Sayı teorisi için yorumlayıcı, modulo n


12

Sayı teorisinin bir cümlesi (bizim için) aşağıdaki sembollerin bir dizisidir:

  • 0ve '(halef) - halef +1,0'''' = 0 + 1 + 1 + 1 + 1 = 4
  • +(toplama) ve *(çarpma)
  • = (eşittir)
  • (ve )(parantez)
  • mantıksal işleç nand( a nand bis not (a and b))
  • forall (evrensel nicelik belirteci)
  • v0, v1, v2, Vb (değişkenler)

    İşte bir cümle örneği:

forall v1 (forall v2 (forall v3 (not (v1*v1*v1 + v2*v2*v2 = v3*v3*v3))))

İşte not xkısaca x nand x- gerçek cümle kullanılır (v1*v1*v1 + v2*v2*v2 = v3*v3*v3) nand (v1*v1*v1 + v2*v2*v2 = v3*v3*v3)çünkü x nand x = not (x and x) = not x.

Bu, üç doğal sayının her kombinasyonu için v1 , v2ve v3bu v1 durum böyle değildir 3 + v2 3 = v3 3 (o alacağı gerçeği dışında, çünkü Fermat'ın Son Teoremi gerçek olacağını 0 ^ 3 +0 ^ 3 = 0 ^ 3).

Ne yazık ki, Gödel tarafından kanıtlandığı gibi, sayı teorisinde bir cümlenin doğru olup olmadığını belirlemek mümkün değildir.

Bu ise bir sonlu kümesine doğal sayılar kümesi kısıtlamak eğer, ancak, mümkün.

Bu nedenle, bu zorluk, sayı teorisinin bir cümlesinin, alındığında doğru olup olmadığını belirlemektir. modulo n , bazı pozitif tamsayı içinn . Örneğin, cümle

forall v0 (v0 * v0 * v0 = v0)

(x, x 3 = x tüm sayıları için ifade )

Sıradan aritmetik için doğru değildir (ör. 2 3 = 8 ≠ 2), ancak bir modulo 3 alındığında doğru:

0 * 0 * 0 ≡ 0 (mod 3)
1 * 1 * 1 ≡ 1 (mod 3)
2 * 2 * 2 ≡ 8 ≡ 2 (mod 3)

Giriş ve çıkış formatı

Giriş, nherhangi bir "makul" formatta bir cümle ve pozitif tamsayıdır . İşte cümle için makul biçimlere bazı örneklerforall v0 (v0 * v0 * v0 = v0)Sayı teorisi modulo 3'teki :

("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)"

Giriş stdin, bir komut satırı bağımsız değişkeni, bir dosya vb. Olabilir.

Program, cümlenin doğru olup olmadığı konusunda iki farklı çıktıya sahip olabilir, örneğin çıktı verebilir yes doğru veno .

Bir değişkenin konu olan bir değişkenini desteklemenize gerek yoktur. forallİki , örn (forall v0 (v0 = 0)) nand (forall v0 (v0 = 0)). Girişinizin geçerli bir sözdizimi olduğunu varsayabilirsiniz.

Test senaryoları

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

Bu , programınızı mümkün olduğunca kısa yapmaya çalışın!


1
Değişken adları her zaman biçimdedir v numbermi?
Jo King

1
Bunları kullanabilirsiniz bazen daha fazla katta istiyorsanız Bunlar olabilir @JoKing var number, hatta sadece 1 + number(bu yüzden 1olacağını v0, 2olurdu v1, vs.)
Leo Tenenbaum

1
@JoKing Sonsuz sayıda değişkene (teorik olarak) izin vermelisiniz. Maksimum değişken sayısı bir tamsayının maksimum boyutu ile sınırlanmışsa sorun değil, ancak bu kadar düşük bir sınırınız olmamalıdır. Bu sizin için bir sorunsa diğer giriş biçimlerinden birini seçebilirsiniz.
Leo Tenenbaum

1
@UnrelatedString Elbette, keyfi olarak uzun süre kalabildikleri sürece.
Leo Tenenbaum

1
Birini kullanabilir miyim 'v numberyerine v number'biz önek sözdizimi seçeneği olur?
Bay Xcoder

Yanıtlar:


3

Python 2 , 252 236 bayt

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

Çevrimiçi deneyin!

Girdi fyerine forallve nyerine iç içe önek-sözdizimi olarak girdi alır nand:

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

Şu anda Python kodunu çıkarıyor, ancak cümlenin doğru veya yanlış olması için iki ayrı çıkışı olmalı. Kullanabilirsiniz print(eval(g(*input()))).
Leo Tenenbaum

@LeoTenenbaum Evet, ilk sürümde vardı, ama golf sonra geri eklemek unuttum
TFeld

1

APL (Dyalog Unicode) , 129 bayt 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}

Çevrimiçi deneyin!

TFeld'in python cevabındaki gibi bir önek sözdizimi ağacı alır , ancak bir tamsayı kodlaması kullanır. Kodlama

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

ve her değişkene 8'den başlayarak bir sayı atanır. Bu kodlama aşağıdaki çözülmemiş versiyonda kullanılandan biraz farklıdır, çünkü kodu golf yaparken değiştirdim.

Görev yalnızca iki giriş içerir (AST ve modulo), ancak bir işlev yerine bir işleç olarak yazılması, modülodan birçok kez bahsetmekten kaçınır (her zaman yinelemeli çağrılar üzerinde taşınır).

Yorum yapılmamış

 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
}

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.