Zdanie teoretycznej ± (naszych celów) jest sekwencją następującymi symbolami:
0
i'
(następca) - następca oznacza+1
, więc0'''' = 0 + 1 + 1 + 1 + 1 = 4
+
(dodawanie) i*
(mnożenie)=
(równy)(
i)
(nawiasy)- operator logiczny
nand
(a nand b
jestnot (a and b)
) forall
(uniwersalny kwantyfikator)v0
,v1
,v2
Itd (zmienne)Oto przykład zdania:
forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))
Oto not x
skrót x nand x
- użyte byłoby właściwe zdanie (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)
, ponieważ x nand x = not (x and x) = not x
.
Stwierdza, że dla każdej kombinacji trzech liczb naturalnych v1
, v2
i v3
to nie jest tak, że v1 3 + v2 3 = v3 3 (co byłoby prawdziwe, ponieważ Wielkie Twierdzenie Fermata, z wyjątkiem faktu, że to się 0 ^ 3 + 0 ^ 3 = 0 ^ 3).
Niestety, jak udowodnił Gödel, nie można ustalić, czy zdanie w teorii liczb jest prawdziwe.
Jest to jednak możliwe, jeśli ograniczymy zbiór liczb naturalnych do zbioru skończonego.
Tak więc wyzwanie polega na ustaleniu, czy zdanie teorii liczb jest prawdziwe, gdy jest brane modulo n
, dla pewnej dodatniej liczby całkowitej n
. Na przykład zdanie
forall v0 (v0 * v0 * v0 = v0)
(stwierdzenie, że dla wszystkich liczb x, x 3 = x)
Nie jest prawdziwe w przypadku zwykłej arytmetyki (np. 2 3 = 8 ≠ 2), ale jest prawdziwe, gdy weźmie się modulo 3:
0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)
Format wejściowy i wyjściowy
Dane wejściowe to zdanie i dodatnia liczba całkowita n
w dowolnym „rozsądnym” formacie. Oto kilka przykładów rozsądnych formatów zdania forall v0 (v0 * v0 * v0 = v0)
w teorii liczb modulo 3:
("forall v0 (v0 * v0 * v0 = v0)", 3)
"3:forall v0 (((v0 * v0) * v0) = v0)"
"(forall v0)(((v0 * v0) * v0) = v0) mod 3"
[3, "forall", "v0", "(", "(", "(", "v0", "*", "v0", ")", "*", "v0", ")", "=", "v0", ")"]
(3, [8, 9, 5, 5, 5, 9, 3, 9, 6, 3, 9, 6, 4, 9, 6]) (the sentence above, but with each symbol replaced with a unique number)
"f v0 = * * v0 v0 v0 v0"
[3, ["forall", "v0", ["=", ["*", "v0", ["*", "v0", "v0"]], "v0"]]]
"3.v0((v0 * (v0 * v0)) = v0)"
Dane wejściowe mogą pochodzić ze standardowego wejścia, argumentu wiersza poleceń, pliku itp.
Program może mieć dowolne dwa różne wyniki dla tego, czy zdanie jest prawdziwe, czy nie, np. Może wypisać, yes
jeśli jest prawdziwe, a no
jeśli nie.
Nie musisz obsługiwać jednej zmiennej będącej przedmiotem forall
podwójnej, np (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0))
. Możesz założyć, że dane wejściowe mają poprawną składnię.
Przypadki testowe
forall v0 (v0 * v0 * v0 = v0) mod 3
true
forall v0 (v0 * v0 * v0 = v0) mod 4
false (2 * 2 * 2 = 8 ≡ 0 mod 4)
forall v0 (v0 = 0) mod 1
true (all numbers are 0 modulo 1)
0 = 0 mod 8
true
0''' = 0 mod 3
true
0''' = 0 mod 4
false
forall v0 (v0' = v0') mod 1428374
true
forall v0 (v0 = 0) nand forall v1 (v1 = 0) mod 2
true (this is False nand False, which is true)
forall v0 ((v0 = 0 nand v0 = 0) nand ((forall v1 (v0 * v1 = 0' nand v0 * v1 = 0') nand forall v2 (v0 * v2 = 0' nand v0 * v2 = 0')) nand (forall v3 (v0 * v3 = 0' nand v0 * v3 = 0') nand forall v4 (v0 * v4 = 0' nand v0 * v4 = 0')))) mod 7
true
(equivalent to "forall v0 (v0 =/= 0 implies exists v1 (v0 * v1 = 0)), which states that every number has a multiplicative inverse modulo n, which is only true if n is 1 or prime)
forall v0 ((v0 = 0 nand v0 = 0) nand ((forall v1 (v0 * v1 = 0' nand v0 * v1 = 0') nand forall v2 (v0 * v2 = 0' nand v0 * v2 = 0')) nand (forall v3 (v0 * v3 = 0' nand v0 * v3 = 0') nand forall v4 (v0 * v4 = 0' nand v0 * v4 = 0')))) mod 4
false
To jest golf golfowy , więc postaraj się, aby twój program był jak najkrótszy!
var number
, a nawet po prostu 1 + number
(tak 1
byłoby v0
, 2
byłoby v1
itd.)
'v number
zamiast, v number'
jeśli wybieramy opcję prefiks-składnia?
v number
?