数论解释器,模n


12

一个句子数论(我们的目的)的是下列符号序列:

  • 0'(后继) -后继手段+1,所以0'''' = 0 + 1 + 1 + 1 + 1 = 4
  • +(加法)和*(乘法)
  • = (等于)
  • ()(括号)
  • 逻辑运算符nanda nand bnot (a and b)
  • forall (通用量词)
  • v0v1v2等。(变量)

    这是一个句子的示例:

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)。

不幸的是,正如哥德尔所证明的那样,无法确定数论中的一个句子是否正确。

可能的,但是,如果我们限制自然数集到有限集。

因此,这一挑战是确定以某个正整数为模数 时,数论句子是否为真。例如,句子nn

forall v0 (v0 * v0 * v0 = v0)

(对于所有数字x,x 3 = x 的陈述)

对于普通算术(例如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

这是,所以请尝试使您的程序尽可能短!


1
变量名称是否总是采用格式v number
乔·金

1
@JoKing如果您希望他们成为他们,您可以使用- var number甚至可以使用1 + number1应该是v02将会是v1,等等)
Leo Tenenbaum

1
@JoKing(理论上)您应该允许无限数量的变量。如果最大数量的变量受整数的最大大小限制,那是可以的,但是您不应有这么低的限制。如果您遇到问题,则可以选择其他输入格式之一。
Leo Tenenbaum

1
@UnrelatedString当然可以,只要它们可以任意长即可。
Leo Tenenbaum

1
如果我们选择prefix-syntax选项,可以'v number代替使用v number'吗?
Xcoder先生19年

Answers:


3

Python 2中252个 236字节

def g(n,s):
 if str(s)==s:return s.replace("'","+1")
 o,l,r=map(g,[n]*3,s);return['all((%s)for %s in range(%d))'%(r,l,n),'not((%s)*(%s))'%(l,r),'(%s)%%%d==(%s)%%%d'%(l,n,r,n),'(%s)%s(%s)'%(l,o,r)]['fn=+'.find(o)]
print eval(g(*input()))

在线尝试!

将输入作为嵌套的前缀语法,使用f代替foralln代替nand

[3, ["f", "v0", ["=", ["*", "v0", ["*", "v0", "v0"]], "v0"]]]

现在它正在输出Python代码,但是对于句子是对还是假,它应该有两个不同的输出。您可以使用print(eval(g(*input())))
Leo Tenenbaum

@LeoTenenbaum是的,我在第一个版本中使用了它,但是忘了在打完高尔夫球后重新添加它
TFeld 19'Aug

1

APL(Dyalog Unicode),129字节SBCS

{x y z3↑⍵⋄7x:y×7<x5x:∧/∇¨y{⍵≡⍺⍺:⍵⍺⋄x y z3↑⍵⋄7x:⍵⋄6x:x(⍺∇y)⋄x(⍺∇⍣(5x)⊢y)(⍺∇z)}∘z¨⍳⍺⍺⋄y←∇y6x:1+yy(⍎x'+×⍲',⊂'0=⍺⍺|-')∇z}

在线尝试!

TFeld的python answer一样采用前缀语法树,但是使用整数编码。编码是

plus times nand eq forall succ zero  1 2 3 4 5 6 7

并且为每个变量分配了一个从8开始的数字。此编码与下面的非高尔夫版本中使用的编码略有不同,因为我在打高尔夫球的代码时对其进行了调整。

该任务仅涉及两个输入(AST和模数),但是将其写为运算符而不是函数可以避免多次提及模数(因为它始终通过递归调用进行)。

取消评论

 node types; anything 8 will be considered a var
plus times eq nand forall succ zero var←⍳8
 AST nodes have 1~3 length, 1st being the node type
 zero  zero, succ  succ arg, var  var | var value (respectively)

 to (from replace) AST  transform AST so that 'from' var has the value 'to' attached
replace←{
  ⍵≡⍺⍺:⍵⍺              variable found, attach the value
  x y z3↑⍵
  zerox:             zero or different variable: keep as is
  succx: x(⍺∇y)       succ: propagate to y
  forallx: x y(⍺∇z)   forall: propagate to z
  x(⍺∇y)(⍺∇z)          plus, times, eq, nand: propagate to both args
}
 (mod eval) AST  evaluate AST with the given modulo
eval←{
  x y z3↑⍵
  zerox:   0
  varx:    y                     return attached value
  forallx: ∧/∇¨y replacez¨⍳⍺⍺   check all replacements for given var
  succx:   1+∇y
  plusx:   (∇y)+∇z
  timesx:  (∇y)×∇z
  eqx:     0=⍺⍺|(∇y)-∇z          modulo equality
  nandx:   (∇y)⍲∇z               nand symbol does nand operation
}

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.