U t`|,@sdZddlZddlTd+ddZd,d d Zd d Zd dZddZd-ddZddZ d.ddZ ddZ d/ddZ d0ddZ ddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd1d)d*ZdS)2z" Usage: import common_z3 as CM_Z3 N)*TcCs<dd}dd}|dkr"||}n |||}|r8t|S|S)z order preserving >>> vset([[11,2],1, [10,['9',1]],2, 1, [11,2],[3,3],[10,99],1,[10,['9',1]]],idfun=repr) [[11, 2], 1, [10, ['9', 1]], 2, [3, 3], [10, 99]] css(i}|D]}||krd||<|VqdSN)seqd_srrsrc/api/python/z3/z3util.py _uniq_normals zvset.._uniq_normalcss0i}|D]"}||}||krd||<|VqdSrr)ridfunrrZh_rrr _uniq_idfun$s zvset.._uniq_idfunN)list)rr Zas_listr r resrrr vsets   rFcCsftd}td}td}td}t||||tt|j|j|j|jf}|r^dj|S|SdS)Nrz {}.{}.{}.{})ctypesZc_uintZ3_get_versionmapintvalueformat)as_strmajorminorbuildZrevrsrrr get_z3_version4s     rcCs,trt|stdt|||S)a" Returns a 'stronger' hash value than the default hash() method. The result from hash() is not enough to distinguish between 2 z3 expressions in some cases. Note: the following doctests will fail with Python 2.x as the default formatting doesn't match that of 3.x. >>> x1 = Bool('x'); x2 = Bool('x'); x3 = Int('x') >>> print(x1.hash(), x2.hash(), x3.hash()) #BAD: all same hash values 783810685 783810685 783810685 >>> print(ehash(x1), ehash(x2), ehash(x3)) x_783810685_1 x_783810685_1 x_783810685_2 z{}_{}_{})z3_debugis_exprAssertionErrorrstrhashZ sort_kindvrrr ehashAs r#cCst|o|tkS)a EXAMPLES: >>> is_expr_var(Int('7')) True >>> is_expr_var(IntVal('7')) False >>> is_expr_var(Bool('y')) True >>> is_expr_var(Int('x') + 7 == Int('y')) False >>> LOnOff, (On,Off) = EnumSort("LOnOff",['On','Off']) >>> Block,Reset,SafetyInjection=Consts("Block Reset SafetyInjection",LOnOff) >>> is_expr_var(LOnOff) False >>> is_expr_var(On) False >>> is_expr_var(Block) True >>> is_expr_var(SafetyInjection) True is_constZdeclkindZZ3_OP_UNINTERPRETEDr!rrr is_expr_var\sr'cCst|o|tkS)a EXAMPLES: >>> is_expr_val(Int('7')) False >>> is_expr_val(IntVal('7')) True >>> is_expr_val(Bool('y')) False >>> is_expr_val(Int('x') + 7 == Int('y')) False >>> LOnOff, (On,Off) = EnumSort("LOnOff",['On','Off']) >>> Block,Reset,SafetyInjection=Consts("Block Reset SafetyInjection",LOnOff) >>> is_expr_val(LOnOff) False >>> is_expr_val(On) True >>> is_expr_val(Block) False >>> is_expr_val(SafetyInjection) False r$r!rrr is_expr_valwsr(cCsj|dkr g}trt|stt|rDt|r2|St||gtSn"|D]}t||}qLt|tSdS)z >>> x,y = Ints('x y') >>> a,b = Bools('a b') >>> get_vars(Implies(And(x+y==0,x*2==10),Or(a,Implies(a,b==False)))) [x, y, a, b] N) rrrr%r(rrZchildrenget_vars)frZf_rrr r)s   r)cCsr|tkrt|}nX|tkr,t|}nB|tkrBt|}n,|tkrZt||}nt d||f|S)Nz%Cannot handle this sort (s: %sid: %d)) r&Z Z3_INT_SORTZIntZ Z3_REAL_SORTZRealZ Z3_BOOL_SORTZBoolZZ3_DATATYPE_SORTZConst TypeError)nameZvsortr"rrr mk_vars        r-c strrtst|}r^trTtt\}}fdd}|dksTt|t|}dkrtdttdt|tdt|t|}t|dd }|d krtd d S|dkrd Strt|t st|rd|dfSdgfSd S)aL >>> r,m = prove(BoolVal(True),verbose=0); r,model_str(m,as_str=False) (True, None) #infinite counter example when proving contradiction >>> r,m = prove(BoolVal(False)); r,model_str(m,as_str=False) (False, []) >>> x,y,z=Bools('x y z') >>> r,m = prove(And(x,Not(x))); r,model_str(m,as_str=True) (False, '[]') >>> r,m = prove(True,assume=And(x,Not(x)),verbose=0) Traceback (most recent call last): ... AssertionError: Assumption is always False! >>> r,m = prove(Implies(x,x),assume=y,verbose=2); r,model_str(m,as_str=False) assume: y claim: Implies(x, x) to_prove: Implies(y, Implies(x, x)) (True, None) >>> r,m = prove(And(x,True),assume=y,verbose=0); r,model_str(m,as_str=False) (False, [(x, False), (y, True)]) >>> r,m = prove(And(x,y),assume=y,verbose=0) >>> print(r) False >>> print(model_str(m,as_str=True)) x = False y = True >>> a,b = Ints('a b') >>> r,m = prove(a**b == b**a,assume=None,verbose=0) E: cannot solve ! >>> r is None and m is None True csd}dkrd|}|S)NzAssumption is always False!z{} {}r)Zemsgassumeverboserr _fs zprove.._fFr.zassume: zclaim: z to_prove: rkNzE: cannot solve !)NN)TNr) rrrproveNotImpliesprint get_models isinstancer ) claimr1r2Zto_proveZ is_proved_r3r*modelsrr0r r6s8-   r6cstrt|st|dkstt}||g}d}|tkr||kr|d}|s`q|t t fddD}||q6|t krdS|t kr|dkrdS|SdS)a] Returns the first k models satisfiying f. If f is not satisfiable, returns False. If f cannot be solved, returns None If f is satisfiable, returns the first k models Note that if f is a tautology, e.g.\ True, then the result is [] Based on http://stackoverflow.com/questions/11867611/z3py-checking-all-solutions-for-equation EXAMPLES: >>> x, y = Ints('x y') >>> len(get_models(And(0<=x,x <= 4),k=11)) 5 >>> get_models(And(0<=x**y,x <= 1),k=2) is None True >>> get_models(And(0<=x,x <= -1),k=2) False >>> len(get_models(x+y==7,5)) 5 >>> len(get_models(And(x<=5,x>=1),7)) 5 >>> get_models(And(x<=0,x>=5),7) False >>> x = Bool('x') >>> get_models(And(x,Not(x)),k=1) False >>> get_models(Implies(x,x),k=1) [] >>> get_models(BoolVal(True),k=1) [] rrcsg|]}||kqSrr.0r"mrr Jszget_models..NF) rrrZSolveraddchecksatmodelappendr7AndunknownZunsat)r*r5rr>iblockrrAr r:s(%      r:cCst|d|ddS)z >>> is_tautology(Implies(Bool('x'),Bool('x'))) True >>> is_tautology(Implies(Bool('x'),Bool('y'))) False >>> is_tautology(BoolVal(True)) True >>> is_tautology(BoolVal(False)) False Nr<r1r2r)r6r<r2rrr is_tautologyUsrOcCstt|d|ddS)a@ >>> x,y=Bools('x y') >>> is_contradiction(BoolVal(False)) True >>> is_contradiction(BoolVal(True)) False >>> is_contradiction(x) False >>> is_contradiction(Implies(x,y)) False >>> is_contradiction(Implies(x,x)) False >>> is_contradiction(And(x,Not(x))) True NrMr)r6r7rNrrr is_contradictiongsrPcCs*t|dd}t|tr"t|dkSdSdS)aA return True if f has exactly 1 model, False otherwise. EXAMPLES: >>> x, y = Ints('x y') >>> exact_one_model(And(0<=x**y,x <= 0)) False >>> exact_one_model(And(0<=x,x <= 0)) True >>> exact_one_model(And(0<=x,x <= 1)) False >>> exact_one_model(And(0<=x,x <= -1)) False r.r4rFN)r:r;r len)r*r>rrr exact_one_models   rRcGstr"|tks"|tks"|tks"tt|dkrRt|dtsJt|dtrR|d}trnt dd|Dsntdd|D}|rt|dkr|dS|tkrt |S|tkrt |St |d|dSdSdS)a >>> myAnd(*[Bool('x'),Bool('y')]) And(x, y) >>> myAnd(*[Bool('x'),None]) x >>> myAnd(*[Bool('x')]) x >>> myAnd(*[]) >>> myAnd(Bool('x'),Bool('y')) And(x, y) >>> myAnd(*[Bool('x'),Bool('y')]) And(x, y) >>> myAnd([Bool('x'),Bool('y')]) And(x, y) >>> myAnd((Bool('x'),Bool('y'))) And(x, y) >>> myAnd(*[Bool('x'),Bool('y'),True]) Traceback (most recent call last): ... AssertionError rrcss|]}t|t VqdSr)r;boolr@valrrr szmyBinOp..cSsg|]}t|r|qSr)rrTrrr rCszmyBinOp..N) rZ3_OP_OR Z3_OP_AND Z3_OP_IMPLIESrrQr;r tupleallZOrrIr8)opLrrr myBinOps ( r^cGsttf|Sr)r^rXr]rrr myAndsr`cGsttf|Sr)r^rWr_rrr myOrsracCstt||gSr)r^rY)abrrr myImpliessrdcCs&tt|d|dt|d|dS)Nrr)rIr8)r*rrr Iffsrecs|tr$dks$gks$tts$trhfddD}t|ddd}|rbddd|DS|Sn|rttSSdS) z Returned a 'sorted' model (so that it's easier to see) The model is sorted by its key, e.g. if the model is y = 3 , x = 10, then the result is x = 10, y = 3 EXAMPLES: see doctest exampels from function prove() Ncsg|]}||fqSrrr?rArr rCszmodel_str..cSst|Sr)r)rbr=rrr zmodel_str..)key cSsg|]\}}d||qS)z{} = {}r/)r@r5r"rrr rCs)rr;ZModelRefrsortedjoinr)rBrZvsrrAr model_strs rl)NT)F)N)Nr)r)r)T)__doc__rz3rrr#r'r(r)r-r6r:rOrPrRr^r`rardrerlrrrr  s( "   YA  5