Produce una descrizione formale completa di tali dichiarazioni come 1+2=3
, 2+2=2*(1+1)
ecc.
Introuction
Se conosci l'aritmetica di Peano puoi probabilmente saltare questa sezione.
Ecco come definiamo i numeri naturali:
(Axiom 1) 0 is a number
(Axiom 2) If `x` is a number, the `S(x)`, the successor of `x`, is a number.
Quindi, ad esempio, S(S(S(0)))
è un numero.
Puoi usare qualsiasi rappresentazione equivalente nel tuo codice. Ad esempio, tutti questi sono validi:
0 "" 0 () !
1 "#" S(0) (()) !'
2 "##" S(S(0)) ((())) !''
3 "###" S(S(S(0))) (((()))) !'''
...
etc
Possiamo estendere le regole per definire l'addizione come segue.
(Rule 1) X+0 = X
(Rule 2) X+S(Y)=S(X)+Y
Con questo possiamo dimostrare 2 + 2 = 4 come segue
S(S(0)) + S(S(0)) = 2 + 2
[Rule 2 with X=S(S(0)), Y=S(0)]
S(S(S(0))) + S(0) = 3 + 1
[Rule 2 with X=S(S(S(0))), Y=0]
S(S(S(S(0)))) + 0 = 4 + 0
[Rule 1 with X=S(S(S(S(0))))
S(S(S(S(0)))) = 4
Possiamo estendere queste regole per definire la moltiplicazione come segue
(Rule 3) X*0 = 0
(Rule 4) X*S(Y) = (X*Y) + X
Sebbene per consentire ciò, dobbiamo definire il ruolo strutturale delle parentesi.
(Axiom 3) If X is a number, (X) is the same number.
Gli operatori di addizione e moltiplicazione sono rigorosamente binari e le parentesi devono essere sempre esplicite. A+B+C
non è ben definito, ma (A+B)+C
e lo A+(B+C)
sono.
Esempio
Ora abbiamo abbastanza per dimostrare un teorema sulla moltiplicazione: 2 + 2 = 2 * 2
2 + 2
(2) + 2
(0 + 2) + 2
((0*2) + 2) + 2
(1*2) + 2
2*2
Requisiti
Una prova cheA=B
è un elenco di espressioni tali che:
- il primo è
A
, - l'ultimo è
B
, e - ogni espressione nella lista a parte la prima può essere ottenuta dalla precedente trasformandola in una delle regole.
Il tuo programma prenderà due espressioni valide come input , ogni espressione contiene numeri, addizioni, moltiplicazioni e parentesi come definito sopra.
Il tuo programma produrrà una prova, un elenco come sopra definito, che le due espressioni sono uguali, se tale prova esiste.
Se le due espressioni non sono uguali, il tuo programma non produrrà nulla.
Provare o confutare è sempre possibile in un numero finito di passaggi, perché ogni espressione può essere ridotta a un singolo numero e questi numeri possono essere banalmente testati per l'uguaglianza.
Se le espressioni di input non sono valide (ad esempio parentesi sbilanciate, contiene operatori non numeri o non binari), il programma dovrebbe uscire con errori, generare un'eccezione, stampare un errore o produrre in altro modo un comportamento osservabile che è distinto dal caso in cui gli input sono validi ma non uguali .
In sintesi, l'output normale per input ammissibili è un elenco di numeri uguali, inclusi gli input, che viene prodotto dalle seguenti regole.
(Axiom 1) 0 is a number
(Axiom 2) If `x` is a number, the `S(x)`, the successor of `x`, is a number.
(Axiom 3) If X is a number, (X) is the same number
(Rule 1) X+0 = X
(Rule 2) X+S(Y)=S(X)+Y
(Rule 3) X*0 = 0
(Rule 4) X*S(Y) = (X*Y) + X
(Rule 5) X = (X) (Axiom 3 expressed as a transformation rule.)
È consentita qualsiasi rappresentazione adeguata dei numeri in ingresso e in uscita, ad es 0=""=()
. 3="###"=(((())))
, Ecc. Gli spazi bianchi sono irrilevanti.
Le regole possono, ovviamente, essere applicate in entrambe le direzioni. Il tuo programma non deve produrre quale regola viene utilizzata, ma solo l'espressione prodotta dalla sua azione sull'espressione precedente.
Il codice più corto vince.