Một câu của lý thuyết số (cho mục đích của chúng tôi) là một chuỗi các ký hiệu sau:
0
và'
(người kế vị) - nghĩa là người kế nhiệm+1
, vì vậy0'''' = 0 + 1 + 1 + 1 + 1 = 4
+
(bổ sung) và*
(nhân)=
(tương đương với)(
và)
(dấu ngoặc đơn)- toán tử logic
nand
(a nand b
lànot (a and b)
) forall
(bộ định lượng phổ quát)v0
,v1
,v2
, Vv (biến)Đây là một ví dụ về một câu:
forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))
Đây not x
là viết tắt cho x nand x
- câu thực tế sẽ sử dụng (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)
, bởi vì x nand x = not (x and x) = not x
.
Này nói rằng đối với mỗi sự kết hợp của ba số tự nhiên v1
, v2
và v3
, nó không phải là trường hợp đó v1 3 + v2 3 = v3 3 (đó sẽ là sự thật vì Fermat cuối Định lý, ngoại trừ một thực tế rằng nó sẽ nhận được 0 ^ 3 + 0 ^ 3 = 0 ^ 3).
Thật không may, như đã được chứng minh bởi Gôdel, không thể xác định liệu một câu trong lý thuyết số có đúng hay không.
Nó là có thể, tuy nhiên, nếu chúng ta hạn chế việc tập hợp các số tự nhiên đến một tập hữu hạn.
Vì vậy, thách thức này là xác định xem một câu của lý thuyết số có đúng hay không, khi lấy modulo n
, đối với một số nguyên dương n
. Ví dụ: câu
forall v0 (v0 * v0 * v0 = v0)
(câu lệnh cho tất cả các số x, x 3 = x)
Là không đúng đối với số học thông thường (ví dụ 2 3 = 8 ≠ 2), nhưng là đúng khi lấy modulo 3:
0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)
Định dạng đầu vào và đầu ra
Đầu vào là một câu và số nguyên dương n
ở bất kỳ định dạng "hợp lý" nào. Dưới đây là một số ví dụ về các định dạng hợp lý cho câu forall v0 (v0 * v0 * v0 = v0)
trong lý thuyết số 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)"
Đầu vào có thể từ stdin, đối số dòng lệnh, tệp, v.v.
Chương trình có thể có bất kỳ hai đầu ra riêng biệt nào cho dù câu đó có đúng hay không, ví dụ: nó có thể xuất ra yes
nếu nó đúng và no
nếu không.
Bạn không cần phải hỗ trợ một biến là chủ đề của forall
hai lần, ví dụ (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0))
. Bạn có thể cho rằng đầu vào của bạn có cú pháp hợp lệ.
Các trường hợp thử nghiệm
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
Đây là môn đánh gôn , vì vậy hãy cố gắng làm cho chương trình của bạn ngắn nhất có thể!
var number
, hoặc thậm chí chỉ 1 + number
(vì vậy 1
sẽ v0
, 2
sẽ là v1
, vv)
'v number
thay vì v number'
nếu chúng ta chọn tùy chọn cú pháp tiền tố?
v number
?