Предложение из теории чисел (для наших целей) представляет собой последовательность следующих символов:
0
и'
(преемник) - значит преемник+1
, так0'''' = 0 + 1 + 1 + 1 + 1 = 4
+
(сложение) и*
(умножение)=
(равно)(
и)
(скобки)- логический оператор
nand
(a nand b
естьnot (a and b)
) forall
(универсальный квантификатор)v0
,v1
,v2
, И т.д. (переменные)Вот пример предложения:
forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))
Вот not x
сокращение от x nand x
- фактическое предложение будет использовать (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)
, потому что x nand x = not (x and x) = not x
.
Это говорит о том, что для каждой комбинации трех натуральных чисел v1
, v2
и v3
, это не тот случай, когда v1 3 + v2 3 = v3 3 (что было бы верно из-за последней теоремы Ферма, за исключением того факта, что она получит 0 ^ 3 + 0 ^ 3 = 0 ^ 3).
К сожалению, как доказал Гёдель, невозможно определить, является ли предложение в теории чисел верным.
Это является возможным, однако, если мы ограничиваем множество натуральных чисел для конечного множества.
Таким образом, эта задача состоит в том, чтобы определить, является ли предложение теории чисел верным, если принимать его по модулю n
для некоторого положительного целого числа n
. Например, предложение
forall v0 (v0 * v0 * v0 = v0)
(утверждение, что для всех чисел х, х 3 = х)
Не относится к обычной арифметике (например , 2 3 = 8 ≠ 2), но это верно , когда берется по модулю 3:
0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)
Формат ввода и вывода
Входные данные представляют собой предложение и положительное целое число n
в любом «разумном» формате. Вот несколько примеров разумных форматов предложения forall v0 (v0 * v0 * v0 = v0)
в теории чисел по модулю 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)"
Входные данные могут быть из стандартного ввода, аргумента командной строки, файла и т. Д.
Программа может иметь любые два различных вывода для того, является ли предложение истинным или нет, например, это могло бы вывести, yes
если это верно, и no
если это не так.
Вам не нужно поддерживать одну переменную, являющуюся предметом forall
двойной переменной , например (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0))
. Вы можете предположить, что ваш ввод имеет правильный синтаксис.
Контрольные примеры
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
Это код-гольф , поэтому постарайтесь сделать свою программу максимально короткой!
var number
, или даже просто 1 + number
(так 1
было бы v0
, 2
будет v1
и т. Д.)
'v number
вместо, v number'
если мы выберем опцию префикс-синтаксис?
v number
?