Çok temel olarak, bu araç, bazı koşulları sağlaması gereken değişkenler için değerler bulmamıza yardımcı olacak ve bunları el ile hesaplamak çok sıkıcı olacaktır. Bu nedenle, Z3'e değişkenlerin sağlaması gereken koşulları belirtebilirsiniz ve mümkünse bazı değerler bulacaktır.
#pip3 install z3-solverfrom z3 import*s =Solver()#The solver will be given the conditionsx =Bool("x")#Declare the symbos x, y and zy =Bool("y")z =Bool("z")# (x or y or !z) and ys.add(And(Or(x,y,Not(z)),y))s.check()#If response is "sat" then the model is satifable, if "unsat" something is wrongprint(s.model())#Print valid values to satisfy the model
Tamsayılar/Sadeleştirme/Gerçek Sayılar
SMT çözücüsü Z3, tamsayılar, sadeleştirme ve gerçek sayılarla çalışmak için kullanılabilir. Bu bölümde, Z3'ün bu tür ifadeleri nasıl işlediğini ve çözdüğünü öğreneceksiniz.
Tamsayılar
Z3, tamsayılarla çalışmak için Int veri türünü sağlar. Tamsayı ifadeleri, aritmetik operatörlerle birleştirilerek oluşturulabilir. Örneğin, x + y veya 2 * z gibi ifadeler geçerlidir. Z3, bu ifadeleri sadeleştirir ve sonucu en basit hale getirir.
Sadeleştirme
Z3, ifadeleri sadeleştirirken, matematiksel eşitlikleri kullanır ve ifadeleri mümkün olduğunca basit hale getirir. Örneğin, x + 0 ifadesi x olarak sadeleştirilir ve x * 1 ifadesi de x olarak sadeleştirilir. Bu sadeleştirme işlemi, ifadelerin daha anlaşılır ve daha kolay çözülebilir hale gelmesini sağlar.
Gerçek Sayılar
Z3, gerçek sayılarla çalışmak için Real veri türünü sağlar. Gerçek sayı ifadeleri, tamsayı ifadeleriyle aynı şekilde oluşturulabilir ve aritmetik operatörlerle birleştirilebilir. Z3, gerçek sayı ifadelerini de sadeleştirir ve sonucu en basit hale getirir.
Bu bölümde, Z3'ün tamsayılar, sadeleştirme ve gerçek sayılarla nasıl çalıştığını öğrendiniz. Bu bilgileri kullanarak, Z3'ü daha etkili bir şekilde kullanabilir ve tamsayı ve gerçek sayı ifadelerini çözebilirsiniz.
from z3 import*x =Int('x')y =Int('y')#Simplify a "complex" ecuationprint(simplify(And(x +1>=3, x**2+ x**2+ y**2+2>=5)))#And(x >= 2, 2*x**2 + y**2 >= 3)#Note that Z3 is capable to treat irrational numbers (An irrational algebraic number is a root of a polynomial with integer coefficients. Internally, Z3 represents all these numbers precisely.)
#so you can get the decimals you need from the solutionr1 =Real('r1')r2 =Real('r2')#Solve the ecuationprint(solve(r1**2+ r2**2==3, r1**3==2))#Solve the ecuation with 30 decimalsset_option(precision=30)print(solve(r1**2+ r2**2==3, r1**3==2))
Modeli Yazdırma
To print the model, you can use the model object obtained from the check() method. The model object represents the satisfying assignment for the given formula.
To print the model in Z3, you can use the sexpr() method of the model object. This method returns a string representation of the model in S-expression format.
Here is an example of how to print the model in Z3:
s =Solver()# ... add constraints and assertions ...result = s.check()if result == sat: m = s.model()print(m.sexpr())
This will print the model in S-expression format, which represents the values assigned to the variables in the model.
Keep in mind that the sexpr() method returns a string, so you can also save the model to a file or process it further as needed.
from z3 import*x, y, z =Reals('x y z')s =Solver()s.add(x >1, y >1, x + y >3, z - x <10)s.check()m = s.model()print ("x = %s"% m[x])for d in m.decls():print("%s = %s"% (d.name(), m[d]))
Makine Aritmetiği
Modern CPU'lar ve yaygın kullanılan programlama dilleri, sabit boyutlu bit vektörleri üzerinde aritmetik işlemler yapar. Makine aritmetiği, Z3Py'de Bit-Vektörleri olarak mevcuttur.
from z3 import*x =BitVec('x', 16)#Bit vector variable "x" of length 16 bity =BitVec('y', 16)e =BitVecVal(10, 16)#Bit vector with value 10 of length 16bitsa =BitVecVal(-1, 16)b =BitVecVal(65535, 16)print(simplify(a == b))#This is True!a =BitVecVal(-1, 32)b =BitVecVal(65535, 32)print(simplify(a == b))#This is False
İmzalı/İmzasız Sayılar
Z3, bit vektörünün imzalı veya imzasız olarak işleme tabi tutulmasının farkını ortaya koyan özel imzalı versiyonlarını sağlar. Z3Py'de <, <=, >, >=, /, % ve >> operatörleri imzalı versiyonlara karşılık gelir. Buna karşılık imzasız operatörler ise ULT, ULE, UGT, UGE, UDiv, URem ve LShR'dir.
from z3 import*# Create to bit-vectors of size 32x, y =BitVecs('x y', 32)solve(x + y ==2, x >0, y >0)# Bit-wise operators# & bit-wise and# | bit-wise or# ~ bit-wise notsolve(x & y ==~y)solve(x <0)# using unsigned version of <solve(ULT(x, 0))
Fonksiyonlar
Yorumlanan fonksiyonlar, fonksiyon +'ın sabit bir standart yorumlaması olan aritmetik gibi fonksiyonlardır (iki sayıyı toplar). Yorumlanmayan fonksiyonlar ve sabitler maksimum esneklik sağlar; fonksiyon veya sabit üzerindeki kısıtlamalarla tutarlı olan herhangi bir yorumlamaya izin verir.
Örnek: x'e iki kez uygulanan f, tekrar x'e döner, ancak x'e bir kez uygulanan f, x'ten farklıdır.
from z3 import*x =Int('x')y =Int('y')f =Function('f', IntSort(), IntSort())s =Solver()s.add(f(f(x)) == x, f(x) == y, x != y)s.check()m = s.model()print("f(f(x)) =", m.evaluate(f(f(x))))print("f(x) =", m.evaluate(f(x)))print(m.evaluate(f(2)))s.add(f(x) ==4)#Find the value that generates 4 as responses.check()print(m.model())
Örnekler
Sudoku çözücü
# 9x9 matrix of integer variablesX = [ [ Int("x_%s_%s"% (i+1, j+1))for j inrange(9) ]for i inrange(9) ]# each cell contains a value in {1, ..., 9}cells_c = [ And(1<= X[i][j], X[i][j] <=9)for i inrange(9)for j inrange(9) ]# each row contains a digit at most oncerows_c = [ Distinct(X[i])for i inrange(9) ]# each column contains a digit at most oncecols_c = [ Distinct([ X[i][j] for i inrange(9) ])for j inrange(9) ]# each 3x3 square contains a digit at most oncesq_c = [ Distinct([ X[3*i0 + i][3*j0 + j]for i inrange(3) for j inrange(3) ])for i0 inrange(3)for j0 inrange(3) ]sudoku_c = cells_c + rows_c + cols_c + sq_c# sudoku instance, we use '0' for empty cellsinstance = ((0,0,0,0,9,4,0,3,0),(0,0,0,5,1,0,0,0,7),(0,8,9,0,0,0,0,4,0),(0,0,0,0,0,0,2,0,8),(0,6,0,2,0,1,0,5,0),(1,0,2,0,0,0,0,0,0),(0,7,0,0,0,0,5,2,0),(9,0,0,0,6,5,0,0,0),(0,4,0,9,7,0,0,0,0))instance_c = [ If(instance[i][j] ==0,True,X[i][j] == instance[i][j])for i inrange(9)for j inrange(9) ]s =Solver()s.add(sudoku_c + instance_c)if s.check()== sat:m = s.model()r = [ [ m.evaluate(X[i][j])for j inrange(9) ]for i inrange(9) ]print_matrix(r)else:print"failed to solve"