U t`@svdZddlmZddlTddlTddlTddlTddlmZddlZddl Z ddl Z ddl Z ej j dkrtddlmZd ad d Zej j dkrd d Zndd ZddZddZddZddZddZddZddZddZdd Zdd!d"Zd#d$Zd%d&Zd'd(Zd)d*Z d+d,Z!Gd-d.d.Z"da#d/d0Z$d1d2Z%d3d4Z&d5d6Z'd7d8Z(d9d:Z)d;d<Z*Gd=d>d>Z+Gd?d@d@e+Z,dAdBZ-dCdDZ.dEdFZ/ddGdHZ0dIdJZ1dKdLZ2dMdNZ3dOdPZ4dQdRZ5dSdTZ6GdUdVdVe,Z7dWdXZ8dYdZZ9d[d\Z:dd]d^Z;Gd_d`d`e,ZdedfZ?dgdhZ@didjZAdkdlZBGdmdndne,ZCdodpZDdqdrZEddsdtZFdudvZGddwdxZHdydzZId{d|ZJd}d~ZKddZLddZMddZNdddZOddZPddZQddZRddZSdddZTddZUdddZVdddZWGddde7ZXGdddeCZYddZZddZ[ddZ\ddZ]ddZ^ddZ_ddZ`ddZaddZbdddZcdddZddddZedddZfdddZgdddZhdddZidddZjdddZkdd„ZlddĄZmddƄZnddȄZoGddʄdeCZpdd̄Zqdd΄ZrddЄZsGdd҄deYZtddԄZudddggfddׄZvdddggfddلZwdddggfddۄZxdd݄ZyGdd߄de7ZzddZ{GdddeCZ|ddZ}ddZ~ddZddZddZddZddZddZddZddZddZddZddZddZddZddZddZddZdd Zd d Zd d ZGddde|ZGddde|ZGddde|ZdÐddZdĐddZdŐddZddZdƐddZdǐddZdȐd d!Zdɐd"d#Zdʐd$d%Zdːd&d'Zd̐d(d)Zd͐d+d,Zdΐd-d.Zdϐd/d0ZdАd1d2Zdѐd3d4Zd5d6Zd7d8Zd9d:ZdҐd;d<ZdӐd=d>ZGd?d@d@e7ZdAdBZGdCdDdDeCZGdEdFdFeZdGdHZdIdJZdԐdLdMZdNdOZdՐdPdQZd֐dRdSZdאdTdUZdؐdVdWZdXdYZdZd[Zd\d]Zd^d_Zd`daZdbdcZdddeZdfdgZdhdiZdjdkZdldmZdndoZdpdqZdrdsZÐdtduZĐdvdwZŐdxdyZƐdzd{Zǐd|d}ZȐd~dZɐddZʐddZːddZ̐ddZ͐ddZΐddZGddde7ZGdddeCZѐddZҐddZӐddZԐddZՐddZ֐ddZאddZؐddZِddZڐddZېddZܐddZݐddZސddZߐddZddZddZddZddZddZddZddZddZddZddZddÄZdĐdńZdƐdDŽZdȐdɄZdʐd˄Zd̐d̈́ZGdΐdτdσZGdАdфdуZGdҐdӄdӃZdԐdՄZGd֐dׄde7ZGdؐdلdeCZdِdڐdۄZdڐdܐd݄Zdېdސd߄ZGdddZdܐddZGdddZGddde+ZGddde+ZGdddZGdddZGddde+ZGddde+ZdݐddZddZddZGdddZGdddZeeZ ee Z ee Z Gddde+ZdސddZdߐddZGddde+ZGddde7ZdddZdd ZGd d d eCZd d ZGdddeZdddZddZGdddZiZddZeeZGddde+ZGddde+Z GdddZ!ddZ"dd d!Z#dd"d#Z$dd$d%Z%d&d'Z&d(d)Z'd*d+Z(d,d-Z)dd.d/Z*dd0d1Z+d2d3Z,d4d5Z-dd7d8Z.dd9d:Z/dd;d<Z0dd=d>Z1d?d@Z2GdAdBdBZ3dCdDZ4ddEdFZ5ddGdHZ6ddIdJZ7dKdLZ8dMdNZ9dOdPZ:dQdRZ;ddSdTZ<ddUdVZ=ddWdXZ>dYdZZ?d[d\Z@d]d^ZAd_d`ZBdadbZCdcddZDdedfZEdgdhZFdidjZGdkdlZHddmdnZIdodpZJdqdrZKddsdtZLdudvZMdwdxZNddydzZOd{d|ZPd}d~ZQdddZRddZSddZTiidfddZUiidfddZVeWaXdaYdaZdddZ[e\eWe]e^e_e`hZadddZbdddZcdddZddddZedddZfddZgGddde7ZhdddZidddZjdddZkdddZldddZmdddZndddZodddZpGddde7ZqddZrddZsGdddeCZtGdddeCZudddZvdddZwdddZxdddZydddZzdddZ{d dd„Z|d dÐdĄZ}d dŐdƄZ~d dǐdȄZdɐdʄZdːd̄ZGd͐d΄dΐetZdϐdЄZdѐd҄Zd dӐdԄZddՐdքZdאd؄ZdِdڄZdېd܄ZdݐdބZdߐdZddZddZdddZdddZdddZdddZdddZddZddZddZddZddZddZdddZdddZdddZdddZdddZdddZdddZdd d Zdd d Zdd dZdddZdddZd ddZd!ddZd"ddZd#ddZd$ddZddZd%dd Zd&d!d"Zd'd#d$Zd(d%d&Zd)d'd(Zd*d)d*Zd+d+d,Zd,d-d.Zd-d/d0Zd.d1d2Zd/d3d4Zd0d5d6Zd1d7d8Zd2d9d:Zd3d;d<Zd4d=d>Zd5d?d@Zd6dAdBZGdCdDdDe7Zd7dEdFZdGdHZGdIdJdJeCZd8dKdLZd9dMdNZdOdPZÐdQdRZĐdSdTZŐd:dUdVZƐd;dWdXZǐd<dYdZZȐd[d\Zɐd]d^Zʐd_d`ZːdadbZ̐dcddZ͐dedfZΐdgdhZϐdidjZАdkdlZѐd=dmdnZҐdodpZӐdqdrZԐdsdtZՐdudvZ֐d>dwdxZGdydzdze7Zؐd{d|ZGd}d~d~eCZڐddZېddZܐddZݐddZސddZߐddZddZddZd?ddZd@ddZddZddZddZddZddZGdddZdaddZddZddZddZddZddZddZddZeeZeeZeeZeeZeeZeeZeeZGdddZdS(AaZ3 is a high performance theorem prover developed at Microsoft Research. Z3 is used in many applications such as: software/hardware verification and testing, constraint solving, analysis of hybrid systems, security, biology (in silico analysis), and geometrical problems. Several online tutorials for Z3Py are available at: http://rise4fun.com/Z3Py/tutorial/guide Please send feedback, comments and/or corrections on the Issue tracker for https://github.com/Z3prover/z3.git. Your comments are very valuable. Small example: >>> x = Int('x') >>> y = Int('y') >>> s = Solver() >>> s.add(x > 0) >>> s.add(x < 2) >>> s.add(y == x + 1) >>> s.check() sat >>> m = s.model() >>> m[x] 1 >>> m[y] 2 Z3 exceptions: >>> try: ... x = BitVec('x', 32) ... y = Bool('y') ... # the expression x + y is type incorrect ... n = x + y ... except Z3Exception as ex: ... print("failed: %s" % ex) failed: sort mismatch )z3core)*)FractionN)IterableTcCstSN)Z3_DEBUGr r src/api/python/z3/z3.pyz3_debug@sr cCst|ttfSr) isinstanceintlongvr r r _is_intFsrcCs t|tSr)r rrr r r rIscCs t|dSr)Z3_enable_tracemsgr r r enable_traceMsrcCs t|dSr)Z3_disable_tracerr r r disable_traceQsrcCsJtd}td}td}td}t||||d|j|j|jfS)Nrz%s.%s.%sctypesc_uintZ3_get_versionvaluemajorminorbuildZrevr r r get_version_stringUs     r"cCsJtd}td}td}td}t|||||j|j|j|jfSNrrrr r r get_version^s     r$cCstSr)Z3_get_full_versionr r r r get_full_versiongsr&cCs|s t|dSr Z3Exception)Zcondrr r r _z3_assertnsr)cCstt|j|k|ddS)Nz is too large)r)rc_intr)nnamer r r _z3_check_cint_overflowssr-cCs t|dS)zSLog interaction to a file. This function must be invoked immediately after init(). N) Z3_open_log)fnamer r r open_logwsr0cCs t|dS)z/Append user-defined string to interaction log. N) Z3_append_logsr r r append_log|sr4cCs0t|rtt||Stt||SdS)z.Convert an integer or string into a Z3 symbol.N)rZ3_mk_int_symbol_get_ctxrefZ3_mk_string_symbolr3ctxr r r to_symbolsr;cCs6t||tkr$dt||St||SdS)z/Convert a Z3 symbol back into a Python object. zk!%sN)Z3_get_symbol_kindr7Z Z3_INT_SYMBOLZ3_get_symbol_intZ3_get_symbol_stringr:r3r r r _symbol2pysr@cCszxt|dkr4t|dts*t|dtr4|dWSt|dkrpt|dts\t|dtrpdd|dDWS|WSWntk r|YSXdS)NrrcSsg|]}|qSr r .0argr r r sz_get_args..)lenr tuplelistset AstVector TypeErrorargsr r r _get_argss( ( rMcCsHz*t|tttfr"dd|DWS|WSWntk rB|YSXdS)NcSsg|]}|qSr r rAr r r rDsz&_get_args_ast_list..)r rHrIrF ExceptionrKr r r _get_args_ast_lists  rOcCst|tr|rdSdSt|S)Ntruefalse)r boolstrvalr r r _to_param_values  rVcCsdSrr )cer r r z3_error_handlersrYc@s0eZdZdZddZddZddZdd Zd S) ContextabA Context manages all other Z3 objects, global configuration options, etc. Z3Py uses a default global context. For most applications this is sufficient. An application may use multiple Z3 contexts. Objects created in one context cannot be used in another one. However, several objects may be "translated" from one context to another. It is not safe to access Z3 objects from multiple threads. The only exception is the method `interrupt()` that can be used to interrupt() a long computation. The initialization method receives global configuration options for the new context. cOstrtt|ddkdt}|D]$}||}t|t|t|q&d}|D]*}|dkrf|}qTt|t|t|d}qTt||_ t |j t |_ t |j tt|dS)Nr3Argument list must have an even number of elements.)r r)rE Z3_mk_configZ3_set_param_valuerSupperrVZ3_mk_context_rcr:Z3_set_error_handlerrYehZ3_set_ast_print_modeZ3_PRINT_SMTLIB2_COMPLIANT Z3_del_config)selfrLkwsconfkeyrprevar r r __init__s   zContext.__init__cCst|jd|_d|_dSr)Z3_del_contextr:rbrfr r r __del__s zContext.__del__cCs|jS)z=Return a reference to the actual C pointer to the Z3 context.r:rnr r r r7sz Context.refcCst|dS)zInterrupt a solver performing a satisfiability test, a tactic processing a goal, or simplify functions. This method can be invoked from a thread different from the one executing the interruptible procedure. N) Z3_interruptr7rnr r r interruptszContext.interruptN)__name__ __module__ __qualname____doc__rlror7rrr r r r rZs  rZcCstdkrtatS)zReturn a reference to the global Z3 context. >>> x = Real('x') >>> x.ctx == main_ctx() True >>> c = Context() >>> c == main_ctx() False >>> x2 = Real('x', c) >>> x2.ctx == c True >>> eq(x, x2) False N) _main_ctxrZr r r r main_ctxsrxcCs|dkrtS|SdSr)rxrpr r r r6sr6cCst|Sr)r6rpr r r get_ctx sryc Ostrtt|ddkdi}|D]}||}t||s$|||<q$|D]"}||}tt|t|qHd}|D](}|dkr|}qttt|t|d}qtdS)zKSet Z3 global (or module) parameters. >>> set_param(precision=10) r[rr\N)r r)rEZ set_pp_optionZ3_global_param_setrSr_rV) rLrgZnew_kwskrrirrjrkr r r set_params   r|cCs tdS)z-Reset all global (or module) parameters. N)Z3_global_param_reset_allr r r r reset_params&sr~cOs t||S)z6Alias for 'set_param' for backward compatibility. )r|)rLrgr r r set_option,srcCs<tjd}tt||r,t|d}|Std|dS)ziReturn the value of a Z3 global (or module) parameter >>> get_param('nlsat.reorder') 'true' rrz!failed to retrieve value for '%s'N)rZc_char_pZ3_global_param_getrSrZ _to_pystrr()r,ptrrr r r get_param2s  rc@s eZdZdZddZddZdS) Z3PPObjectzDSuperclass for all Z3 objects that have support for pretty printing.cCsdSNTr rnr r r use_ppJszZ3PPObject.use_ppcCs"t}tdt|}t||Sr in_html_modeZ set_html_modereprrfZin_htmlresr r r _repr_html_Ms zZ3PPObject._repr_html_N)rsrtrurvrrr r r r rGsrc@seZdZdZd%ddZddZifddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#d$ZdS)&AstRefz[AST are Direct Acyclic Graphs (DAGs) used to represent sorts, declarations and expressions.NcCs(||_t||_t|j|dSr)astr6r: Z3_inc_refr7as_ast)rfrr:r r r rlXs zAstRef.__init__cCs6|jdk r2|jdk r2t|j|d|_dSr)r:r7r Z3_dec_refrrnr r r ro]szAstRef.__del__cCst|j|jSr) _to_ast_refrr:rfmemor r r __deepcopy__bszAstRef.__deepcopy__cCst|SrZ obj_to_stringrnr r r __str__eszAstRef.__str__cCst|Srrrnr r r __repr__hszAstRef.__repr__cCs ||Sreqrfotherr r r __eq__ksz AstRef.__eq__cCs|Sr)hashrnr r r __hash__nszAstRef.__hash__cCs|Sr)__bool__rnr r r __nonzero__qszAstRef.__nonzero__cCsNt|r dSt|rdSt|rB|dkrB|d|dStddS)NTFr[rrz?Symbolic expressions cannot be cast to concrete Boolean values.)is_trueis_falseis_eqnum_argsrCrr(rnr r r rtszAstRef.__bool__cCst||S)zReturn a string representing the AST node in s-expression notation. >>> x = Int('x') >>> ((x + 1)*x).sexpr() '(* (+ x 1) x)' Z3_ast_to_stringctx_refrrnr r r sexpr~sz AstRef.sexprcCs|jS)z6Return a pointer to the corresponding C Z3_ast object.rrnr r r rsz AstRef.as_astcCst||S)zMReturn unique identifier for object. It can be used for hash-tables and maps. Z3_get_ast_idrrrnr r r get_idsz AstRef.get_idcCs |jS)zBReturn a reference to the C context where this AST node is stored.r:r7rnr r r rszAstRef.ctx_refcCs,trtt|dt|||S)aReturn `True` if `self` and `other` are structurally identical. >>> x = Int('x') >>> n1 = x + 1 >>> n2 = 1 + x >>> n1.eq(n2) False >>> n1 = simplify(n1) >>> n2 = simplify(n2) >>> n1.eq(n2) True zZ3 AST expected)r r)is_ast Z3_is_eq_astrrrr r r rs z AstRef.eqcCs6trtt|tdtt|j|||S)aTranslate `self` to the context `target`. That is, return a copy of `self` in the context `target`. >>> c1 = Context() >>> c2 = Context() >>> x = Int('x', c1) >>> y = Int('y', c2) >>> # Nodes in different contexts can't be mixed. >>> # However, we can translate nodes from one context to another. >>> x.translate(c2) + y x + y argument must be a Z3 context) r r)r rZr Z3_translater:r7rrftargetr r r translates zAstRef.translatecCs ||jSrrr:rnr r r __copy__szAstRef.__copy__cCst||S)zReturn a hashcode for the `self`. >>> n1 = simplify(Int('x') + 1) >>> n2 = simplify(2 + Int('x') - 1) >>> n1.hash() == n2.hash() True )Z3_get_ast_hashrrrnr r r rsz AstRef.hash)N)rsrtrurvrlrorrrrrrrrrrrrrrrr r r r rUs$    rcCs t|tS)a/Return `True` if `a` is an AST node. >>> is_ast(10) False >>> is_ast(IntVal(10)) True >>> is_ast(Int('x')) True >>> is_ast(BoolSort()) True >>> is_ast(Function('f', IntSort(), IntSort())) True >>> is_ast("x") False >>> is_ast(Solver()) False )r rrkr r r rsrcCs&trtt|ot|d||S)aReturn `True` if `a` and `b` are structurally identical AST nodes. >>> x = Int('x') >>> y = Int('y') >>> eq(x, y) False >>> eq(x + 1, x + 1) True >>> eq(x + 1, 1 + x) False >>> eq(simplify(x + 1), simplify(1 + x)) True zZ3 ASTs expected)r r)rrrkbr r r rsrcCst|r|}t||Sr)rrZ3_get_ast_kindr7r:rkr r r _ast_kindsrcCsTd}|D]:}t|st|r|dkr,|j}qtrt||jkdq|dkrP|}|SNContext mismatch)ris_prober:r r))rL default_ctxr:rkr r r _ctx_from_ast_arg_listsrcGst|Sr)rrKr r r _ctx_from_ast_argssrcCs8t|}t|}t|D]}||||<q||fSr)rEFuncDeclrange as_func_declrLsz_argsir r r _to_func_decl_arrays   rcCs8t|}t|}t|D]}||||<q||fSr)rEAstrrrr r r _to_ast_array s   rcCs8t|}||}t|D]}||||<q||fSr)rErr)r7rLrrrr r r _to_ref_arrays   rcCs<t||}|tkrt||S|tkr.t||St||SdSr)rZ Z3_SORT_AST _to_sort_refZZ3_FUNC_DECL_AST_to_func_decl_ref _to_expr_ref)rkr:r{r r r rs    rcCst||Sr)Z3_get_sort_kindr7r?r r r _sort_kind*src@sXeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS)SortRefzTA Sort is essentially a type. Every Z3 expression has a sort. A sort is an AST node.cCst||jSr)Z3_sort_to_astrrrnr r r r1szSortRef.as_astcCst||Srrrnr r r r4szSortRef.get_idcCst|j|jS)aReturn the Z3 internal kind of a sort. This method can be used to test if `self` is one of the Z3 builtin sorts. >>> b = BoolSort() >>> b.kind() == Z3_BOOL_SORT True >>> b.kind() == Z3_INT_SORT False >>> A = ArraySort(IntSort(), IntSort()) >>> A.kind() == Z3_ARRAY_SORT True >>> A.kind() == Z3_INT_SORT False )rr:rrnr r r kind7sz SortRef.kindcCsdS)zqReturn `True` if `self` is a subsort of `other`. >>> IntSort().subsort(RealSort()) True Fr rr r r subsortHszSortRef.subsortcCs,tr(tt|dt||d|S)a Try to cast `val` as an element of sort `self`. This method is used in Z3Py to convert Python objects such as integers, floats, longs and strings into Z3 expressions. >>> x = Int('x') >>> RealSort().cast(x) ToReal(x) Z3 expression expectedz Sort mismatch)r r)is_exprrsortrfrUr r r castPs z SortRef.castcCst|jt||jS)zReturn the name (string) of sort `self`. >>> BoolSort().name() 'Bool' >>> ArraySort(IntSort(), IntSort()).name() 'Array' )r@r:Z3_get_sort_namerrrnr r r r,_sz SortRef.namecCs |dkr dSt||j|jS)zReturn `True` if `self` and `other` are the same Z3 sort. >>> p = Bool('p') >>> p.sort() == BoolSort() True >>> p.sort() == IntSort() False NF Z3_is_eq_sortrrrr r r ris zSortRef.__eq__cCst||j|j S)zReturn `True` if `self` and `other` are not the same Z3 sort. >>> p = Bool('p') >>> p.sort() != BoolSort() False >>> p.sort() != IntSort() True rrr r r __ne__vs zSortRef.__ne__cCs t|Sz Hash code. rrrnr r r rszSortRef.__hash__N) rsrtrurvrrrrrr,rrrr r r r r.s   rcCs t|tS)zReturn `True` if `s` is a Z3 sort. >>> is_sort(IntSort()) True >>> is_sort(Int('x')) False >>> is_expr(Int('x')) True )r rr2r r r is_sorts rcCstrtt|tdt||}|tkr2t||S|tksB|tkrLt ||S|t kr^t ||S|t krpt ||S|tkrt||S|tkrt||S|tkrt||S|tkrt||S|tkrt||S|tkrt||St||S)NzZ3 Sort expected)r r)r Sortr Z3_BOOL_SORT BoolSortRef Z3_INT_SORT Z3_REAL_SORT ArithSortRef Z3_BV_SORT BitVecSortRef Z3_ARRAY_SORT ArraySortRefZ3_DATATYPE_SORTDatatypeSortRefZ3_FINITE_DOMAIN_SORTFiniteDomainSortRefZ3_FLOATING_POINT_SORT FPSortRefZ3_ROUNDING_MODE_SORT FPRMSortRef Z3_RE_SORT ReSortRef Z3_SEQ_SORT SeqSortRefr)r3r:r{r r r rs0           rcCstt|||Sr)r Z3_get_sortr7rr r r _sortsrcCs"t|}tt|t|||S)a*Create a new uninterpreted sort named `name`. If `ctx=None`, then the new sort is declared in the global Z3Py context. >>> A = DeclareSort('A') >>> a = Const('a', A) >>> b = Const('b', A) >>> a.sort() == A True >>> b.sort() == A True >>> a == b a == b )r6rZ3_mk_uninterpreted_sortr7r;r,r:r r r DeclareSortsrc@s`eZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ dS) FuncDeclRefaFunction declaration. Every constant and function have an associated declaration. The declaration assigns a name, a sort (i.e., type), and for function the sort (i.e., type) of each of its arguments. Note that, in Z3, a constant is a function with 0 arguments. cCst||jSr)Z3_func_decl_to_astrrrnr r r rszFuncDeclRef.as_astcCst||Srrrnr r r rszFuncDeclRef.get_idcCs|jSrrrnr r r rszFuncDeclRef.as_func_declcCst|jt||jS)zReturn the name of the function declaration `self`. >>> f = Function('f', IntSort(), IntSort()) >>> f.name() 'f' >>> isinstance(f.name(), str) True )r@r:Z3_get_decl_namerrrnr r r r,s zFuncDeclRef.namecCstt||jS)zReturn the number of arguments of a function declaration. If `self` is a constant, then `self.arity()` is 0. >>> f = Function('f', IntSort(), RealSort(), BoolSort()) >>> f.arity() 2 )r Z3_get_arityrrrnr r r arityszFuncDeclRef.aritycCs2trt||kdtt||j||jS)a Return the sort of the argument `i` of a function declaration. This method assumes that `0 <= i < self.arity()`. >>> f = Function('f', IntSort(), RealSort(), BoolSort()) >>> f.domain(0) Int >>> f.domain(1) Real zIndex out of bounds)r r)rr Z3_get_domainrrr:rfrr r r domains zFuncDeclRef.domaincCstt||j|jS)zReturn the sort of the range of a function declaration. For constants, this is the sort of the constant. >>> f = Function('f', IntSort(), RealSort(), BoolSort()) >>> f.range() Bool )r Z3_get_rangerrr:rnr r r rszFuncDeclRef.rangecCst||jS)a4Return the internal kind of a function declaration. It can be used to identify Z3 built-in functions such as addition, multiplication, etc. >>> x = Int('x') >>> d = (x + 1).decl() >>> d.kind() == Z3_OP_ADD True >>> d.kind() == Z3_OP_MUL False )Z3_get_decl_kindrrrnr r r r s zFuncDeclRef.kindcCsL|j}t||j}ddt|D}t|D]}t||j|}|tkrht||j|||<q0|tkrt ||j|||<q0|t krt ||j|||<q0|t krt ||j|||<q0|tkrtt||j||||<q0|tkrtt||j||||<q0|tkr>tt||j||||<q0ds0tq0|S)NcSsg|]}dqSrr rBrr r r rDsz&FuncDeclRef.params..F)r:Z3_get_decl_num_parametersrrrZ3_get_decl_parameter_kindZZ3_PARAMETER_INTZ3_get_decl_int_parameterZZ3_PARAMETER_DOUBLEZ3_get_decl_double_parameterZZ3_PARAMETER_RATIONALZ3_get_decl_rational_parameterZZ3_PARAMETER_SYMBOLZ3_get_decl_symbol_parameterZZ3_PARAMETER_SORTrZ3_get_decl_sort_parameterZZ3_PARAMETER_ASTExprRefZ3_get_decl_ast_parameterZZ3_PARAMETER_FUNC_DECLrZ3_get_decl_func_decl_parameterAssertionError)rfr:r+resultrr{r r r paramss*   zFuncDeclRef.paramscGst|}t|}tr,t||kd|t|}g}t|D].}||||}| || ||<qBt t | |jt|||jS)aCreate a Z3 application expression using the function `self`, and the given arguments. The arguments must be Z3 expressions. This method assumes that the sorts of the elements in `args` match the sorts of the domain. Limited coercion is supported. For example, if args[0] is a Python integer, and the function expects a Z3 integer, then the argument is automatically converted into a Z3 integer. >>> f = Function('f', IntSort(), RealSort(), BoolSort()) >>> x = Int('x') >>> y = Real('y') >>> f(x, y) f(x, y) >>> f(x, x) f(x, ToReal(x)) z#Incorrect number of arguments to %s)rMrEr r)rrrrrappendrr Z3_mk_apprrr:)rfrLnumrZsavedrZtmpr r r __call__.s   zFuncDeclRef.__call__N)rsrtrurvrrrr,rrrrrrr r r r rs    rcCs t|tS)zReturn `True` if `a` is a Z3 function declaration. >>> f = Function('f', IntSort(), IntSort()) >>> is_func_decl(f) True >>> x = Real('x') >>> is_func_decl(x) False )r rrr r r is_func_declOs rcGst|}tr tt|dkdt|d}||}trHtt|dt|}t|D]*}trvtt||d||j||<qZ|j}t t | t |||||j|S)zCreate a new Z3 uninterpreted function with the given sorts. >>> f = Function('f', IntSort(), IntSort()) >>> f(f(0)) f(f(0)) rAt least two arguments expectedrZ3 sort expected) rMr r)rErrrrr:rZ3_mk_func_declr7r;r,sigrrngdomrr:r r r Function\s   r$cGst|}tr tt|dkdt|d}||}trHtt|dtj|}t|D]*}trxtt||d||j||<q\|j }t t | d|||j|S)zGCreate a new fresh Z3 uninterpreted function with the given sorts. rrrrf) rMr r)rErz3rrrr:rZ3_mk_fresh_func_declr7)r!rr"r#rr:r r r FreshFunctionss   r(cCs t||Sr)rrkr:r r r rsrcGst|}tr tt|dkdt|d}||}trHtt|dt|}t|D]*}trvtt||d||j||<qZ|j}t t | t |||||j|S)z/Create a new Z3 recursive with the given sorts.rrrr) rMr r)rErrrrr:rZ3_mk_rec_func_declr7r;r r r r RecFunctions   r+cCsft|r|g}|j}t|}t|}t|}t|D]}||j||<q6t||j|||jdS)aSet the body of a recursive function. Recursive definitions can be simplified if they are applied to ground arguments. >>> ctx = Context() >>> fac = RecFunction('fac', IntSort(ctx), IntSort(ctx)) >>> n = Int('n', ctx) >>> RecAddDefinition(fac, n, If(n == 0, 1, n*fac(n-1))) >>> simplify(fac(5)) 120 >>> s = Solver(ctx=ctx) >>> s.add(fac(n) < 3) >>> s.check() sat >>> s.model().eval(fac(5)) 120 N) is_appr:rMrErrrZ3_add_rec_defr7)r%rLbodyr:r+rrr r r RecAddDefinitions  r/c@speZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZdS)ralConstraints, formulas and terms are expressions in Z3. Expressions are ASTs. Every expression has a sort. There are three main kinds of expressions: function applications, quantifiers and bounded variables. A constant is a function application with 0 arguments. For quantifier free problems, all expressions are function applications. cCs|jSrrrnr r r rszExprRef.as_astcCst||Srrrnr r r rszExprRef.get_idcCst|j|S)zReturn the sort of expression `self`. >>> x = Int('x') >>> (x + 1).sort() Int >>> y = Real('y') >>> (x + y).sort() Real )rr:rrnr r r rs z ExprRef.sortcCs |S)zShorthand for `self.sort().kind()`. >>> a = Array('a', IntSort(), IntSort()) >>> a.sort_kind() == Z3_ARRAY_SORT True >>> a.sort_kind() == Z3_INT_SORT False )rrrnr r r sort_kinds zExprRef.sort_kindcCs:|dkr dSt||\}}tt||||jS)aReturn a Z3 expression that represents the constraint `self == other`. If `other` is `None`, then this method simply returns `False`. >>> a = Int('a') >>> b = Int('b') >>> a == b a == b >>> a is None False NF) _coerce_exprsBoolRefZ3_mk_eqrrr:rfrrkrr r r rs zExprRef.__eq__cCs t|Srrrnr r r rszExprRef.__hash__cCsB|dkr dSt||\}}t||f\}}tt|d||jS)aReturn a Z3 expression that represents the constraint `self != other`. If `other` is `None`, then this method simply returns `True`. >>> a = Int('a') >>> b = Int('b') >>> a != b a != b >>> a is not None True NTr[)r1rr2Z3_mk_distinctrr:)rfrrkrrrr r r rs zExprRef.__ne__cCs |Sr)declrrnr r r r szExprRef.paramscCs.trtt|dtt|||jS)zReturn the Z3 function declaration associated with a Z3 application. >>> f = Function('f', IntSort(), IntSort()) >>> a = Int('a') >>> t = f(a) >>> eq(t.decl(), f) True >>> (a + 1).decl() + Z3 application expected)r r)r,rZ3_get_app_declrrr:rnr r r r6s z ExprRef.declcCs*trtt|dtt||S)a Return the number of arguments of a Z3 application. >>> a = Int('a') >>> b = Int('b') >>> (a + b).num_args() 2 >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort()) >>> t = f(a, b, 0) >>> t.num_args() 3 r7)r r)r,rZ3_get_app_num_argsrrrnr r r rs zExprRef.num_argscCsBtr&tt|dt||kdtt||||jS)aReturn argument `idx` of the application `self`. This method assumes that `self` is a function application with at least `idx+1` arguments. >>> a = Int('a') >>> b = Int('b') >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort()) >>> t = f(a, b, 0) >>> t.arg(0) a >>> t.arg(1) b >>> t.arg(2) 0 r7zInvalid argument index) r r)r,rrZ3_get_app_argrrr:rfidxr r r rC/sz ExprRef.argcs*tr"fddtDSgSdS)a Return a list containing the children of the given expression >>> a = Int('a') >>> b = Int('b') >>> f = Function('f', IntSort(), IntSort(), IntSort(), IntSort()) >>> t = f(a, b, 0) >>> t.children() [a, b, 0] csg|]}|qSr rCr rnr r rDOsz$ExprRef.children..N)r,rrrnr rnr childrenDs zExprRef.childrenN)rsrtrurvrrrr0rrrrr6rrCr>r r r r rs   rcCst|trt||S|}t||}|tkr8t||St|t||}|t krZt ||S|t kr~|t krtt ||St||S|tkr|t krt||St||rt||St||S|tkr|t krt||St||S|tkrt||S|tkrt||S|tkr4|tkr*t||r*t||St||S|tkr\|t krRt ||St!||S|t"krpt#||S|t$krt%||S|t&krt'||St(||Sr))r Pattern PatternRefr7rZZ3_QUANTIFIER_AST QuantifierRefrrrr2rZ3_NUMERAL_AST IntNumRefArithRefr RatNumRef _is_algebraicAlgebraicNumRefr BitVecNumRef BitVecRefrArrayRefr DatatypeRefr Z3_APP_AST _is_numeralFPNumRefFPRefrFiniteDomainNumRefFiniteDomainRefrFPRMRefrSeqRefrReRefr)rkr:rr{skr r r rTsT                             rcCsrt|rj|}|dkr|S||r*|S||r8|S||rF|Strnt|j|jkdtddn|SdS)Ncontext mismatchF sort mismatch)rrrrr r)r:)r3rks1r r r _coerce_expr_merges    rYcCst|s$t|s$t||}t||}t|trDt|trDt||j}t|trdt|trdt||j}d}t||}t||}||}||}||fSr) r_py2exprr rSrS StringValr:rYrrkrr:r3r r r r1s        r1cCs|}|D]}|||}q|Srr )funcZsequenceinitialrelementr r r _reduces r`csRd}|D]}t|rd}qq|s4fdd|D}tt|dfdd|DS)NFTcsg|]}t|qSr )rZrBrkrpr r rDsz%_coerce_expr_list..csg|]}|qSr )rrar2r r rDs)rr`rY)alistr:Zhas_exprrkr r?r _coerce_expr_lists rccCs t|tS)aKReturn `True` if `a` is a Z3 expression. >>> a = Int('a') >>> is_expr(a) True >>> is_expr(a + 1) True >>> is_expr(IntSort()) False >>> is_expr(1) False >>> is_expr(IntVal(1)) True >>> x = Int('x') >>> is_expr(ForAll(x, x >= 0)) True >>> is_expr(FPVal(1.0)) True )r rrr r r rsrcCs*t|tsdSt|j|}|tkp(|tkS)aqReturn `True` if `a` is a Z3 function application. Note that, constants are function applications with 0 arguments. >>> a = Int('a') >>> is_app(a) True >>> is_app(a + 1) True >>> is_app(IntSort()) False >>> is_app(1) False >>> is_app(IntVal(1)) True >>> x = Int('x') >>> is_app(ForAll(x, x >= 0)) False F)r rrr:rBrLrkr{r r r r,s  r,cCst|o|dkS)aReturn `True` if `a` is Z3 constant/variable expression. >>> a = Int('a') >>> is_const(a) True >>> is_const(a + 1) False >>> is_const(1) False >>> is_const(IntVal(1)) True >>> x = Int('x') >>> is_const(ForAll(x, x >= 0)) False r)r,rrr r r is_constsrecCst|ot|j|tkS)aReturn `True` if `a` is variable. Z3 uses de-Bruijn indices for representing bound variables in quantifiers. >>> x = Int('x') >>> is_var(x) False >>> is_const(x) True >>> f = Function('f', IntSort(), IntSort()) >>> # Z3 replaces x with bound variables when ForAll is executed. >>> q = ForAll(x, f(x) == x) >>> b = q.body() >>> b f(Var(0)) == Var(0) >>> b.arg(1) Var(0) >>> is_var(b.arg(1)) True )rrr:Z Z3_VAR_ASTrr r r is_varsrfcCs,trtt|dtt|j|S)asReturn the de-Bruijn index of the Z3 bounded variable `a`. >>> x = Int('x') >>> y = Int('y') >>> is_var(x) False >>> is_const(x) True >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> # Z3 replaces x and y with bound variables when ForAll is executed. >>> q = ForAll([x, y], f(x, y) == x + y) >>> q.body() f(Var(1), Var(0)) == Var(1) + Var(0) >>> b = q.body() >>> b.arg(0) f(Var(1), Var(0)) >>> v1 = b.arg(0).arg(0) >>> v2 = b.arg(0).arg(1) >>> v1 Var(1) >>> v2 Var(0) >>> get_var_index(v1) 1 >>> get_var_index(v2) 0 zZ3 bound variable expected)r r)rfrZ3_get_index_valuer:r7rrr r r get_var_indexsrhcCst|o||kS)zReturn `True` if `a` is an application of the given kind `k`. >>> x = Int('x') >>> n = x + 1 >>> is_app_of(n, Z3_OP_ADD) True >>> is_app_of(n, Z3_OP_MUL) False )r,r6rrdr r r is_app_of8s ricCst|tst|tst|tr,t||||Stt|||g|}t|}||}t|||\}}t rzt |j |j kdt t |||||SdS)zCreate a Z3 if-then-else expression. >>> x = Int('x') >>> y = Int('y') >>> max = If(x > y, x, y) >>> max If(x > y, x, y) >>> simplify(max) If(x <= y, y, x) rN)r ProbeTacticCondr6rBoolSortrr1r r)r:r Z3_mk_iter7r)rkrrWr:r3r r r IfEs  rocGsPt|}t|}tr$t|dk dt||}t|\}}tt||||S)aYCreate a Z3 distinct expression. >>> x = Int('x') >>> y = Int('y') >>> Distinct(x, y) x != y >>> z = Int('z') >>> Distinct(x, y, z) Distinct(x, y, z) >>> simplify(Distinct(x, y, z)) Distinct(x, y, z) >>> simplify(Distinct(x, y, z), blast_distinct=True) And(Not(x == y), Not(x == z), Not(y == z)) N5At least one of the arguments must be a Z3 expression) rMrr r)rcrr2r5r7rLr:rrr r r Distinct\s  rrcCsLtd}tr"t|j|jkd||d<||d<||jd|S)Nr[rrr)rr r)r:rr7)r%rkrrLr r r _mk_bints    rscCs:trtt|td|j}tt|t|||j |S)zNCreate a constant of the given sort. >>> Const('x', IntSort()) x r) r r)r rr:r Z3_mk_constr7r;r)r,rr:r r r Const}srucs&t|tr|d}fdd|DS)aCreate several constants of the given sort. `names` is a string containing the names of all constants to be created. Blank spaces separate the names of different constants. >>> x, y, z = Consts('x y z', IntSort()) >>> x + y + z x + y + z  csg|]}t|qSr )rurBr,rr r rDszConsts..)r rSsplit)namesrr rxr Constss  r{rWcCs"t|j}tt|||j|S)z+Create a fresh constant of a specified sort)r6r:rZ3_mk_fresh_constr7r)rprefixr:r r r FreshConsts r~cCs.trtt|dtt|||j|jS)zCreate a Z3 free variable. Free variables are used to create quantified formulas. >>> Var(0, IntSort()) Var(0) >>> eq(Var(0, IntSort()), Var(0, BoolSort())) False r)r r)rr Z3_mk_boundrrr:)r<r3r r r VarsrcCst|t|S)z Create a real free variable. Free variables are used to create quantified formulas. They are also used to create polynomials. >>> RealVar(0) Var(0) )rRealSort)r<r:r r r RealVarsrcsfddt|DS)z Create a list of Real free variables. The variables have ids: 0, 1, ..., n-1 >>> x0, x1, x2, x3 = RealVarVector(4) >>> x2 Var(2) csg|]}t|qSr )rr rpr r rDsz!RealVarVector..r)r+r:r rpr RealVarVectors rc@s0eZdZdZddZddZddZdd Zd S) rz Boolean sort.cCsht|trt||jStrdt|sBd}tt|||t|f|| sdt|| d|S)zTry to cast `val` as a Boolean. >>> x = BoolSort().cast(True) >>> x True >>> is_expr(x) True >>> is_expr(True) False >>> x.sort() Bool zETrue, False or Z3 Boolean expression expected. Received %s of type %sz1Value cannot be converted into a Z3 Boolean value) r rRBoolValr:r rr)typerr)rfrUrr r r rs  zBoolSortRef.castcCs t|tSrr rrr r r rszBoolSortRef.subsortcCsdSrr rnr r r is_intszBoolSortRef.is_intcCsdSrr rnr r r is_boolszBoolSortRef.is_boolN)rsrtrurvrrrrr r r r rs rc@s(eZdZdZddZddZddZdS) r2z4All Boolean expressions are instances of this class.cCstt|||jSr)rrrrr:rnr r r rsz BoolRef.sortcCs||Srr rr r r __rmul__szBoolRef.__rmul__cCs$|dkr |S|dkrdSt||dS)z1Create the Z3 expression `self * other`. rr)rorr r r __mul__s zBoolRef.__mul__N)rsrtrurvrrrr r r r r2sr2cCs t|tS)zReturn `True` if `a` is a Z3 Boolean expression. >>> p = Bool('p') >>> is_bool(p) True >>> q = Bool('q') >>> is_bool(And(p, q)) True >>> x = Real('x') >>> is_bool(x) False >>> is_bool(x == 0) True )r r2rr r r rsrcCs t|tS)aReturn `True` if `a` is the Z3 true expression. >>> p = Bool('p') >>> is_true(p) False >>> is_true(simplify(p == p)) True >>> x = Real('x') >>> is_true(x == 0) False >>> # True is a Python Boolean expression >>> is_true(True) False )riZ Z3_OP_TRUErr r r rsrcCs t|tS)zReturn `True` if `a` is the Z3 false expression. >>> p = Bool('p') >>> is_false(p) False >>> is_false(False) False >>> is_false(BoolVal(False)) True )riZ Z3_OP_FALSErr r r r#s rcCs t|tS)zReturn `True` if `a` is a Z3 and expression. >>> p, q = Bools('p q') >>> is_and(And(p, q)) True >>> is_and(Or(p, q)) False )riZ Z3_OP_ANDrr r r is_and1s rcCs t|tS)zReturn `True` if `a` is a Z3 or expression. >>> p, q = Bools('p q') >>> is_or(Or(p, q)) True >>> is_or(And(p, q)) False )riZZ3_OP_ORrr r r is_or=s rcCs t|tS)zReturn `True` if `a` is a Z3 implication expression. >>> p, q = Bools('p q') >>> is_implies(Implies(p, q)) True >>> is_implies(And(p, q)) False )riZ Z3_OP_IMPLIESrr r r is_impliesIs rcCs t|tS)zReturn `True` if `a` is a Z3 not expression. >>> p = Bool('p') >>> is_not(p) False >>> is_not(Not(p)) True )riZ Z3_OP_NOTrr r r is_notUs rcCs t|tS)zqReturn `True` if `a` is a Z3 equality expression. >>> x, y = Ints('x y') >>> is_eq(x == y) True )riZZ3_OP_EQrr r r rasrcCs t|tS)zReturn `True` if `a` is a Z3 distinct expression. >>> x, y, z = Ints('x y z') >>> is_distinct(x == y) False >>> is_distinct(Distinct(x, y, z)) True )riZZ3_OP_DISTINCTrr r r is_distinctks rcCst|}tt||S)a&Return the Boolean Z3 sort. If `ctx=None`, then the global context is used. >>> BoolSort() Bool >>> p = Const('p', BoolSort()) >>> is_bool(p) True >>> r = Function('r', IntSort(), IntSort(), BoolSort()) >>> r(0, 1) r(0, 1) >>> is_bool(r(0, 1)) True )r6rZ3_mk_bool_sortr7rpr r r rmwsrmcCs4t|}|rtt||Stt||SdS)zReturn the Boolean value `True` or `False`. If `ctx=None`, then the global context is used. >>> BoolVal(True) True >>> is_true(BoolVal(True)) True >>> is_true(True) False >>> is_false(BoolVal(False)) True N)r6r2 Z3_mk_truer7 Z3_mk_falserUr:r r r rs rcCs*t|}tt|t||t|j|S)zReturn a Boolean constant named `name`. If `ctx=None`, then the global context is used. >>> p = Bool('p') >>> q = Bool('q') >>> And(p, q) And(p, q) )r6r2rtr7r;rmrrr r r Boolsrcs.tt|tr|d}fdd|DS)zReturn a tuple of Boolean constants. `names` is a single string containing all names separated by blank spaces. If `ctx=None`, then the global context is used. >>> p, q, r = Bools('p q r') >>> And(p, Or(q, r)) And(p, Or(q, r)) rvcsg|]}t|qSr rrwrpr r rDszBools..r6r rSryrzr:r rpr Boolss   rcsfddt|DS)aReturn a list of Boolean constants of size `sz`. The constants are named using the given prefix. If `ctx=None`, then the global context is used. >>> P = BoolVector('p', 3) >>> P [p__0, p__1, p__2] >>> And(P) And(p__0, p__1, p__2) csg|]}td|fqSz%s__%srr r}r r rDszBoolVector..rr}rr:r rr BoolVectors rrcCs$t|}tt||t|j|S)zReturn a fresh Boolean constant in the given context using the given prefix. If `ctx=None`, then the global context is used. >>> b1 = FreshBool() >>> b2 = FreshBool() >>> eq(b1, b2) False )r6r2r|r7rmrr}r:r r r FreshBools rcCsLtt||g|}t|}||}||}tt||||S)ziCreate a Z3 implies expression. >>> p, q = Bools('p q') >>> Implies(p, q) Implies(p, q) )r6rrmrr2 Z3_mk_impliesr7rr\r r r Impliess   rcCsLtt||g|}t|}||}||}tt||||S)zCreate a Z3 Xor expression. >>> p, q = Bools('p q') >>> Xor(p, q) Xor(p, q) >>> simplify(Xor(p, q)) Not(p) == q )r6rrmrr2 Z3_mk_xorr7rr\r r r Xors   rcCs\tt|g|}t|r.tt||j|St|}||}t t || |SdS)zCreate a Z3 not expression or probe. >>> p = Bool('p') >>> Not(Not(p)) Not(Not(p)) >>> simplify(Not(Not(p))) p N) r6rrrj Z3_probe_notr7probermrr2 Z3_mk_notr)rkr:r3r r r Nots  rcCst|r|dSt|SdSr#)rrCrrr r r mk_nots rcCs|D]}t|rdSqdS)zKReturn `True` if one of the elements of the given collection is a Z3 probe.TF)r)rLrCr r r _has_probe srcGsd}t|dkr |t|d}t|trP|t|d}|dt|d}n>> p, q, r = Bools('p q r') >>> And(p, q, r) And(p, q, r) >>> P = BoolVector('p', 5) >>> And(P) And(p__0, p__1, p__2, p__3, p__4) NrrcSsg|]}|qSr r rar r r rD'szAnd..>At least one of the arguments must be a Z3 expression or probe)rEr rZrIr:rMr6rr r)r _probe_andrcrr2 Z3_mk_andr7rLZlast_argr:rrr r r Ands&       rcGsd}t|dkr |t|d}t|trP|t|d}|dt|d}n>> p, q, r = Bools('p q r') >>> Or(p, q, r) Or(p, q, r) >>> P = BoolVector('p', 5) >>> Or(P) Or(p__0, p__1, p__2, p__3, p__4) NrrcSsg|]}|qSr r rar r r rDHszOr..r)rEr rZrIr:rMr6rr r)r _probe_orrcrr2Z3_mk_orr7rr r r Or6s&       rc@s eZdZdZddZddZdS)r@z6Patterns are hints for quantifier instantiation. cCst||jSr)Z3_pattern_to_astrrrnr r r rbszPatternRef.as_astcCst||Srrrnr r r reszPatternRef.get_idN)rsrtrurvrrr r r r r@]sr@cCs t|tS)aXReturn `True` if `a` is a Z3 pattern (hint for quantifier instantiation. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ]) >>> q ForAll(x, f(x) == 0) >>> q.num_patterns() 1 >>> is_pattern(q.pattern(0)) True >>> q.pattern(0) f(Var(0)) )r r@rr r r is_patternisrcGs\tr0tt|dkdttdd|Dd|dj}t|\}}tt||||S)aCreate a Z3 multi-pattern using the given expressions `*args` >>> f = Function('f', IntSort(), IntSort()) >>> g = Function('g', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) != g(x), patterns = [ MultiPattern(f(x), g(x)) ]) >>> q ForAll(x, f(x) != g(x)) >>> q.num_patterns() 1 >>> is_pattern(q.pattern(0)) True >>> q.pattern(0) MultiPattern(f(Var(0)), g(Var(0))) rAt least one argument expectedcSsg|] }t|qSr rrar r r rDsz MultiPattern..zZ3 expressions expected) r r)rEallr:rr@ Z3_mk_patternr7)rLr:rr r r MultiPattern{s   rcCst|r |St|SdSr)rrr=r r r _to_patternsrc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd"d#Zd$S)%rAz2Universally and Existentially quantified formulas.cCs|jSrrrnr r r rszQuantifierRef.as_astcCst||Srrrnr r r rszQuantifierRef.get_idcCs"|rt|j|St|jS)z*Return the Boolean sort or sort of Lambda.) is_lambdarr:rrmrnr r r rszQuantifierRef.sortcCst||jS)a"Return `True` if `self` is a universal quantifier. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) == 0) >>> q.is_forall() True >>> q = Exists(x, f(x) != 0) >>> q.is_forall() False )Z3_is_quantifier_forallrrrnr r r is_foralls zQuantifierRef.is_forallcCst||jS)a%Return `True` if `self` is an existential quantifier. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) == 0) >>> q.is_exists() False >>> q = Exists(x, f(x) != 0) >>> q.is_exists() True )Z3_is_quantifier_existsrrrnr r r is_existss zQuantifierRef.is_existscCst||jS)aReturn `True` if `self` is a lambda expression. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = Lambda(x, f(x)) >>> q.is_lambda() True >>> q = Exists(x, f(x) != 0) >>> q.is_lambda() False ) Z3_is_lambdarrrnr r r rs zQuantifierRef.is_lambdacCsFtrt|d||}tt|| | |j S)z.Return the Z3 expression `self[arg]`. z(quantifier should be a lambda expression) r r)rrrrr Z3_mk_selectrrr:rfrCr r r __getitem__szQuantifierRef.__getitem__cCstt||jS)aReturn the weight annotation of `self`. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) == 0) >>> q.weight() 1 >>> q = ForAll(x, f(x) == 0, weight=10) >>> q.weight() 10 )rZ3_get_quantifier_weightrrrnr r r weights zQuantifierRef.weightcCstt||jS)aDReturn the number of patterns (i.e., quantifier instantiation hints) in `self`. >>> f = Function('f', IntSort(), IntSort()) >>> g = Function('g', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ]) >>> q.num_patterns() 2 )rZ3_get_quantifier_num_patternsrrrnr r r num_patternss zQuantifierRef.num_patternscCs2trt||kdtt||j||jS)aReturn a pattern (i.e., quantifier instantiation hints) in `self`. >>> f = Function('f', IntSort(), IntSort()) >>> g = Function('g', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) != g(x), patterns = [ f(x), g(x) ]) >>> q.num_patterns() 2 >>> q.pattern(0) f(Var(0)) >>> q.pattern(1) g(Var(0)) zInvalid pattern idx)r r)rr@Z3_get_quantifier_pattern_astrrr:r;r r r patternszQuantifierRef.patterncCst||jS)z!Return the number of no-patterns.)!Z3_get_quantifier_num_no_patternsrrrnr r r num_no_patterns szQuantifierRef.num_no_patternscCs2trt||kdtt||j||jS)zReturn a no-pattern.zInvalid no-pattern idx)r r)rr Z3_get_quantifier_no_pattern_astrrr:r;r r r no_patternszQuantifierRef.no_patterncCstt||j|jS)zReturn the expression being quantified. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) == 0) >>> q.body() f(Var(0)) == 0 )rZ3_get_quantifier_bodyrrr:rnr r r r.s zQuantifierRef.bodycCstt||jS)aReturn the number of variables bounded by this quantifier. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> x = Int('x') >>> y = Int('y') >>> q = ForAll([x, y], f(x, y) >= x) >>> q.num_vars() 2 )rZ3_get_quantifier_num_boundrrrnr r r num_vars"s zQuantifierRef.num_varscCs2trt||kdt|jt||j|S)a<Return a string representing a name used when displaying the quantifier. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> x = Int('x') >>> y = Int('y') >>> q = ForAll([x, y], f(x, y) >= x) >>> q.var_name(0) 'x' >>> q.var_name(1) 'y' Invalid variable idx)r r)rr@r:Z3_get_quantifier_bound_namerrr;r r r var_name.s zQuantifierRef.var_namecCs2trt||kdtt||j||jS)aReturn the sort of a bound variable. >>> f = Function('f', IntSort(), RealSort(), IntSort()) >>> x = Int('x') >>> y = Real('y') >>> q = ForAll([x, y], f(x, y) >= x) >>> q.var_sort(0) Int >>> q.var_sort(1) Real r)r r)rrZ3_get_quantifier_bound_sortrrr:r;r r r var_sort>s zQuantifierRef.var_sortcCs |gS)zReturn a list containing a single element self.body() >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) == 0) >>> q.children() [f(Var(0)) == 0] )r.rnr r r r>Ns zQuantifierRef.childrenN)rsrtrurvrrrrrrrrrrrrr.rrrr>r r r r rAs$   rAcCs t|tS)zReturn `True` if `a` is a Z3 quantifier. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> q = ForAll(x, f(x) == 0) >>> is_quantifier(q) True >>> is_quantifier(f(x)) False )r rArr r r is_quantifierZs rcCstrtt|p.t|p.t|dko.t|ddtt|pZt|dkoZtdd|Ddttdd|Ddttdd|Dd t|r|j}|g}n |dj}t|st ||}t|} | dkr|St | } t | D]} ||  | | <qd d|D}t|} t | } t | D]} || j| | <q&t|\}}t||}t||}tt|||||| | | | ||| |S) NrrcSsg|] }t|qSr )rerBrr r r rDksz"_mk_quantifier..zInvalid bounded variable(s)cSsg|]}t|pt|qSr )rrrar r r rDlszZ3 patterns expectedcSsg|] }t|qSr rrBpr r r rDmszno patterns are Z3 expressionscSsg|] }t|qSr )rrr r r rD|s)r r)rr,rErerr:rrrrrr?rrr;rAZ3_mk_quantifier_const_exr7)rvsr.rqidskidpatterns no_patternsr:r_vsrZnum_patsZ_patsZ_no_patsZ num_no_patsr r r _mk_quantifierhsH.,         rc Cstd|||||||S)aCreate a Z3 forall formula. The parameters `weight`, `qid`, `skid`, `patterns` and `no_patterns` are optional annotations. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> x = Int('x') >>> y = Int('y') >>> ForAll([x, y], f(x, y) >= x) ForAll([x, y], f(x, y) >= x) >>> ForAll([x, y], f(x, y) >= x, patterns=[ f(x, y) ]) ForAll([x, y], f(x, y) >= x) >>> ForAll([x, y], f(x, y) >= x, weight=10) ForAll([x, y], f(x, y) >= x) Trrr.rrrrrr r r ForAllsrc Cstd|||||||S)aCreate a Z3 exists formula. The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> x = Int('x') >>> y = Int('y') >>> q = Exists([x, y], f(x, y) >= x, skid="foo") >>> q Exists([x, y], f(x, y) >= x) >>> is_quantifier(q) True >>> r = Tactic('nnf')(q).as_expr() >>> is_quantifier(r) False Frrr r r ExistssrcCs`|j}t|r|g}t|}t|}t|D]}||||<q.tt|||||S)a?Create a Z3 lambda expression. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> mem0 = Array('mem0', IntSort(), IntSort()) >>> lo, hi, e, i = Ints('lo hi e i') >>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i])) >>> mem1 Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i])) ) r:r,rErrrrAZ3_mk_lambda_constr7)rr.r:rrrr r r Lambdas   rc@s0eZdZdZddZddZddZdd Zd S) rzReal and Integer sorts.cCs |tkS)zReturn `True` if `self` is of the sort Real. >>> x = Real('x') >>> x.is_real() True >>> (x + 1).is_real() True >>> x = Int('x') >>> x.is_real() False )rrrnr r r is_reals zArithSortRef.is_realcCs |tkS)zReturn `True` if `self` is of the sort Integer. >>> x = Int('x') >>> x.is_int() True >>> (x + 1).is_int() True >>> x = Real('x') >>> x.is_int() False )rrrnr r r rs zArithSortRef.is_intcCs|ot|o|S)z0Return `True` if `self` is a subsort of `other`.)r is_arith_sortrrr r r rszArithSortRef.subsortcCst|rtr t|j|jkd|}||r6|S|rN|rNt|S| rj|rjt |ddS| r|rtt |ddStrtddn@|rt ||jS|rt ||jStrd}td||dS)aTry to cast `val` as an Integer or Real. >>> IntSort().cast(10) 10 >>> is_int(IntSort().cast(10)) True >>> is_int(10) False >>> RealSort().cast(10) 10 >>> is_real(RealSort().cast(10)) True rrrFz#Z3 Integer/Real expression expectedzRint, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %sN) rr r)r:rrrrToRealrroIntValRealVal)rfrUZval_srr r r rs*     zArithSortRef.castN)rsrtrurvrrrrr r r r rs rcCs t|tS)zReturn `True` if s is an arithmetical sort (type). >>> is_arith_sort(IntSort()) True >>> is_arith_sort(RealSort()) True >>> is_arith_sort(BoolSort()) False >>> n = Int('x') + 1 >>> is_arith_sort(n.sort()) True rr2r r r r s rc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0S)1rDzInteger and Real expressions.cCstt|||jS)zReturn the sort (type) of the arithmetical expression `self`. >>> Int('x').sort() Int >>> (Real('x') + 1).sort() Real )rrrrr:rnr r r r) sz ArithRef.sortcCs |S)zReturn `True` if `self` is an integer expression. >>> x = Int('x') >>> x.is_int() True >>> (x + 1).is_int() True >>> y = Real('y') >>> (x + y).is_int() False )rrrnr r r r3 s zArithRef.is_intcCs |S)zReturn `True` if `self` is an real expression. >>> x = Real('x') >>> x.is_real() True >>> (x + 1).is_real() True )rrrnr r r rA s zArithRef.is_realcCs"t||\}}ttt|||jS)zCreate the Z3 expression `self + other`. >>> x = Int('x') >>> y = Int('y') >>> x + y x + y >>> (x + y).sort() Int r1rDrs Z3_mk_addr:r4r r r __add__L s zArithRef.__add__cCs"t||\}}ttt|||jS)zmCreate the Z3 expression `other + self`. >>> x = Int('x') >>> 10 + x 10 + x rr4r r r __radd__Y szArithRef.__radd__cCs8t|trt||dSt||\}}ttt|||jS)zCreate the Z3 expression `self * other`. >>> x = Real('x') >>> y = Real('y') >>> x * y x*y >>> (x * y).sort() Real r)r r2ror1rDrs Z3_mk_mulr:r4r r r rc s  zArithRef.__mul__cCs"t||\}}ttt|||jS)zlCreate the Z3 expression `other * self`. >>> x = Real('x') >>> 10 * x 10*x )r1rDrsrr:r4r r r rr szArithRef.__rmul__cCs"t||\}}ttt|||jS)zCreate the Z3 expression `self - other`. >>> x = Int('x') >>> y = Int('y') >>> x - y x - y >>> (x - y).sort() Int r1rDrs Z3_mk_subr:r4r r r __sub__| s zArithRef.__sub__cCs"t||\}}ttt|||jS)zmCreate the Z3 expression `other - self`. >>> x = Int('x') >>> 10 - x 10 - x rr4r r r __rsub__ szArithRef.__rsub__cCs.t||\}}tt||||jS)zCreate the Z3 expression `self**other` (** is the power operator). >>> x = Real('x') >>> x**3 x**3 >>> (x**3).sort() Real >>> simplify(IntVal(2)**8) 256 r1rD Z3_mk_powerrrr:r4r r r __pow__ s zArithRef.__pow__cCs.t||\}}tt||||jS)zCreate the Z3 expression `other**self` (** is the power operator). >>> x = Real('x') >>> 2**x 2**x >>> (2**x).sort() Real >>> simplify(2**IntVal(8)) 256 rr4r r r __rpow__ s zArithRef.__rpow__cCs.t||\}}tt||||jS)asCreate the Z3 expression `other/self`. >>> x = Int('x') >>> y = Int('y') >>> x/y x/y >>> (x/y).sort() Int >>> (x/y).sexpr() '(div x y)' >>> x = Real('x') >>> y = Real('y') >>> x/y x/y >>> (x/y).sort() Real >>> (x/y).sexpr() '(/ x y)' r1rD Z3_mk_divrrr:r4r r r __div__ szArithRef.__div__cCs ||Sz&Create the Z3 expression `other/self`.rrr r r __truediv__ szArithRef.__truediv__cCs.t||\}}tt||||jS)zCreate the Z3 expression `other/self`. >>> x = Int('x') >>> 10/x 10/x >>> (10/x).sexpr() '(div 10 x)' >>> x = Real('x') >>> 10/x 10/x >>> (10/x).sexpr() '(/ 10.0 x)' rr4r r r __rdiv__ szArithRef.__rdiv__cCs ||Srrrr r r __rtruediv__ szArithRef.__rtruediv__cCsBt||\}}tr"t|dtt||||jS)zCreate the Z3 expression `other%self`. >>> x = Int('x') >>> y = Int('y') >>> x % y x%y >>> simplify(IntVal(10) % IntVal(3)) 1 Z3 integer expression expected r1r r)rrD Z3_mk_modrrr:r4r r r __mod__ s zArithRef.__mod__cCsBt||\}}tr"t|dtt||||jS)ziCreate the Z3 expression `other%self`. >>> x = Int('x') >>> 10 % x 10%x rrr4r r r __rmod__ szArithRef.__rmod__cCstt|||jS)zReturn an expression representing `-self`. >>> x = Int('x') >>> -x -x >>> simplify(-(-x)) x )rDZ3_mk_unary_minusrrr:rnr r r __neg__ s zArithRef.__neg__cCs|S)zJReturn `self`. >>> x = Int('x') >>> +x x r rnr r r __pos__ szArithRef.__pos__cCs.t||\}}tt||||jS)zCreate the Z3 expression `other <= self`. >>> x, y = Ints('x y') >>> x <= y x <= y >>> y = Real('y') >>> x <= y ToReal(x) <= y )r1r2Z3_mk_lerrr:r4r r r __le__ s zArithRef.__le__cCs.t||\}}tt||||jS)zCreate the Z3 expression `other < self`. >>> x, y = Ints('x y') >>> x < y x < y >>> y = Real('y') >>> x < y ToReal(x) < y )r1r2Z3_mk_ltrrr:r4r r r __lt__ s zArithRef.__lt__cCs.t||\}}tt||||jS)zCreate the Z3 expression `other > self`. >>> x, y = Ints('x y') >>> x > y x > y >>> y = Real('y') >>> x > y ToReal(x) > y )r1r2Z3_mk_gtrrr:r4r r r __gt__( s zArithRef.__gt__cCs.t||\}}tt||||jS)zCreate the Z3 expression `other >= self`. >>> x, y = Ints('x y') >>> x >= y x >= y >>> y = Real('y') >>> x >= y ToReal(x) >= y )r1r2Z3_mk_gerrr:r4r r r __ge__5 s zArithRef.__ge__N)rsrtrurvrrrrrrrrrrrrrrrrrr r r rrrr r r r rD& s0             rDcCs t|tS)a#Return `True` if `a` is an arithmetical expression. >>> x = Int('x') >>> is_arith(x) True >>> is_arith(x + 1) True >>> is_arith(1) False >>> is_arith(IntVal(1)) True >>> y = Real('y') >>> is_arith(y) True >>> is_arith(y + 1) True )r rDrr r r is_arithC srcCst|o|S)zReturn `True` if `a` is an integer expression. >>> x = Int('x') >>> is_int(x + 1) True >>> is_int(1) False >>> is_int(IntVal(1)) True >>> y = Real('y') >>> is_int(y) False >>> is_int(y + 1) False )rrrr r r rX srcCst|o|S)zReturn `True` if `a` is a real expression. >>> x = Int('x') >>> is_real(x + 1) False >>> y = Real('y') >>> is_real(y) True >>> is_real(y + 1) True >>> is_real(1) False >>> is_real(RealVal(1)) True )rrrr r r rk srcCst||Sr)Z3_is_numeral_astr7rr r r rM~ srMcCst||Sr)Z3_is_algebraic_numberr7rr r r rF srFcCs t|o|ot|j|S)auReturn `True` if `a` is an integer value of sort Int. >>> is_int_value(IntVal(1)) True >>> is_int_value(1) False >>> is_int_value(Int('x')) False >>> n = Int('x') + 1 >>> n x + 1 >>> n.arg(1) 1 >>> is_int_value(n.arg(1)) True >>> is_int_value(RealVal("1/3")) False >>> is_int_value(RealVal(1)) False )rrrMr:rrr r r is_int_value srcCs t|o|ot|j|S)aReturn `True` if `a` is rational value of sort Real. >>> is_rational_value(RealVal(1)) True >>> is_rational_value(RealVal("3/5")) True >>> is_rational_value(IntVal(1)) False >>> is_rational_value(1) False >>> n = Real('x') + 1 >>> n.arg(1) 1 >>> is_rational_value(n.arg(1)) True >>> is_rational_value(Real('x')) False )rrrMr:rrr r r is_rational_value srcCs t|o|ot|j|S)zReturn `True` if `a` is an algebraic value of sort Real. >>> is_algebraic_value(RealVal("3/5")) False >>> n = simplify(Sqrt(2)) >>> n 1.4142135623? >>> is_algebraic_value(n) True )rrrFr:rrr r r is_algebraic_value s rcCs t|tS)zReturn `True` if `a` is an expression of the form b + c. >>> x, y = Ints('x y') >>> is_add(x + y) True >>> is_add(x - y) False )riZ Z3_OP_ADDrr r r is_add s rcCs t|tS)zReturn `True` if `a` is an expression of the form b * c. >>> x, y = Ints('x y') >>> is_mul(x * y) True >>> is_mul(x - y) False )riZ Z3_OP_MULrr r r is_mul s rcCs t|tS)zReturn `True` if `a` is an expression of the form b - c. >>> x, y = Ints('x y') >>> is_sub(x - y) True >>> is_sub(x + y) False )riZ Z3_OP_SUBrr r r is_sub s rcCs t|tS)zReturn `True` if `a` is an expression of the form b / c. >>> x, y = Reals('x y') >>> is_div(x / y) True >>> is_div(x + y) False >>> x, y = Ints('x y') >>> is_div(x / y) False >>> is_idiv(x / y) True )riZ Z3_OP_DIVrr r r is_div srcCs t|tS)zReturn `True` if `a` is an expression of the form b div c. >>> x, y = Ints('x y') >>> is_idiv(x / y) True >>> is_idiv(x + y) False )riZ Z3_OP_IDIVrr r r is_idiv s rcCs t|tS)zReturn `True` if `a` is an expression of the form b % c. >>> x, y = Ints('x y') >>> is_mod(x % y) True >>> is_mod(x + y) False )riZ Z3_OP_MODrr r r is_mod s rcCs t|tS)zReturn `True` if `a` is an expression of the form b <= c. >>> x, y = Ints('x y') >>> is_le(x <= y) True >>> is_le(x < y) False )riZZ3_OP_LErr r r is_le s rcCs t|tS)zReturn `True` if `a` is an expression of the form b < c. >>> x, y = Ints('x y') >>> is_lt(x < y) True >>> is_lt(x == y) False )riZZ3_OP_LTrr r r is_lt s r cCs t|tS)zReturn `True` if `a` is an expression of the form b >= c. >>> x, y = Ints('x y') >>> is_ge(x >= y) True >>> is_ge(x == y) False )riZZ3_OP_GErr r r is_ge' s r!cCs t|tS)zReturn `True` if `a` is an expression of the form b > c. >>> x, y = Ints('x y') >>> is_gt(x > y) True >>> is_gt(x == y) False )riZZ3_OP_GTrr r r is_gt3 s r"cCs t|tS)zReturn `True` if `a` is an expression of the form IsInt(b). >>> x = Real('x') >>> is_is_int(IsInt(x)) True >>> is_is_int(x) False )riZ Z3_OP_IS_INTrr r r is_is_int? s r#cCs t|tS)zReturn `True` if `a` is an expression of the form ToReal(b). >>> x = Int('x') >>> n = ToReal(x) >>> n ToReal(x) >>> is_to_real(n) True >>> is_to_real(x) False )riZ Z3_OP_TO_REALrr r r is_to_realK s r$cCs t|tS)zReturn `True` if `a` is an expression of the form ToInt(b). >>> x = Real('x') >>> n = ToInt(x) >>> n ToInt(x) >>> is_to_int(n) True >>> is_to_int(x) False )riZ Z3_OP_TO_INTrr r r is_to_intZ s r%c@s(eZdZdZddZddZddZdS) rCInteger values.cCs trt|dt|S)zReturn a Z3 integer numeral as a Python long (bignum) numeral. >>> v = IntVal(1) >>> v + 1 1 + 1 >>> v.as_long() + 1 2 zInteger value expected)r r)rr as_stringrnr r r as_longl s zIntNumRef.as_longcCst||S)z|Return a Z3 integer numeral as a Python string. >>> v = IntVal(100) >>> v.as_string() '100' Z3_get_numeral_stringrrrnr r r r'y szIntNumRef.as_stringcCst||S)zReturn a Z3 integer numeral as a Python binary string. >>> v = IntVal(10) >>> v.as_binary_string() '1010' Z3_get_numeral_binary_stringrrrnr r r as_binary_string szIntNumRef.as_binary_stringN)rsrtrurvr(r'r-r r r r rCi s rCc@sheZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZdS)rEzRational values.cCstt|||jS)a Return the numerator of a Z3 rational numeral. >>> is_rational_value(RealVal("3/5")) True >>> n = RealVal("3/5") >>> n.numerator() 3 >>> is_rational_value(Q(3,5)) True >>> Q(3,5).numerator() 3 )rCZ3_get_numeratorrrr:rnr r r numerator s zRatNumRef.numeratorcCstt|||jS)z Return the denominator of a Z3 rational numeral. >>> is_rational_value(Q(3,5)) True >>> n = Q(3,5) >>> n.denominator() 5 )rCZ3_get_denominatorrrr:rnr r r denominator s zRatNumRef.denominatorcCs |S)z Return the numerator as a Python long. >>> v = RealVal(10000000000) >>> v 10000000000 >>> v + 1 10000000000 + 1 >>> v.numerator_as_long() + 1 == 10000000001 True )r/r(rnr r r numerator_as_long s zRatNumRef.numerator_as_longcCs |S)z Return the denominator as a Python long. >>> v = RealVal("1/3") >>> v 1/3 >>> v.denominator_as_long() 3 )r1r(rnr r r denominator_as_long s zRatNumRef.denominator_as_longcCsdSNFr rnr r r r szRatNumRef.is_intcCsdSrr rnr r r r szRatNumRef.is_realcCs|o|dkS)Nr)r1rr3rnr r r r szRatNumRef.is_int_valuecCst|d|S)NzExpected integer fraction)r)rr2rnr r r r( szRatNumRef.as_longcCst|||S)z Return a Z3 rational value as a string in decimal notation using at most `prec` decimal places. >>> v = RealVal("1/5") >>> v.as_decimal(3) '0.2' >>> v = RealVal("1/3") >>> v.as_decimal(3) '0.333?' Z3_get_numeral_decimal_stringrrrfprecr r r as_decimal s zRatNumRef.as_decimalcCst||S)zyReturn a Z3 rational numeral as a Python string. >>> v = Q(3,6) >>> v.as_string() '1/2' r)rnr r r r' szRatNumRef.as_stringcCst||S)zReturn a Z3 rational as a Python Fraction object. >>> v = RealVal("1/5") >>> v.as_fraction() Fraction(1, 5) )rr2r3rnr r r as_fraction szRatNumRef.as_fractionN)rsrtrurvr/r1r2r3rrrr(r9r'r:r r r r rE s     rEc@s2eZdZdZd ddZddZddZd d Zd S) rGzAlgebraic irrational values. cCstt||||jS)a<Return a Z3 rational number that approximates the algebraic number `self`. The result `r` is such that |r - self| <= 1/10^precision >>> x = simplify(Sqrt(2)) >>> x.approx(20) 6838717160008073720548335/4835703278458516698824704 >>> x.approx(5) 2965821/2097152 )rEZ3_get_algebraic_number_upperrrr:)rf precisionr r r approx s zAlgebraicNumRef.approxcCst|||S)aReturn a string representation of the algebraic number `self` in decimal notation using `prec` decimal places. >>> x = simplify(Sqrt(2)) >>> x.as_decimal(10) '1.4142135623?' >>> x.as_decimal(20) '1.41421356237309504880?' r5r7r r r r9 s zAlgebraicNumRef.as_decimalcCstt|||jSr)rIZ3_algebraic_get_polyrrr:rnr r r poly szAlgebraicNumRef.polycCst||Sr)Z3_algebraic_get_irrrnr r r index szAlgebraicNumRef.indexN)r;)rsrtrurvr>r9r@rBr r r r rG s   rGcCsnt|trt||St|r&t||St|tr:t||St|trNt||St |rZ|St rjt dddS)NFz(Python bool, int, long or float expected) r rRrrrfloatrrSr[rr r)r)r r r rZ s       rZcCst|}tt||S)a Return the integer sort in the given context. If `ctx=None`, then the global context is used. >>> IntSort() Int >>> x = Const('x', IntSort()) >>> is_int(x) True >>> x.sort() == IntSort() True >>> x.sort() == BoolSort() False )r6rZ3_mk_int_sortr7rpr r r IntSort s rEcCst|}tt||S)zReturn the real sort in the given context. If `ctx=None`, then the global context is used. >>> RealSort() Real >>> x = Const('x', RealSort()) >>> is_real(x) True >>> is_int(x) False >>> x.sort() == RealSort() True )r6rZ3_mk_real_sortr7rpr r r r- s rcCs`t|trtt|St|tr.|r(dSdSnt|r>t|St|trL|Str\tdddS)N10Fz+Python value cannot be used as a Z3 integer)r rCrSrrRrr r)rTr r r _to_int_str> s    rIcCs(t|}tt|t|t|j|S)zReturn a Z3 integer value. If `ctx=None`, then the global context is used. >>> IntVal(1) 1 >>> IntVal("100") 100 )r6rC Z3_mk_numeralr7rIrErrr r r rN srcCs(t|}tt|t|t|j|S)a8Return a Z3 real value. `val` may be a Python int, long, float or string representing a number in decimal or rational notation. If `ctx=None`, then the global context is used. >>> RealVal(1) 1 >>> RealVal(1).sort() Real >>> RealVal("3/5") 3/5 >>> RealVal("1.5") 3/2 )r6rErJr7rSrrrr r r rZ srcCsNtr6tt|pt|tdtt|p0t|tdtt||t||S)zReturn a Z3 rational a/b. If `ctx=None`, then the global context is used. >>> RatVal(3,5) 3/5 >>> RatVal(3,5).sort() Real z2First argument cannot be converted into an integerz3Second argument cannot be converted into an integer)r r)rr rSsimplifyrrkrr:r r r RatValm s rMcCstt||S)zReturn a Z3 rational a/b. If `ctx=None`, then the global context is used. >>> Q(3,5) 3/5 >>> Q(3,5).sort() Real )rKrMrLr r r Q} s rNcCs*t|}tt|t||t|j|S)zReturn an integer constant named `name`. If `ctx=None`, then the global context is used. >>> x = Int('x') >>> is_int(x) True >>> is_int(x + 1) True )r6rDrtr7r;rErrr r r Int s rOcs.tt|tr|d}fdd|DS)zmReturn a tuple of Integer constants. >>> x, y, z = Ints('x y z') >>> Sum(x, y, z) x + y + z rvcsg|]}t|qSr rOrwrpr r rD szInts..rrr rpr Ints s  rQcs tfddt|DS)zReturn a list of integer constants of size `sz`. >>> X = IntVector('x', 3) >>> X [x__0, x__1, x__2] >>> Sum(X) x__0 + x__1 + x__2 csg|]}td|fqSrrPr r:r}r r rD szIntVector..r6rrr rRr IntVector s rTxcCs$t|}tt||t|j|S)zReturn a fresh integer constant in the given context using the given prefix. >>> x = FreshInt() >>> y = FreshInt() >>> eq(x, y) False >>> x.sort() Int )r6rDr|r7rErrr r r FreshInt s rVcCs*t|}tt|t||t|j|S)zReturn a real constant named `name`. If `ctx=None`, then the global context is used. >>> x = Real('x') >>> is_real(x) True >>> is_real(x + 1) True )r6rDrtr7r;rrrr r r Real s rWcs.tt|tr|d}fdd|DS)zReturn a tuple of real constants. >>> x, y, z = Reals('x y z') >>> Sum(x, y, z) x + y + z >>> Sum(x, y, z).sort() Real rvcsg|]}t|qSr rWrwrpr r rD szReals..rrr rpr Reals s   rYcs tfddt|DS)zReturn a list of real constants of size `sz`. >>> X = RealVector('x', 3) >>> X [x__0, x__1, x__2] >>> Sum(X) x__0 + x__1 + x__2 >>> Sum(X).sort() Real csg|]}td|fqSrrXr rRr r rD szRealVector..rSrr rRr RealVector s rZcCs$t|}tt||t|j|S)zReturn a fresh real constant in the given context using the given prefix. >>> x = FreshReal() >>> y = FreshReal() >>> eq(x, y) False >>> x.sort() Real )r6rDr|r7rrrr r r FreshReal s r[cCs2trt|d|j}tt|||S)z Return the Z3 expression ToReal(a). >>> x = Int('x') >>> x.sort() Int >>> n = ToReal(x) >>> n ToReal(x) >>> n.sort() Real zZ3 integer expression expected.)r r)rr:rDZ3_mk_int2realr7rr)r r r r s rcCs2trt|d|j}tt|||S)z Return the Z3 expression ToInt(a). >>> x = Real('x') >>> x.sort() Real >>> n = ToInt(x) >>> n ToInt(x) >>> n.sort() Int Z3 real expression expected.)r r)rr:rDZ3_mk_real2intr7rr)r r r ToInt s r_cCs2trt|d|j}tt|||S)z Return the Z3 predicate IsInt(a). >>> x = Real('x') >>> IsInt(x + "1/2") IsInt(x + 1/2) >>> solve(IsInt(x + "1/2"), x > 0, x < 1) [x = 1/2] >>> solve(IsInt(x + "1/2"), x > 0, x < 1, x != "1/2") no solution r])r r)rr:r2 Z3_mk_is_intr7rr)r r r IsInt s racCs"t|st|}t||}|dS)zw Return a Z3 expression which represents the square root of a. >>> x = Real('x') >>> Sqrt(x) x**(1/2) z1/2rr6rr)r r r Sqrt- s rccCs"t|st|}t||}|dS)zv Return a Z3 expression which represents the cubic root of a. >>> x = Real('x') >>> Cbrt(x) x**(1/3) z1/3rbr)r r r Cbrt: s rdc@s(eZdZdZddZddZddZdS) rzBit-vector sort.cCstt||jS)zReturn the size (number of bits) of the bit-vector sort `self`. >>> b = BitVecSort(32) >>> b.size() 32 )rZ3_get_bv_sort_sizerrrnr r r sizeP szBitVecSortRef.sizecCst|o||kSr) is_bv_sortrfrr r r rY szBitVecSortRef.subsortcCs2t|r$tr t|j|jkd|St||SdS)zTry to cast `val` as a Bit-Vector. >>> b = BitVecSort(32) >>> b.cast(10) 10 >>> b.cast(10).sexpr() '#x0000000a' rN)rr r)r: BitVecValrr r r r\ s zBitVecSortRef.castN)rsrtrurvrfrrr r r r rM s rcCs t|tS)zReturn True if `s` is a Z3 bit-vector sort. >>> is_bv_sort(BitVecSort(32)) True >>> is_bv_sort(IntSort()) False )r rr2r r r rgn srgc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Z dd?Z"d@S)ArIzBit-vector expressions.cCstt|||jS)zReturn the sort of the bit-vector expression `self`. >>> x = BitVec('x', 32) >>> x.sort() BitVec(32) >>> x.sort() == BitVecSort(32) True )rrrrr:rnr r r r| s zBitVecRef.sortcCs |S)zReturn the number of bits of the bit-vector expression `self`. >>> x = BitVec('x', 32) >>> (x + 1).size() 32 >>> Concat(x, x).size() 64 )rrfrnr r r rf s zBitVecRef.sizecCs.t||\}}tt||||jS)zCreate the Z3 expression `self + other`. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x + y x + y >>> (x + y).sort() BitVec(32) r1rI Z3_mk_bvaddrrr:r4r r r r s zBitVecRef.__add__cCs.t||\}}tt||||jS)ztCreate the Z3 expression `other + self`. >>> x = BitVec('x', 32) >>> 10 + x 10 + x rir4r r r r szBitVecRef.__radd__cCs.t||\}}tt||||jS)zCreate the Z3 expression `self * other`. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x * y x*y >>> (x * y).sort() BitVec(32) r1rI Z3_mk_bvmulrrr:r4r r r r s zBitVecRef.__mul__cCs.t||\}}tt||||jS)zrCreate the Z3 expression `other * self`. >>> x = BitVec('x', 32) >>> 10 * x 10*x rkr4r r r r szBitVecRef.__rmul__cCs.t||\}}tt||||jS)zCreate the Z3 expression `self - other`. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x - y x - y >>> (x - y).sort() BitVec(32) r1rI Z3_mk_bvsubrrr:r4r r r r s zBitVecRef.__sub__cCs.t||\}}tt||||jS)ztCreate the Z3 expression `other - self`. >>> x = BitVec('x', 32) >>> 10 - x 10 - x rmr4r r r r szBitVecRef.__rsub__cCs.t||\}}tt||||jS)zCreate the Z3 expression bitwise-or `self | other`. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x | y x | y >>> (x | y).sort() BitVec(32) r1rI Z3_mk_bvorrrr:r4r r r __or__ s zBitVecRef.__or__cCs.t||\}}tt||||jS)zCreate the Z3 expression bitwise-or `other | self`. >>> x = BitVec('x', 32) >>> 10 | x 10 | x ror4r r r __ror__ szBitVecRef.__ror__cCs.t||\}}tt||||jS)zCreate the Z3 expression bitwise-and `self & other`. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x & y x & y >>> (x & y).sort() BitVec(32) r1rI Z3_mk_bvandrrr:r4r r r __and__ s zBitVecRef.__and__cCs.t||\}}tt||||jS)zCreate the Z3 expression bitwise-or `other & self`. >>> x = BitVec('x', 32) >>> 10 & x 10 & x rsr4r r r __rand__ szBitVecRef.__rand__cCs.t||\}}tt||||jS)zCreate the Z3 expression bitwise-xor `self ^ other`. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x ^ y x ^ y >>> (x ^ y).sort() BitVec(32) r1rI Z3_mk_bvxorrrr:r4r r r __xor__s zBitVecRef.__xor__cCs.t||\}}tt||||jS)zCreate the Z3 expression bitwise-xor `other ^ self`. >>> x = BitVec('x', 32) >>> 10 ^ x 10 ^ x rwr4r r r __rxor__szBitVecRef.__rxor__cCs|S)zQReturn `self`. >>> x = BitVec('x', 32) >>> +x x r rnr r r r szBitVecRef.__pos__cCstt|||jS)zReturn an expression representing `-self`. >>> x = BitVec('x', 32) >>> -x -x >>> simplify(-(-x)) x )rI Z3_mk_bvnegrrr:rnr r r r %s zBitVecRef.__neg__cCstt|||jS)zCreate the Z3 expression bitwise-not `~self`. >>> x = BitVec('x', 32) >>> ~x ~x >>> simplify(~(~x)) x )rI Z3_mk_bvnotrrr:rnr r r __invert__0s zBitVecRef.__invert__cCs.t||\}}tt||||jS)aqCreate the Z3 expression (signed) division `self / other`. Use the function UDiv() for unsigned division. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x / y x/y >>> (x / y).sort() BitVec(32) >>> (x / y).sexpr() '(bvsdiv x y)' >>> UDiv(x, y).sexpr() '(bvudiv x y)' r1rI Z3_mk_bvsdivrrr:r4r r r r;szBitVecRef.__div__cCs ||S)z:Create the Z3 expression (signed) division `self / other`.rrr r r rNszBitVecRef.__truediv__cCs.t||\}}tt||||jS)a9Create the Z3 expression (signed) division `other / self`. Use the function UDiv() for unsigned division. >>> x = BitVec('x', 32) >>> 10 / x 10/x >>> (10 / x).sexpr() '(bvsdiv #x0000000a x)' >>> UDiv(10, x).sexpr() '(bvudiv #x0000000a x)' r~r4r r r rRs zBitVecRef.__rdiv__cCs ||S)z:Create the Z3 expression (signed) division `other / self`.rrr r r rbszBitVecRef.__rtruediv__cCs.t||\}}tt||||jS)aCreate the Z3 expression (signed) mod `self % other`. Use the function URem() for unsigned remainder, and SRem() for signed remainder. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> x % y x%y >>> (x % y).sort() BitVec(32) >>> (x % y).sexpr() '(bvsmod x y)' >>> URem(x, y).sexpr() '(bvurem x y)' >>> SRem(x, y).sexpr() '(bvsrem x y)' r1rI Z3_mk_bvsmodrrr:r4r r r rfszBitVecRef.__mod__cCs.t||\}}tt||||jS)aCreate the Z3 expression (signed) mod `other % self`. Use the function URem() for unsigned remainder, and SRem() for signed remainder. >>> x = BitVec('x', 32) >>> 10 % x 10%x >>> (10 % x).sexpr() '(bvsmod #x0000000a x)' >>> URem(10, x).sexpr() '(bvurem #x0000000a x)' >>> SRem(10, x).sexpr() '(bvsrem #x0000000a x)' rr4r r r r{szBitVecRef.__rmod__cCs.t||\}}tt||||jS)a/Create the Z3 expression (signed) `other <= self`. Use the function ULE() for unsigned less than or equal to. >>> x, y = BitVecs('x y', 32) >>> x <= y x <= y >>> (x <= y).sexpr() '(bvsle x y)' >>> ULE(x, y).sexpr() '(bvule x y)' )r1r2 Z3_mk_bvslerrr:r4r r r r s zBitVecRef.__le__cCs.t||\}}tt||||jS)aCreate the Z3 expression (signed) `other < self`. Use the function ULT() for unsigned less than. >>> x, y = BitVecs('x y', 32) >>> x < y x < y >>> (x < y).sexpr() '(bvslt x y)' >>> ULT(x, y).sexpr() '(bvult x y)' )r1r2 Z3_mk_bvsltrrr:r4r r r rs zBitVecRef.__lt__cCs.t||\}}tt||||jS)a"Create the Z3 expression (signed) `other > self`. Use the function UGT() for unsigned greater than. >>> x, y = BitVecs('x y', 32) >>> x > y x > y >>> (x > y).sexpr() '(bvsgt x y)' >>> UGT(x, y).sexpr() '(bvugt x y)' )r1r2 Z3_mk_bvsgtrrr:r4r r r rs zBitVecRef.__gt__cCs.t||\}}tt||||jS)a2Create the Z3 expression (signed) `other >= self`. Use the function UGE() for unsigned greater than or equal to. >>> x, y = BitVecs('x y', 32) >>> x >= y x >= y >>> (x >= y).sexpr() '(bvsge x y)' >>> UGE(x, y).sexpr() '(bvuge x y)' )r1r2 Z3_mk_bvsgerrr:r4r r r rs zBitVecRef.__ge__cCs.t||\}}tt||||jS)aCreate the Z3 expression (arithmetical) right shift `self >> other` Use the function LShR() for the right logical shift >>> x, y = BitVecs('x y', 32) >>> x >> y x >> y >>> (x >> y).sexpr() '(bvashr x y)' >>> LShR(x, y).sexpr() '(bvlshr x y)' >>> BitVecVal(4, 3) 4 >>> BitVecVal(4, 3).as_signed_long() -4 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long() -2 >>> simplify(BitVecVal(4, 3) >> 1) 6 >>> simplify(LShR(BitVecVal(4, 3), 1)) 2 >>> simplify(BitVecVal(2, 3) >> 1) 1 >>> simplify(LShR(BitVecVal(2, 3), 1)) 1 r1rI Z3_mk_bvashrrrr:r4r r r __rshift__szBitVecRef.__rshift__cCs.t||\}}tt||||jS)zCreate the Z3 expression left shift `self << other` >>> x, y = BitVecs('x y', 32) >>> x << y x << y >>> (x << y).sexpr() '(bvshl x y)' >>> simplify(BitVecVal(2, 3) << 1) 4 r1rI Z3_mk_bvshlrrr:r4r r r __lshift__s zBitVecRef.__lshift__cCs.t||\}}tt||||jS)aCreate the Z3 expression (arithmetical) right shift `other` >> `self`. Use the function LShR() for the right logical shift >>> x = BitVec('x', 32) >>> 10 >> x 10 >> x >>> (10 >> x).sexpr() '(bvashr #x0000000a x)' rr4r r r __rrshift__s zBitVecRef.__rrshift__cCs.t||\}}tt||||jS)zCreate the Z3 expression left shift `other << self`. Use the function LShR() for the right logical shift >>> x = BitVec('x', 32) >>> 10 << x 10 << x >>> (10 << x).sexpr() '(bvshl #x0000000a x)' rr4r r r __rlshift__s zBitVecRef.__rlshift__N)#rsrtrurvrrfrrrrrrrqrrrurvryrzr r r}rrrrrrr rrrrrrrr r r r rIy s@                 rIc@s0eZdZdZddZddZddZdd Zd S) rHzBit-vector values.cCs t|S)zReturn a Z3 bit-vector numeral as a Python long (bignum) numeral. >>> v = BitVecVal(0xbadc0de, 32) >>> v 195936478 >>> print("0x%.8x" % v.as_long()) 0x0badc0de rr'rnr r r r(s zBitVecNumRef.as_longcCsR|}|}|d|dkr,|d|}|d|d krJ|d|}t|S)aReturn a Z3 bit-vector numeral as a Python long (bignum) numeral. The most significant bit is assumed to be the sign. >>> BitVecVal(4, 3).as_signed_long() -4 >>> BitVecVal(7, 3).as_signed_long() -1 >>> BitVecVal(3, 3).as_signed_long() 3 >>> BitVecVal(2**32 - 1, 32).as_signed_long() -1 >>> BitVecVal(2**64 - 1, 64).as_signed_long() -1 r[r)rfr(r)rfrrUr r r as_signed_long$s  zBitVecNumRef.as_signed_longcCst||Srr)rnr r r r';szBitVecNumRef.as_stringcCst||Srr+rnr r r r->szBitVecNumRef.as_binary_stringN)rsrtrurvr(rr'r-r r r r rHs  rHcCs t|tS)zReturn `True` if `a` is a Z3 bit-vector expression. >>> b = BitVec('b', 32) >>> is_bv(b) True >>> is_bv(b + 10) True >>> is_bv(Int('x')) False )r rIrr r r is_bvBs rcCst|ot|j|S)zReturn `True` if `a` is a Z3 bit-vector numeral value. >>> b = BitVec('b', 32) >>> is_bv_value(b) False >>> b = BitVecVal(10, 32) >>> b 10 >>> is_bv_value(b) True )rrMr:rrr r r is_bv_valuePs rFcCs4trtt|d|j}tt||||S)alReturn the Z3 expression BV2Int(a). >>> b = BitVec('b', 3) >>> BV2Int(b).sort() Int >>> x = Int('x') >>> x > BV2Int(b) x > BV2Int(b) >>> x > BV2Int(b, is_signed=False) x > BV2Int(b) >>> x > BV2Int(b, is_signed=True) x > If(b < 0, BV2Int(b) - 8, BV2Int(b)) >>> solve(x > BV2Int(b), b == 1, x < 3) [x = 2, b = 1] 1First argument must be a Z3 bit-vector expression)r r)rr:rD Z3_mk_bv2intr7r)rkZ is_signedr:r r r BV2Int_srcCs |j}tt||||S)zReturn the z3 expression Int2BV(a, num_bits). It is a bit-vector of width num_bits and represents the modulo of a by 2^num_bits )r:rI Z3_mk_int2bvr7r)rkZnum_bitsr:r r r Int2BVvsrcCst|}tt|||S)zReturn a Z3 bit-vector sort of the given size. If `ctx=None`, then the global context is used. >>> Byte = BitVecSort(8) >>> Word = BitVecSort(16) >>> Byte BitVec(8) >>> x = Const('x', Byte) >>> eq(x, BitVec('x', 8)) True )r6r Z3_mk_bv_sortr7)rr:r r r BitVecSorts rcCsXt|r*|j}tt|t||j|St|}tt|t|t||j|SdS)zReturn a bit-vector value with the given number of bits. If `ctx=None`, then the global context is used. >>> v = BitVecVal(10, 32) >>> v 10 >>> print("0x%.8x" % v.as_long()) 0x0000000a N) rgr:rHrJr7rIrr6r)rUbvr:r r r rhs rhcCsBt|tr|j}nt|}t||}tt|t|||j |S)a`Return a bit-vector constant named `name`. `bv` may be the number of bits of a bit-vector sort. If `ctx=None`, then the global context is used. >>> x = BitVec('x', 16) >>> is_bv(x) True >>> x.size() 16 >>> x.sort() BitVec(16) >>> word = BitVecSort(16) >>> x2 = BitVec('x', word) >>> eq(x, x2) True ) r rr:r6rrIrtr7r;r)r,rr:r r r BitVecs   rcs0tt|tr|d}fdd|DS)aReturn a tuple of bit-vector constants of size bv. >>> x, y, z = BitVecs('x y z', 16) >>> x.size() 16 >>> x.sort() BitVec(16) >>> Sum(x, y, z) 0 + x + y + z >>> Product(x, y, z) 1*x*y*z >>> simplify(Product(x, y, z)) x*y*z rvcsg|]}t|qSr )rrwrr:r r rDszBitVecs..r)rzrr:r rr BitVecss  rcst|}t|}tr$t|dkdd|D]}t|r,|jqDq,t|ds^t|dtṙfdd|D}trtt dd|Ddt |}t |D]}|| ||<qt t||St|dr8trtt d d|Dd t |}t |D]}|| ||<q tt||StrXtt d d|Dd |d}t |d D],}tt| ||d  }ql|S)zCreate a Z3 bit-vector concatenation expression. >>> v = BitVecVal(1, 4) >>> Concat(v, v+1, v) Concat(Concat(1, 1 + 1), 1) >>> simplify(Concat(v, v+1, v)) 289 >>> print("%.3x" % simplify(Concat(v, v+1, v)).as_long()) 121 r[z At least two arguments expected.Nrcsg|]}t|qSr ) _coerce_seqrBr3rpr r rDszConcat..cSsg|] }t|qSr )is_seqrar r r rDsz+All arguments must be sequence expressions.cSsg|] }t|qSr is_rerar r r rDs*All arguments must be regular expressions.cSsg|] }t|qSr )rrar r r rDsz0All arguments must be Z3 bit-vector expressions.r)rMrEr r)rr:rr rSrrrrrSZ3_mk_seq_concatr7rrTZ3_mk_re_concatrI Z3_mk_concat)rLrrkrrrr rpr Concats<     *rcCst|trt|}t|rV|}t|||j\}}tt|| | | |jSt rt ||kdt t |o|dkot |o|dkdt t |dtt|||| |jS)a Create a Z3 bit-vector extraction expression. Extract is overloaded to also work on sequence extraction. The functions SubString and SubSeq are redirected to Extract. For this case, the arguments are reinterpreted as: high - is a sequence (string) low - is an offset a - is the length to be extracted >>> x = BitVec('x', 8) >>> Extract(6, 2, x) Extract(6, 2, x) >>> Extract(6, 2, x).sort() BitVec(5) >>> simplify(Extract(StringVal("abcd"),2,1)) "c" z?First argument must be greater than or equal to second argumentrz8First and second arguments must be non negative integersz1Third argument must be a Z3 bit-vector expression)r rSr[rr1r:rSZ3_mk_seq_extractrrr r)rrrI Z3_mk_extract)ZhighZlowrkr3offsetlengthr r r Extracts & rcCs trtt|pt|ddS)Nz;First or second argument must be a Z3 bit-vector expression)r r)rrr r r _check_bv_argssrcCs8t||t||\}}tt||||jS)aCreate the Z3 expression (unsigned) `other <= self`. Use the operator <= for signed less than or equal to. >>> x, y = BitVecs('x y', 32) >>> ULE(x, y) ULE(x, y) >>> (x <= y).sexpr() '(bvsle x y)' >>> ULE(x, y).sexpr() '(bvule x y)' )rr1r2 Z3_mk_bvulerrr:rr r r ULEs rcCs8t||t||\}}tt||||jS)zCreate the Z3 expression (unsigned) `other < self`. Use the operator < for signed less than. >>> x, y = BitVecs('x y', 32) >>> ULT(x, y) ULT(x, y) >>> (x < y).sexpr() '(bvslt x y)' >>> ULT(x, y).sexpr() '(bvult x y)' )rr1r2 Z3_mk_bvultrrr:rr r r ULT0s rcCs8t||t||\}}tt||||jS)aCreate the Z3 expression (unsigned) `other >= self`. Use the operator >= for signed greater than or equal to. >>> x, y = BitVecs('x y', 32) >>> UGE(x, y) UGE(x, y) >>> (x >= y).sexpr() '(bvsge x y)' >>> UGE(x, y).sexpr() '(bvuge x y)' )rr1r2 Z3_mk_bvugerrr:rr r r UGEBs rcCs8t||t||\}}tt||||jS)aCreate the Z3 expression (unsigned) `other > self`. Use the operator > for signed greater than. >>> x, y = BitVecs('x y', 32) >>> UGT(x, y) UGT(x, y) >>> (x > y).sexpr() '(bvsgt x y)' >>> UGT(x, y).sexpr() '(bvugt x y)' )rr1r2 Z3_mk_bvugtrrr:rr r r UGTTs rcCs8t||t||\}}tt||||jS)aKCreate the Z3 expression (unsigned) division `self / other`. Use the operator / for signed division. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> UDiv(x, y) UDiv(x, y) >>> UDiv(x, y).sort() BitVec(32) >>> (x / y).sexpr() '(bvsdiv x y)' >>> UDiv(x, y).sexpr() '(bvudiv x y)' )rr1rI Z3_mk_bvudivrrr:rr r r UDivfs rcCs8t||t||\}}tt||||jS)alCreate the Z3 expression (unsigned) remainder `self % other`. Use the operator % for signed modulus, and SRem() for signed remainder. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> URem(x, y) URem(x, y) >>> URem(x, y).sort() BitVec(32) >>> (x % y).sexpr() '(bvsmod x y)' >>> URem(x, y).sexpr() '(bvurem x y)' )rr1rI Z3_mk_bvuremrrr:rr r r URem{s rcCs8t||t||\}}tt||||jS)a[Create the Z3 expression signed remainder. Use the operator % for signed modulus, and URem() for unsigned remainder. >>> x = BitVec('x', 32) >>> y = BitVec('y', 32) >>> SRem(x, y) SRem(x, y) >>> SRem(x, y).sort() BitVec(32) >>> (x % y).sexpr() '(bvsmod x y)' >>> SRem(x, y).sexpr() '(bvsrem x y)' )rr1rI Z3_mk_bvsremrrr:rr r r SRems rcCs8t||t||\}}tt||||jS)aUCreate the Z3 expression logical right shift. Use the operator >> for the arithmetical right shift. >>> x, y = BitVecs('x y', 32) >>> LShR(x, y) LShR(x, y) >>> (x >> y).sexpr() '(bvashr x y)' >>> LShR(x, y).sexpr() '(bvlshr x y)' >>> BitVecVal(4, 3) 4 >>> BitVecVal(4, 3).as_signed_long() -4 >>> simplify(BitVecVal(4, 3) >> 1).as_signed_long() -2 >>> simplify(BitVecVal(4, 3) >> 1) 6 >>> simplify(LShR(BitVecVal(4, 3), 1)) 2 >>> simplify(BitVecVal(2, 3) >> 1) 1 >>> simplify(LShR(BitVecVal(2, 3), 1)) 1 )rr1rI Z3_mk_bvlshrrrr:rr r r LShRs rcCs8t||t||\}}tt||||jS)zReturn an expression representing `a` rotated to the left `b` times. >>> a, b = BitVecs('a b', 16) >>> RotateLeft(a, b) RotateLeft(a, b) >>> simplify(RotateLeft(a, 0)) a >>> simplify(RotateLeft(a, 16)) a )rr1rIZ3_mk_ext_rotate_leftrrr:rr r r RotateLefts rcCs8t||t||\}}tt||||jS)zReturn an expression representing `a` rotated to the right `b` times. >>> a, b = BitVecs('a b', 16) >>> RotateRight(a, b) RotateRight(a, b) >>> simplify(RotateRight(a, 0)) a >>> simplify(RotateRight(a, 16)) a )rr1rIZ3_mk_ext_rotate_rightrrr:rr r r RotateRights rcCs>tr"tt|dtt|dtt||||jS)aReturn a bit-vector expression with `n` extra sign-bits. >>> x = BitVec('x', 16) >>> n = SignExt(8, x) >>> n.size() 24 >>> n SignExt(8, x) >>> n.sort() BitVec(24) >>> v0 = BitVecVal(2, 2) >>> v0 2 >>> v0.size() 2 >>> v = simplify(SignExt(6, v0)) >>> v 254 >>> v.size() 8 >>> print("%.x" % v.as_long()) fe !First argument must be an integer2Second argument must be a Z3 bit-vector expression) r r)rrrIZ3_mk_sign_extrrr:r+rkr r r SignExtsrcCs>tr"tt|dtt|dtt||||jS)a[Return a bit-vector expression with `n` extra zero-bits. >>> x = BitVec('x', 16) >>> n = ZeroExt(8, x) >>> n.size() 24 >>> n ZeroExt(8, x) >>> n.sort() BitVec(24) >>> v0 = BitVecVal(2, 2) >>> v0 2 >>> v0.size() 2 >>> v = simplify(ZeroExt(6, v0)) >>> v 2 >>> v.size() 8 rr) r r)rrrIZ3_mk_zero_extrrr:rr r r ZeroExtsrcCs>tr"tt|dtt|dtt||||jS)acReturn an expression representing `n` copies of `a`. >>> x = BitVec('x', 8) >>> n = RepeatBitVec(4, x) >>> n RepeatBitVec(4, x) >>> n.size() 32 >>> v0 = BitVecVal(10, 4) >>> print("%.x" % v0.as_long()) a >>> v = simplify(RepeatBitVec(4, v0)) >>> v.size() 16 >>> print("%.x" % v.as_long()) aaaa rr) r r)rrrI Z3_mk_repeatrrr:rr r r RepeatBitVecsrcCs.trtt|dtt|||jS)z+Return the reduction-and expression of `a`.r)r r)rrIZ3_mk_bvredandrrr:rr r r BVRedAnd7srcCs.trtt|dtt|||jS)z*Return the reduction-or expression of `a`.r)r r)rrI Z3_mk_bvredorrrr:rr r r BVRedOr>srcCs:t||t||\}}tt|||||jS)zEA predicate the determines that bit-vector addition does not overflow)rr1r2Z3_mk_bvadd_no_overflowrrr:rkrZsignedr r r BVAddNoOverflowEs rcCs8t||t||\}}tt||||jS)zMA predicate the determines that signed bit-vector addition does not underflow)rr1r2Z3_mk_bvadd_no_underflowrrr:rr r r BVAddNoUnderflowLs rcCs8t||t||\}}tt||||jS)zHA predicate the determines that bit-vector subtraction does not overflow)rr1r2Z3_mk_bvsub_no_overflowrrr:rr r r BVSubNoOverflowSs rcCs:t||t||\}}tt|||||jS)zIA predicate the determines that bit-vector subtraction does not underflow)rr1r2Z3_mk_bvsub_no_underflowrrr:rr r r BVSubNoUnderflowZs rcCs8t||t||\}}tt||||jS)zLA predicate the determines that bit-vector signed division does not overflow)rr1r2Z3_mk_bvsdiv_no_overflowrrr:rr r r BVSDivNoOverflowas rcCs.trtt|dtt|||jS)zKA predicate the determines that bit-vector unary negation does not overflowr)r r)rr2Z3_mk_bvneg_no_overflowrrr:rr r r BVSNegNoOverflowhsrcCs:t||t||\}}tt|||||jS)zKA predicate the determines that bit-vector multiplication does not overflow)rr1r2Z3_mk_bvmul_no_overflowrrr:rr r r BVMulNoOverflowos rcCs8t||t||\}}tt||||jS)zSA predicate the determines that bit-vector signed multiplication does not underflow)rr1r2Z3_mk_bvmul_no_underflowrrr:rr r r BVMulNoUnderflowvs rc@s eZdZdZddZddZdS)rz Array sorts.cCstt||j|jS)zReturn the domain of the array sort `self`. >>> A = ArraySort(IntSort(), BoolSort()) >>> A.domain() Int )rZ3_get_array_sort_domainrrr:rnr r r rszArraySortRef.domaincCstt||j|jS)zReturn the range of the array sort `self`. >>> A = ArraySort(IntSort(), BoolSort()) >>> A.range() Bool )rZ3_get_array_sort_rangerrr:rnr r r rszArraySortRef.rangeN)rsrtrurvrrr r r r rs rc@s8eZdZdZddZddZddZdd Zd d Zd S) rJzArray expressions. cCstt|||jS)zReturn the array sort of the array expression `self`. >>> a = Array('a', IntSort(), BoolSort()) >>> a.sort() Array(Int, Bool) )rrrrr:rnr r r rsz ArrayRef.sortcCs |S)zShorthand for `self.sort().domain()`. >>> a = Array('a', IntSort(), BoolSort()) >>> a.domain() Int )rrrnr r r rszArrayRef.domaincCs |S)zShorthand for `self.sort().range()`. >>> a = Array('a', IntSort(), BoolSort()) >>> a.range() Bool )rrrnr r r rszArrayRef.rangecCs.||}tt||||jS)zReturn the Z3 expression `self[arg]`. >>> a = Array('a', IntSort(), BoolSort()) >>> i = Int('i') >>> a[i] a[i] >>> a[i].sexpr() '(select a i)' )rrrrrrr:rr r r rs zArrayRef.__getitem__cCstt|||jSr)rZ3_mk_array_defaultrrr:rnr r r defaultszArrayRef.defaultN) rsrtrurvrrrrrr r r r rJs     rJcCs"t|jt|j|jtkSr)rr:r7rrrrr r r is_array_sortsrcCs t|tS)zReturn `True` if `a` is a Z3 array expression. >>> a = Array('a', IntSort(), IntSort()) >>> is_array(a) True >>> is_array(Store(a, 0, 1)) True >>> is_array(a[0]) False )r rJrr r r is_arrays rcCs t|tS)zReturn `True` if `a` is a Z3 constant array. >>> a = K(IntSort(), 10) >>> is_const_array(a) True >>> a = Array('a', IntSort(), IntSort()) >>> is_const_array(a) False riZZ3_OP_CONST_ARRAYrr r r is_const_arrays rcCs t|tS)zReturn `True` if `a` is a Z3 constant array. >>> a = K(IntSort(), 10) >>> is_K(a) True >>> a = Array('a', IntSort(), IntSort()) >>> is_K(a) False rrr r r is_Ks rcCs t|tS)zReturn `True` if `a` is a Z3 map array expression. >>> f = Function('f', IntSort(), IntSort()) >>> b = Array('b', IntSort(), IntSort()) >>> a = Map(f, b) >>> a Map(f, b) >>> is_map(a) True >>> is_map(b) False )riZZ3_OP_ARRAY_MAPrr r r is_maps rcCs t|tS)zReturn `True` if `a` is a Z3 default array expression. >>> d = Default(K(IntSort(), 10)) >>> is_default(d) True )riZZ3_OP_ARRAY_DEFAULTrr r r is_defaultsrcCs>trtt|dtt|t||jd|j dS)a.Return the function declaration associated with a Z3 map array expression. >>> f = Function('f', IntSort(), IntSort()) >>> b = Array('b', IntSort(), IntSort()) >>> a = Map(f, b) >>> eq(f, get_map_func(a)) True >>> get_map_func(a) f >>> get_map_func(a)(0) f(0) z!Z3 array map expression expected.rrp) r r)rrZ3_to_func_declrrr6rr:rr r r get_map_func s rcGst|}tr tt|dkdt|d}||}|d}trl|D]$}tt|dt|j|jkdqF|j}t|dkrtt||j |j |St |}t |D]}||j ||<qtt ||||j |S)aReturn the Z3 array sort with the given domain and range sorts. >>> A = ArraySort(IntSort(), BoolSort()) >>> A Array(Int, Bool) >>> A.domain() Int >>> A.range() Bool >>> AA = ArraySort(IntSort(), A) >>> AA Array(Int, Array(Int, Bool)) rrrrrr[) rMr r)rErr:rZ3_mk_array_sortr7rrrZ3_mk_array_sort_n)r!rrdr3r:r#rr r r ArraySort%s"    rcCs.t||}|j}tt|t|||j|S)zReturn an array constant named `name` with the given domain and range sorts. >>> a = Array('a', IntSort(), IntSort()) >>> a.sort() Array(Int, Int) >>> a[0] a[0] )rr:rJrtr7r;r)r,r#r"r3r:r r r ArrayFs rcCsbtrtt|d||}||}|j}tt | | | | |S)a,Return a Z3 store array expression. >>> a = Array('a', IntSort(), IntSort()) >>> i, v = Ints('i v') >>> s = Update(a, i, v) >>> s.sort() Array(Int, Int) >>> prove(s[i] == v) proved >>> j = Int('j') >>> prove(Implies(i != j, s[j] == a[j])) proved ,First argument must be a Z3 array expression) r r)rrrrrr:r Z3_mk_storer7r)rkrrr:r r r UpdateTs rcCstrtt|d|S)zx Return a default value for array expression. >>> b = K(IntSort(), 1) >>> prove(Default(b) == 1) proved r)r r)rrrr r r DefaultjsrcCs t|||S)a+Return a Z3 store array expression. >>> a = Array('a', IntSort(), IntSort()) >>> i, v = Ints('i v') >>> s = Store(a, i, v) >>> s.sort() Array(Int, Int) >>> prove(s[i] == v) proved >>> j = Int('j') >>> prove(Implies(i != j, s[j] == a[j])) proved )r)rkrrr r r StoreusrcCstrtt|d||S)zReturn a Z3 select array expression. >>> a = Array('a', IntSort(), IntSort()) >>> i = Int('i') >>> Select(a, i) a[i] >>> eq(Select(a, i), a[i]) True r)r r)r)rkrr r r Selects rcGst|}tr\tt|dkdtt|dttdd|Ddtt||kdt|\}}|j}t t | |j |||S)a+Return a Z3 map array expression. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> a1 = Array('a1', IntSort(), IntSort()) >>> a2 = Array('a2', IntSort(), IntSort()) >>> b = Map(f, a1, a2) >>> b Map(f, a1, a2) >>> prove(b[0] == f(a1[0], a2[0])) proved rz)At least one Z3 array expression expectedz0First argument must be a Z3 function declarationcSsg|] }t|qSr )rrar r r rDszMap..zZ3 array expected expectedzNumber of arguments mismatch) rMr r)rErrrrr:rJ Z3_mk_mapr7r)r%rLrrr:r r r Maps  rcCsHtrtt|d|j}t|s,t||}tt||j | |S)zReturn a Z3 constant array expression. >>> a = K(IntSort(), 10) >>> a K(Int, 10) >>> a.sort() Array(Int, Int) >>> i = Int('i') >>> a[i] K(Int, 10)[i] >>> simplify(a[i]) 10 r) r r)rr:rrZrJZ3_mk_const_arrayr7rr)r#rr:r r r Ks  rcCs@|j}tr"tt|ot|dtt||||S)zReturn extensionality index for one-dimensional arrays. >> a, b = Consts('a b', SetSort(IntSort())) >> Ext(a, b) Ext(a, b) zarguments must be arrays) r:r r)rrrZ3_mk_array_extr7rrLr r r ExtsrcCs.|j}t||}tt||||Sr)r:rZrZ3_mk_set_has_sizer7r)rkr{r:r r r SetHasSizes rcCs t|tS)zReturn `True` if `a` is a Z3 array select application. >>> a = Array('a', IntSort(), IntSort()) >>> is_select(a) False >>> i = Int('i') >>> is_select(a[i]) True )riZ Z3_OP_SELECTrr r r is_selects rcCs t|tS)zReturn `True` if `a` is a Z3 array store application. >>> a = Array('a', IntSort(), IntSort()) >>> is_store(a) False >>> is_store(Store(a, 0, 1)) True )riZ Z3_OP_STORErr r r is_stores rcCs t|tS)z& Create a set sort over element sort s)rrmr2r r r SetSortsrcCs|j}tt||j|S)zGCreate the empty set >>> EmptySet(IntSort()) K(Int, False) )r:rJZ3_mk_empty_setr7rr9r r r EmptySetsrcCs|j}tt||j|S)zDCreate the full set >>> FullSet(IntSort()) K(Int, True) )r:rJZ3_mk_full_setr7rr9r r r FullSetsrcGs2t|}t|}t|\}}tt||||S)z Take the union of sets >>> a = Const('a', SetSort(IntSort())) >>> b = Const('b', SetSort(IntSort())) >>> SetUnion(a, b) union(a, b) )rMrrrJZ3_mk_set_unionr7rqr r r SetUnion s rcGs2t|}t|}t|\}}tt||||S)z Take the union of sets >>> a = Const('a', SetSort(IntSort())) >>> b = Const('b', SetSort(IntSort())) >>> SetIntersect(a, b) intersection(a, b) )rMrrrJZ3_mk_set_intersectr7rqr r r SetIntersects r cCs4t||g}t||}tt||||S)zr Add element e to set s >>> a = Const('a', SetSort(IntSort())) >>> SetAdd(a, 1) Store(a, 1, True) )rrZrJ Z3_mk_set_addr7rr3rXr:r r r SetAdd$s  r cCs4t||g}t||}tt||||S)zv Remove element e to set s >>> a = Const('a', SetSort(IntSort())) >>> SetDel(a, 1) Store(a, 1, False) )rrZrJ Z3_mk_set_delr7rr r r r SetDel/s  rcCs|j}tt|||S)zs The complement of set s >>> a = Const('a', SetSort(IntSort())) >>> SetComplement(a) complement(a) )r:rJZ3_mk_set_complementr7rr9r r r SetComplement:srcCs*t||g}tt||||S)z The set difference of a and b >>> a = Const('a', SetSort(IntSort())) >>> b = Const('b', SetSort(IntSort())) >>> SetDifference(a, b) setminus(a, b) )rrJZ3_mk_set_differencer7rrLr r r SetDifferenceDs rcCs4t||g}t||}tt||||S)zp Check if e is a member of set s >>> a = Const('a', SetSort(IntSort())) >>> IsMember(1, a) a[1] )rrZr2Z3_mk_set_memberr7r)rXr3r:r r r IsMemberOs  rcCs*t||g}tt||||S)z Check if a is a subset of b >>> a = Const('a', SetSort(IntSort())) >>> b = Const('b', SetSort(IntSort())) >>> IsSubset(a, b) subset(a, b) )rr2Z3_mk_set_subsetr7rrLr r r IsSubsetZs rcCsFt|tsdSt|dkrdSt|dtoDt|dtpDt|dS)zEReturn `True` if acc is pair of the form (String, Datatype or Sort). Fr[rr)r rFrErSDatatyper)Zaccr r r _valid_accessorks   rc@sFeZdZdZdddZifddZddZd d Zd d Zd dZ dS)raYHelper class for declaring Z3 datatypes. >>> List = Datatype('List') >>> List.declare('cons', ('car', IntSort()), ('cdr', List)) >>> List.declare('nil') >>> List = List.create() >>> # List is now a Z3 declaration >>> List.nil nil >>> List.cons(10, List.nil) cons(10, nil) >>> List.cons(10, List.nil).sort() List >>> cons = List.cons >>> nil = List.nil >>> car = List.car >>> cdr = List.cdr >>> n = cons(1, cons(0, nil)) >>> n cons(1, cons(0, nil)) >>> simplify(cdr(n)) cons(0, nil) >>> simplify(car(n)) 1 NcCst||_||_g|_dSr)r6r:r, constructors)rfr,r:r r r rls zDatatype.__init__cCs t|j|j}t|j|_|Sr)rr,r:copydeepcopyr)rfrrr r r rszDatatype.__deepcopy__cGsTtr>tt|tdtt|tdttdd|Dd|j|||fdS)NString expectedcSsg|] }t|qSr )rrar r r rDsz)Datatype.declare_core..z[Valid list of accessors expected. An accessor is a pair of the form (String, Datatype|Sort))r r)r rSrrr)rfr,Zrec_namerLr r r declare_coreszDatatype.declare_corecGs:tr$tt|tdt|dkd|j|d|f|S)aUDeclare constructor named `name` with the given accessors `args`. Each accessor is a pair `(name, sort)`, where `name` is a string and `sort` a Z3 sort or a reference to the datatypes being declared. In the following example `List.declare('cons', ('car', IntSort()), ('cdr', List))` declares the constructor named `cons` that builds a new List using an integer and a List. It also declares the accessors `car` and `cdr`. The accessor `car` extracts the integer of a `cons` cell, and `cdr` the list of a `cons` cell. After all constructors were declared, we use the method create() to create the actual datatype in Z3. >>> List = Datatype('List') >>> List.declare('cons', ('car', IntSort()), ('cdr', List)) >>> List.declare('nil') >>> List = List.create() rrz Constructor name cannot be emptyzis-)r r)r rSr)rfr,rLr r r declareszDatatype.declarecCsd|j|jfS)NzDatatype(%s, %s))r,rrnr r r rszDatatype.__repr__cCst|gdS)aCreate a Z3 datatype based on the constructors declared using the method `declare()`. The function `CreateDatatypes()` must be used to define mutually recursive datatypes. >>> List = Datatype('List') >>> List.declare('cons', ('car', IntSort()), ('cdr', List)) >>> List.declare('nil') >>> List = List.create() >>> List.nil nil >>> List.cons(10, List.nil) cons(10, nil) r)CreateDatatypesrnr r r createszDatatype.create)N) rsrtrurvrlrrrrr r r r r rts   rc@s eZdZdZddZddZdS)ScopedConstructor-Auxiliary object used to create Z3 datatypes.cCs||_||_dSrrWr:rfrWr:r r r rlszScopedConstructor.__init__cCs$|jdk r t|j|jdSr)r:r7Z3_del_constructorrWrnr r r roszScopedConstructor.__del__Nrsrtrurvrlror r r r r!sr!c@s eZdZdZddZddZdS)ScopedConstructorListr"cCs||_||_dSrr#r$r r r rlszScopedConstructorList.__init__cCs$|jdk r t|j|jdSr)r:r7Z3_del_constructor_listrWrnr r r roszScopedConstructorList.__del__Nr&r r r r r'sr'c sttrlttdkdttddDdttfddDdttddDd dj}t}t|}t|}t|}g}t |D]}|}t |j |||<t|j } t | } t | D](} |j | } t | d|} t | d |}| d }t|}t|}t|}tj|}t |D]}||d}||d }t ||||<t|trtrt|d kd d ||<|||<n(trtt|d|j||<d||<qFt|| |||||| | <|t| | |qt|| | ||<|t|||qt|||||g}t |D]}t|||}|} t | D]} || }| }| }| dkr|}t!||||"| }t!|d||t |D]"}|#| |}t!|| |qڐqz||qXt$|S)aCreate mutually recursive Z3 datatypes using 1 or more Datatype helper objects. In the following example we define a Tree-List using two mutually recursive datatypes. >>> TreeList = Datatype('TreeList') >>> Tree = Datatype('Tree') >>> # Tree has two constructors: leaf and node >>> Tree.declare('leaf', ('val', IntSort())) >>> # a node contains a list of trees >>> Tree.declare('node', ('children', TreeList)) >>> TreeList.declare('nil') >>> TreeList.declare('cons', ('car', Tree), ('cdr', TreeList)) >>> Tree, TreeList = CreateDatatypes(Tree, TreeList) >>> Tree.val(Tree.leaf(10)) val(leaf(10)) >>> simplify(Tree.val(Tree.leaf(10))) 10 >>> n1 = Tree.node(TreeList.cons(Tree.leaf(10), TreeList.cons(Tree.leaf(20), TreeList.nil))) >>> n1 node(cons(leaf(10), cons(leaf(20), nil))) >>> n2 = Tree.node(TreeList.cons(n1, TreeList.nil)) >>> simplify(n2 == n1) False >>> simplify(TreeList.car(Tree.children(n2)) == n1) True rz'At least one Datatype must be specifiedcSsg|]}t|tqSr )r rrBrr r r rDsz#CreateDatatypes..zArguments must be Datatypescsg|]}|jdjkqSrrpr)dsr r rDsrcSsg|]}|jgkqSr )rr)r r r rDszNon-empty Datatypes expectedrr[z8One and only one occurrence of each datatype is expectedNris_)%rMr r)rErr:SymbolrZConstructorListrr;r,rZ Constructorrrr rcountrBrrZ3_mk_constructorr7rr!Z3_mk_constructor_listr'Z3_mk_datatypesrnum_constructors constructorrsetattr recognizeraccessorrF)r,r:rrzoutZclistsZ to_deleterrZnum_cscsjrWcnameZrnamefsZnum_fsfnamessortsZrefsr{r/ZftyperZdrefZcrefZ cref_nameZ cref_arityZrrefZarefr r+r rs                        rc@s0eZdZdZddZddZddZdd Zd S) rzDatatype sorts.cCstt||jS)aGReturn the number of constructors in the given Z3 datatype. >>> List = Datatype('List') >>> List.declare('cons', ('car', IntSort()), ('cdr', List)) >>> List.declare('nil') >>> List = List.create() >>> # List is now a Z3 declaration >>> List.num_constructors() 2 )r%Z3_get_datatype_sort_num_constructorsrrrnr r r r3Gs z DatatypeSortRef.num_constructorscCs2trt||kdtt||j||jS)aReturn a constructor of the datatype `self`. >>> List = Datatype('List') >>> List.declare('cons', ('car', IntSort()), ('cdr', List)) >>> List.declare('nil') >>> List = List.create() >>> # List is now a Z3 declaration >>> List.num_constructors() 2 >>> List.constructor(0) cons >>> List.constructor(1) nil Invalid constructor index)r r)r3r Z3_get_datatype_sort_constructorrrr:r;r r r r4TszDatatypeSortRef.constructorcCs2trt||kdtt||j||jS)aIn Z3, each constructor has an associated recognizer predicate. If the constructor is named `name`, then the recognizer `is_name`. >>> List = Datatype('List') >>> List.declare('cons', ('car', IntSort()), ('cdr', List)) >>> List.declare('nil') >>> List = List.create() >>> # List is now a Z3 declaration >>> List.num_constructors() 2 >>> List.recognizer(0) is(cons) >>> List.recognizer(1) is(nil) >>> simplify(List.is_nil(List.cons(10, List.nil))) False >>> simplify(List.is_cons(List.cons(10, List.nil))) True >>> l = Const('l', List) >>> simplify(List.is_cons(l)) is(cons, l) zInvalid recognizer index)r r)r3rZ3_get_datatype_sort_recognizerrrr:r;r r r r6gszDatatypeSortRef.recognizercCsNtr0t||kdt|||kdtt||j|||j dS)aIn Z3, each constructor has 0 or more accessor. The number of accessors is equal to the arity of the constructor. >>> List = Datatype('List') >>> List.declare('cons', ('car', IntSort()), ('cdr', List)) >>> List.declare('nil') >>> List = List.create() >>> List.num_constructors() 2 >>> List.constructor(0) cons >>> num_accs = List.constructor(0).arity() >>> num_accs 2 >>> List.accessor(0, 0) car >>> List.accessor(0, 1) cdr >>> List.constructor(1) nil >>> num_accs = List.constructor(1).arity() >>> num_accs 0 r@zInvalid accessor indexrp) r r)r3r4rr)Z3_get_datatype_sort_constructor_accessorrrr:)rfrr:r r r r7szDatatypeSortRef.accessorN)rsrtrurvr3r4r6r7r r r r rDs  rc@seZdZdZddZdS)rKzDatatype expressions.cCstt|||jS)z;Return the datatype sort of the datatype expression `self`.)rrrrr:rnr r r rszDatatypeRef.sortN)rsrtrurvrr r r r rKsrKcsbt||fddttD}j|f|dfddttDfS)zCreate a named tuple sort base on a set of underlying sorts Example: >>> pair, mk_pair, (first, second) = TupleSort("pair", [IntSort(), StringSort()]) csg|]}d||fqS) project%dr r )r>r r rDszTupleSort..rcsg|]}d|qSr*)r7r )rFr r rDs)rrrErr r4)r,r>r:Zprojectsr )r>rFr TupleSorts  rEcs^t||tt|D] }d|d|||fqfddtt|DfS)zCreate a named tagged union sort base on a set of underlying sorts Example: >>> sum, ((inject0, extract0), (inject1, extract1)) = DisjointSum("+", [IntSort(), StringSort()]) zinject%drDcs"g|]}||dfqSr*)r4r7r sumr r rDszDisjointSum..)rrrErr )r,r>r:rr rFr DisjointSums  rHc Cstr@tt|tdttdd|Ddtt|dkdt|}t|}t|}t|D]}t ||||<qbt |}t |}t |}t t | ||||||}g} t|D]}| t|||qdd| D} || fS)zReturn a new enumeration sort named `name` containing the given values. The result is a pair (sort, list of constants). Example: >>> Color, (red, green, blue) = EnumSort('Color', ['red', 'green', 'blue']) zName must be a stringcSsg|]}t|tqSr )r rSrr r r rDszEnumSort..z&Eumeration sort values must be stringsrzAt least one value expectedcSsg|] }|qSr r rar r r rDs)r r)r rSrrEr6r.rr;rrZ3_mk_enumeration_sortr7rr) r,valuesr:rZ _val_namesrZ_valuesZ_testersSVr r r EnumSorts$     rMc@sFeZdZdZdddZifddZddZd d Zd d Zd dZ dS) ParamsRefzSet of parameters used to configure Solvers, Tactics and Simplifiers in Z3. Consider using the function `args2params` to create instances of this object. NcCs@t||_|dkr$t|j|_n||_t|j|jdSr)r6r: Z3_mk_paramsr7rZ3_params_inc_ref)rfr:rr r r rls  zParamsRef.__init__cCst|j|jSr)rNr:rrr r r rszParamsRef.__deepcopy__cCs$|jdk r t|j|jdSr)r:r7Z3_params_dec_refrrnr r r roszParamsRef.__del__cCstrtt|tdt||j}t|trDt|j|j ||n|t |rdt |j|j ||n\t|t rt |j|j ||n:t|trt|j|j |t||jntrtdddS)z"Set parameter name with value val.zparameter name must be a stringFzinvalid parameter valueN)r r)r rSr;r:rRZ3_params_set_boolr7rrZ3_params_set_uintrCZ3_params_set_doubleZ3_params_set_symbol)rfr,rUZname_symr r r rHs     z ParamsRef.setcCst|j|jSr)Z3_params_to_stringr:r7rrnr r r r szParamsRef.__repr__cCs*tt|tdt|j|j|jdS)Nz"parameter description set expected)r)r ParamDescrsRefZ3_params_validater:r7rdescr)rfr,r r r validateszParamsRef.validate)NN) rsrtrurvrlrrorHrrZr r r r rNs  rNcCsrtrtt|ddkdd}t|}|D]"}|dkr>|}q,|||d}q,|D]}||}|||qT|S)zConvert python arguments into a Z3_params object. A ':' is added to the keywords, and '_' is replaced with '-' >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True}) (params model true relevancy 2 elim_and true) r[rr\N)r r)rErNrH) argumentskeywordsr:rjrrkr{rr r r args2paramss r]c@sfeZdZdZdddZifddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ dS)rWzNSet of parameter descriptions for Solvers, Tactics and Simplifiers in Z3. NcCs6tt|tdt||_||_t|j|jdS)Nz%parameter description object expected)r)r Z ParamDescrsr6r:rYZ3_param_descrs_inc_refr7)rfrYr:r r r rl/s zParamDescrsRef.__init__cCst|j|jSr)ZParamsDescrsRefrYr:rr r r r5szParamDescrsRef.__deepcopy__cCs$|jdk r t|j|jdSr)r:r7Z3_param_descrs_dec_refrYrnr r r ro8szParamDescrsRef.__del__cCstt|j|jSz@Return the size of in the parameter description `self`. )rZ3_param_descrs_sizer:r7rYrnr r r rf<szParamDescrsRef.sizecCs|Sr`rfrnr r r __len__AszParamDescrsRef.__len__cCst|jt|j|j|S)zLReturn the i-th parameter name in the parameter description `self`. )r@r:Z3_param_descrs_get_namer7rYrr r r get_nameFszParamDescrsRef.get_namecCst|j|jt||jS)z4Return the kind of the parameter named `n`. )Z3_param_descrs_get_kindr:r7rYr;rfr+r r r get_kindKszParamDescrsRef.get_kindcCst|j|jt||jS)zDReturn the documentation string of the parameter named `n`. )!Z3_param_descrs_get_documentationr:r7rYr;rgr r r get_documentationPsz ParamDescrsRef.get_documentationcCs t|r||S||SdSr)rrerhrr r r rUs zParamDescrsRef.__getitem__cCst|j|jSr)Z3_param_descrs_to_stringr:r7rYrnr r r r[szParamDescrsRef.__repr__)N)rsrtrurvrlrrorfrcrerhrjrrr r r r rW+s  rWc@seZdZdZd3ddZddZd d Zd d Zd dZddZ ddZ ddZ ddZ ddZ ddZddZddZdd Zd!d"Zd#d$Zd%d&Zd4d'd(Zd)d*Zd+d,Zifd-d.Zd/d0Zd1d2ZdS)5GoalaHGoal is a collection of constraints we want to find a solution or show to be unsatisfiable (infeasible). Goals are processed using Tactics. A Tactic transforms a goal into a set of subgoals. A goal has a solution if one of its subgoals has a solution. A goal is unsatisfiable if all subgoals are unsatisfiable. TFNcCsbtrt|dkp|dk dt||_||_|jdkrLt|j||||_t|j|jdS)NzIIf goal is different from None, then ctx must be also different from None)r r)r6r:goal Z3_mk_goalr7Z3_goal_inc_ref)rfZmodelsZ unsat_coresproofsr:rmr r r rlms  z Goal.__init__cCs.|jdk r*|jdk r*t|j|jdSr)rmr:r7Z3_goal_dec_refrnr r r rowsz Goal.__del__cCstt|j|jS)aReturn the depth of the goal `self`. The depth corresponds to the number of tactics applied to `self`. >>> x, y = Ints('x y') >>> g = Goal() >>> g.add(x == 0, y >= x + 1) >>> g.depth() 0 >>> r = Then('simplify', 'solve-eqs')(g) >>> # r has 1 subgoal >>> len(r) 1 >>> r[0].depth() 2 )r Z3_goal_depthr:r7rmrnr r r depth{sz Goal.depthcCst|j|jS)auReturn `True` if `self` contains the `False` constraints. >>> x, y = Ints('x y') >>> g = Goal() >>> g.inconsistent() False >>> g.add(x == 0, x == 1) >>> g [x == 0, x == 1] >>> g.inconsistent() False >>> g2 = Tactic('propagate-values')(g)[0] >>> g2.inconsistent() True )Z3_goal_inconsistentr:r7rmrnr r r inconsistentszGoal.inconsistentcCst|j|jS)aCReturn the precision (under-approximation, over-approximation, or precise) of the goal `self`. >>> g = Goal() >>> g.prec() == Z3_GOAL_PRECISE True >>> x, y = Ints('x y') >>> g.add(x == y + 1) >>> g.prec() == Z3_GOAL_PRECISE True >>> t = With(Tactic('add-bounds'), add_bound_lower=0, add_bound_upper=10) >>> g2 = t(g)[0] >>> g2 [x == y + 1, x <= 10, x >= 0, y <= 10, y >= 0] >>> g2.prec() == Z3_GOAL_PRECISE False >>> g2.prec() == Z3_GOAL_UNDER True )Z3_goal_precisionr:r7rmrnr r r r8sz Goal.preccCs|S)znAlias for `prec()`. >>> g = Goal() >>> g.precision() == Z3_GOAL_PRECISE True )r8rnr r r r=szGoal.precisioncCstt|j|jS)zReturn the number of constraints in the goal `self`. >>> g = Goal() >>> g.size() 0 >>> x, y = Ints('x y') >>> g.add(x == 0, y > x) >>> g.size() 2 )r Z3_goal_sizer:r7rmrnr r r rfs z Goal.sizecCs|S)zReturn the number of constraints in the goal `self`. >>> g = Goal() >>> len(g) 0 >>> x, y = Ints('x y') >>> g.add(x == 0, y > x) >>> len(g) 2 rbrnr r r rcs z Goal.__len__cCstt|j|j||jS)zReturn a constraint in the goal `self`. >>> g = Goal() >>> x, y = Ints('x y') >>> g.add(x == 0, y > x) >>> g.get(0) x == 0 >>> g.get(1) y > x )rZ3_goal_formular:r7rmrr r r gets zGoal.getcCs|t|krt||S)zReturn a constraint in the goal `self`. >>> g = Goal() >>> x, y = Ints('x y') >>> g.add(x == 0, y > x) >>> g[0] x == 0 >>> g[1] y > x )rE IndexErrorryrr r r rs zGoal.__getitem__cGsBt|}t|j}|D]&}||}t|j|j|qdS)zAssert constraints into the goal. >>> x = Int('x') >>> g = Goal() >>> g.assert_exprs(x > 0, x < 2) >>> g [x > 0, x < 2] N)rMrmr:rZ3_goal_assertr7rmr)rfrLr3rCr r r assert_exprss   zGoal.assert_exprscGs|j|dS)zAdd constraints. >>> x = Int('x') >>> g = Goal() >>> g.append(x > 0, x < 2) >>> g [x > 0, x < 2] Nr|rfrLr r r rs z Goal.appendcGs|j|dS)zAdd constraints. >>> x = Int('x') >>> g = Goal() >>> g.insert(x > 0, x < 2) >>> g [x > 0, x < 2] Nr}r~r r r insert s z Goal.insertcGs|j|dS)zAdd constraints. >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0, x < 2) >>> g [x > 0, x < 2] Nr}r~r r r adds zGoal.addcCs4trtt|tdtt|j|j|j|jS)a~Retrieve model from a satisfiable goal >>> a, b = Ints('a b') >>> g = Goal() >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b) >>> t = Then(Tactic('split-clause'), Tactic('solve-eqs')) >>> r = t(g) >>> r[0] [Or(b == 0, b == 1), Not(0 <= b)] >>> r[1] [Or(b == 0, b == 1), Not(1 <= b)] >>> # Remark: the subgoal r[0] is unsatisfiable >>> # Creating a solver for solving the second subgoal >>> s = Solver() >>> s.add(r[1]) >>> s.check() sat >>> s.model() [b = 0] >>> # Model s.model() does not assign a value to `a` >>> # It is a model for subgoal `r[1]`, but not for goal `g` >>> # The method convert_model creates a model for `g` from a model for `r[1]`. >>> r[1].convert_model(s.model()) [b = 0, a = 1] zZ3 Model expected) r r)r ModelRefZ3_goal_convert_modelr:r7rmmodel)rfrr r r convert_model#szGoal.convert_modelcCst|Srrrnr r r r@sz Goal.__repr__cCst|j|jS)zJReturn a textual representation of the s-expression representing the goal.)Z3_goal_to_stringr:r7rmrnr r r rCsz Goal.sexprcCst|j|j|S)z=Return a textual representation of the goal in DIMACS format.)Z3_goal_to_dimacs_stringr:r7rmrfZ include_namesr r r dimacsGsz Goal.dimacscCs6trtt|tdtt|j|j||dS)avCopy goal `self` to context `target`. >>> x = Int('x') >>> g = Goal() >>> g.add(x > 10) >>> g [x > 10] >>> c2 = Context() >>> g2 = g.translate(c2) >>> g2 [x > 10] >>> g.ctx == main_ctx() True >>> g2.ctx == c2 True >>> g2.ctx == main_ctx() False ztarget must be a contextrmr:) r r)r rZrlZ3_goal_translater:r7rmrr r r rKszGoal.translatecCs ||jSrrrnr r r rbsz Goal.__copy__cCs ||jSrrrr r r reszGoal.__deepcopy__cOstd}|j|f||dS)a\Return a new simplified goal. This method is essentially invoking the simplify tactic. >>> g = Goal() >>> x = Int('x') >>> g.add(x + 1 >= 2) >>> g [x + 1 >= 2] >>> g2 = g.simplify() >>> g2 [x >= 1] >>> # g was not modified >>> g [x + 1 >= 2] rKr)rkapply)rfr[r\tr r r rKhsz Goal.simplifycsTt}|dkrtdjS|dkr.dStfddttDjSdS)aReturn goal `self` as a single Z3 expression. >>> x = Int('x') >>> g = Goal() >>> g.as_expr() True >>> g.add(x > 1) >>> g.as_expr() x > 1 >>> g.add(x < 10) >>> g.as_expr() And(x > 1, x < 10) rTrcsg|]}|qSr )ryr rnr r rDsz Goal.as_expr..N)rErr:ryrrrfrr rnr as_expr|s   z Goal.as_expr)TFFNN)T)rsrtrurvrlrorsrur8r=rfrcryrr|rrrrrrrrrrrKrr r r r rles0          rlc@s~eZdZdZdddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ifddZddZddZdS)rIzA collection (vector) of ASTs.NcCsXd|_|dkr*t||_t|j|_n||_|dk s>> A = AstVector() >>> len(A) 0 >>> A.push(Int('x')) >>> A.push(Int('x')) >>> len(A) 2 )rZ3_ast_vector_sizer:r7rrnr r r rcs zAstVector.__len__cCst|trJ|dkr||7}||kr.ttt|j|j||jSt|t rg}t | |D]&}| tt|j|j||jqj|SdS)zReturn the AST at position `i`. >>> A = AstVector() >>> A.push(Int('x') + 1) >>> A.push(Int('y')) >>> A[0] x + 1 >>> A[1] y rN) r rrcrzrZ3_ast_vector_getr:r7rslicerindicesr)rfrriir r r rs    zAstVector.__getitem__cCs.||krtt|j|j||dS)zUpdate AST at position `i`. >>> A = AstVector() >>> A.push(Int('x') + 1) >>> A.push(Int('y')) >>> A[0] x + 1 >>> A[0] = Int('x') >>> A[0] x N)rcrzZ3_ast_vector_setr:r7rr)rfrrr r r __setitem__s zAstVector.__setitem__cCst|j|j|dS)zAdd `v` in the end of the vector. >>> A = AstVector() >>> len(A) 0 >>> A.push(Int('x')) >>> len(A) 1 N)Z3_ast_vector_pushr:r7rr)rfrr r r pushs zAstVector.pushcCst|j|j|dS)zResize the vector to `sz` elements. >>> A = AstVector() >>> A.resize(10) >>> len(A) 10 >>> for i in range(10): A[i] = Int('x') >>> A[5] x N)Z3_ast_vector_resizer:r7rrr r r resizes zAstVector.resizecCs|D]}||rdSqdS)aDReturn `True` if the vector contains `item`. >>> x = Int('x') >>> A = AstVector() >>> x in A False >>> A.push(x) >>> x in A True >>> (x+1) in A False >>> A.push(x+1) >>> (x+1) in A True >>> A [x, x + 1] TFr)rfitemelemr r r __contains__s zAstVector.__contains__cCs tt|j|j||dS)zCopy vector `self` to context `other_ctx`. >>> x = Int('x') >>> A = AstVector() >>> A.push(x) >>> c2 = Context() >>> B = A.translate(c2) >>> B [x] rp)rIZ3_ast_vector_translater:r7rrfZ other_ctxr r r rs zAstVector.translatecCs ||jSrrrnr r r r%szAstVector.__copy__cCs ||jSrrrr r r r(szAstVector.__deepcopy__cCst|Srrrnr r r r+szAstVector.__repr__cCst|j|jS)zLReturn a textual representation of the s-expression representing the vector.)Z3_ast_vector_to_stringr:r7rrnr r r r.szAstVector.sexpr)NN)rsrtrurvrlrorcrrrrrrrrrrr r r r rIs     rIc@sneZdZdZdddZifddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZdS)AstMapzA mapping from ASTs to ASTs.NcCsXd|_|dkr*t||_t|j|_n||_|dk s>> M = AstMap() >>> len(M) 0 >>> x = Int('x') >>> M[x] = IntVal(1) >>> len(M) 1 )rZ3_ast_map_sizer:r7rrnr r r rcNs zAstMap.__len__cCst|j|j|S)zReturn `True` if the map contains key `key`. >>> M = AstMap() >>> x = Int('x') >>> M[x] = x + 1 >>> x in M True >>> x+1 in M False )Z3_ast_map_containsr:r7rrrfrir r r r[s zAstMap.__contains__cCs tt|j|j||jS)zRetrieve the value associated with key `key`. >>> M = AstMap() >>> x = Int('x') >>> M[x] = x + 1 >>> M[x] x + 1 )rZ3_ast_map_findr:r7rrrr r r rhs zAstMap.__getitem__cCs"t|j|j||dS)zAdd/Update key `k` with value `v`. >>> M = AstMap() >>> x = Int('x') >>> M[x] = x + 1 >>> len(M) 1 >>> M[x] x + 1 >>> M[x] = IntVal(1) >>> M[x] 1 N)Z3_ast_map_insertr:r7rr)rfr{rr r r rsszAstMap.__setitem__cCst|j|jSr)Z3_ast_map_to_stringr:r7rrnr r r rszAstMap.__repr__cCst|j|j|dS)zRemove the entry associated with key `k`. >>> M = AstMap() >>> x = Int('x') >>> M[x] = x + 1 >>> len(M) 1 >>> M.erase(x) >>> len(M) 0 N)Z3_ast_map_eraser:r7rr)rfr{r r r erases z AstMap.erasecCst|j|jdS)zRemove all entries from the map. >>> M = AstMap() >>> x = Int('x') >>> M[x] = x + 1 >>> M[x+x] = IntVal(1) >>> len(M) 2 >>> M.reset() >>> len(M) 0 N)Z3_ast_map_resetr:r7rrnr r r resets z AstMap.resetcCstt|j|j|jS)zReturn an AstVector containing all keys in the map. >>> M = AstMap() >>> x = Int('x') >>> M[x] = x + 1 >>> M[x+x] = IntVal(1) >>> M.keys() [x, x + x] )rIZ3_ast_map_keysr:r7rrnr r r keyss z AstMap.keys)NN)rsrtrurvrlrrorcrrrrrrrr r r r r9s    rc@sTeZdZdZddZifddZddZdd Zd d Zd d Z ddZ ddZ dS) FuncEntryzJStore the value of the interpretation of a function in a particular point.cCs"||_||_t|j|jdSr)entryr:Z3_func_entry_inc_refr7)rfrr:r r r rlszFuncEntry.__init__cCst|j|jSr)rrr:rr r r rszFuncEntry.__deepcopy__cCs$|jdk r t|j|jdSr)r:r7Z3_func_entry_dec_refrrnr r r roszFuncEntry.__del__cCstt|j|jS)aReturn the number of arguments in the given entry. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10) >>> s.check() sat >>> m = s.model() >>> f_i = m[f] >>> f_i.num_entries() 1 >>> e = f_i.entry(0) >>> e.num_args() 2 )rZ3_func_entry_get_num_argsr:r7rrnr r r rszFuncEntry.num_argscCs,||krttt|j|j||jS)anReturn the value of argument `idx`. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10) >>> s.check() sat >>> m = s.model() >>> f_i = m[f] >>> f_i.num_entries() 1 >>> e = f_i.entry(0) >>> e [1, 2, 20] >>> e.num_args() 2 >>> e.arg_value(0) 1 >>> e.arg_value(1) 2 >>> try: ... e.arg_value(2) ... except IndexError: ... print("index error") index error )rrzrZ3_func_entry_get_argr:r7rr;r r r arg_values zFuncEntry.arg_valuecCstt|j|j|jS)aReturn the value of the function at point `self`. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10) >>> s.check() sat >>> m = s.model() >>> f_i = m[f] >>> f_i.num_entries() 1 >>> e = f_i.entry(0) >>> e [1, 2, 20] >>> e.num_args() 2 >>> e.value() 20 )rZ3_func_entry_get_valuer:r7rrnr r r rszFuncEntry.valuecs,fddtD}||S)aReturn entry `self` as a Python list. >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0, 1) == 10, f(1, 2) == 20, f(1, 0) == 10) >>> s.check() sat >>> m = s.model() >>> f_i = m[f] >>> f_i.num_entries() 1 >>> e = f_i.entry(0) >>> e.as_list() [1, 2, 20] csg|]}|qSr )rr rnr r rDsz%FuncEntry.as_list..)rrrrr~r rnr as_list szFuncEntry.as_listcCs t|Sr)rrrnr r r rszFuncEntry.__repr__N) rsrtrurvrlrrorrrrrr r r r rs rc@sleZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ifddZ ddZ ddZdS) FuncInterpz6Stores the interpretation of a function in a Z3 model.cCs,||_||_|jdk r(t|j|jdSr)r%r:Z3_func_interp_inc_refr7)rfr%r:r r r rl&s zFuncInterp.__init__cCs.|jdk r*|jdk r*t|j|jdSr)r%r:r7Z3_func_interp_dec_refrnr r r ro,szFuncInterp.__del__cCs*t|j|j}|r"t||jSdSdS)a Return the `else` value for a function interpretation. Return None if Z3 did not specify the `else` value for this object. >>> f = Function('f', IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0) >>> s.check() sat >>> m = s.model() >>> m[f] [2 -> 0, else -> 1] >>> m[f].else_value() 1 N)Z3_func_interp_get_elser:r7r%rrfrr r r else_value0s zFuncInterp.else_valuecCstt|j|jS)afReturn the number of entries/points in the function interpretation `self`. >>> f = Function('f', IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0) >>> s.check() sat >>> m = s.model() >>> m[f] [2 -> 0, else -> 1] >>> m[f].num_entries() 1 )rZ3_func_interp_get_num_entriesr:r7r%rnr r r num_entriesGszFuncInterp.num_entriescCstt|j|jS)a=Return the number of arguments for each entry in the function interpretation `self`. >>> f = Function('f', IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0) >>> s.check() sat >>> m = s.model() >>> m[f].arity() 1 )rZ3_func_interp_get_arityr:r7r%rnr r r rWs zFuncInterp.aritycCs,||krttt|j|j||jS)aReturn an entry at position `idx < self.num_entries()` in the function interpretation `self`. >>> f = Function('f', IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0) >>> s.check() sat >>> m = s.model() >>> m[f] [2 -> 0, else -> 1] >>> m[f].num_entries() 1 >>> m[f].entry(0) [2, 0] )rrzrZ3_func_interp_get_entryr:r7r%r;r r r res zFuncInterp.entrycCstt|j|j||S)z2Copy model 'self' to context 'other_ctx'. )rZ3_model_translater:r7rrr r r ryszFuncInterp.translatecCs ||jSrrrnr r r r~szFuncInterp.__copy__cCs ||jSrrrr r r rszFuncInterp.__deepcopy__cs,fddtD}||S)aUReturn the function interpretation as a Python list. >>> f = Function('f', IntSort(), IntSort()) >>> s = Solver() >>> s.add(f(0) == 1, f(1) == 1, f(2) == 0) >>> s.check() sat >>> m = s.model() >>> m[f] [2 -> 0, else -> 1] >>> m[f].as_list() [[2, 0], 1] csg|]}|qSr )rrr rnr r rDsz&FuncInterp.as_list..)rrrrrr rnr rs zFuncInterp.as_listcCst|Srrrnr r r rszFuncInterp.__repr__N)rsrtrurvrlrorrrrrrrrrr r r r r#s rc@seZdZdZddZddZddZdd Zd&d d Zd'd dZ ddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zifd#d$Zd%S)(rzGModel/Solution of a satisfiability problem (aka system of constraints).cCs.|dk s t||_||_t|j|jdSr)rrr:Z3_model_inc_refr7rr r r rls zModelRef.__init__cCs$|jdk r t|j|jdSr)r:r7Z3_model_dec_refrrnr r r roszModelRef.__del__cCst|Srrrnr r r rszModelRef.__repr__cCst|j|jS)zKReturn a textual representation of the s-expression representing the model.)Z3_model_to_stringr:r7rrnr r r rszModelRef.sexprFcCsBtd}t|j|j|||r6t|d|jStddS)aEvaluate the expression `t` in the model `self`. If `model_completion` is enabled, then a default interpretation is automatically added for symbols that do not have an interpretation in the model `self`. >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0, x < 2) >>> s.check() sat >>> m = s.model() >>> m.eval(x + 1) 2 >>> m.eval(x == 1) True >>> y = Int('y') >>> m.eval(y + x) 1 + y >>> m.eval(y) y >>> m.eval(y, model_completion=True) 0 >>> # Now, m contains an interpretation for y >>> m.eval(y + x) 1 rrz*failed to evaluate expression in the modelN)r Z3_model_evalr:r7rrrr()rfrmodel_completionrr r r evals z ModelRef.evalcCs |||S)aAlias for `eval`. >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0, x < 2) >>> s.check() sat >>> m = s.model() >>> m.evaluate(x + 1) 2 >>> m.evaluate(x == 1) True >>> y = Int('y') >>> m.evaluate(y + x) 1 + y >>> m.evaluate(y) y >>> m.evaluate(y, model_completion=True) 0 >>> # Now, m contains an interpretation for y >>> m.evaluate(y + x) 1 )r)rfrrr r r evaluateszModelRef.evaluatecCs4tt|j|j}tt|j|j}||S)a9Return the number of constant and function declarations in the model `self`. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0, f(x) != x) >>> s.check() sat >>> m = s.model() >>> len(m) 2 )rZ3_model_get_num_constsr:r7rZ3_model_get_num_funcs)rf num_constsZ num_funcsr r r rcs zModelRef.__len__cCstrtt|tpt|dt|r.|}z|dkrt|j |j |j }|j dkrbWdSt ||j}t|r|t|WS|WSn tt|j |j |j |jWSWntk rYdSXdS)aUReturn the interpretation for a given declaration or constant. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0, x < 2, f(x) == 0) >>> s.check() sat >>> m = s.model() >>> m[x] 1 >>> m[f] [else -> 0] zZ3 declaration expectedrN)r r)r rrer6rZ3_model_get_const_interpr:r7rrrr is_as_array get_interpget_as_array_funcrZ3_model_get_func_interpr()rfr6Z_rrr r r rs    $zModelRef.get_interpcCstt|j|jS)a>Return the number of uninterpreted sorts that contain an interpretation in the model `self`. >>> A = DeclareSort('A') >>> a, b = Consts('a b', A) >>> s = Solver() >>> s.add(a != b) >>> s.check() sat >>> m = s.model() >>> m.num_sorts() 1 )rZ3_model_get_num_sortsr:r7rrnr r r num_sortss zModelRef.num_sortscCs,||krttt|j|j||jS)aReturn the uninterpreted sort at position `idx` < self.num_sorts(). >>> A = DeclareSort('A') >>> B = DeclareSort('B') >>> a1, a2 = Consts('a1 a2', A) >>> b1, b2 = Consts('b1 b2', B) >>> s = Solver() >>> s.add(a1 != a2, b1 != b2) >>> s.check() sat >>> m = s.model() >>> m.num_sorts() 2 >>> m.get_sort(0) A >>> m.get_sort(1) B )rrzrZ3_model_get_sortr:r7rr;r r r get_sort(s zModelRef.get_sortcsfddtDS)aReturn all uninterpreted sorts that have an interpretation in the model `self`. >>> A = DeclareSort('A') >>> B = DeclareSort('B') >>> a1, a2 = Consts('a1 a2', A) >>> b1, b2 = Consts('b1 b2', B) >>> s = Solver() >>> s.add(a1 != a2, b1 != b2) >>> s.check() sat >>> m = s.model() >>> m.sorts() [A, B] csg|]}|qSr )rr rnr r rDNsz"ModelRef.sorts..)rrrnr rnr r>?szModelRef.sortscCsRtrtt|tdz tt|j|j|j |jWSt k rLYdSXdS)aDReturn the interpretation for the uninterpreted sort `s` in the model `self`. >>> A = DeclareSort('A') >>> a, b = Consts('a b', A) >>> s = Solver() >>> s.add(a != b) >>> s.check() sat >>> m = s.model() >>> m.get_universe(A) [A!val!1, A!val!0] rN) r r)r rrIZ3_model_get_sort_universer:r7rrr(rfr3r r r get_universePs  zModelRef.get_universecCst|rn|t|krtt|j|j}||krNtt|j|j||jStt |j|j|||jSt |tr| |St |r| | St |tr||StrtdddS)aIf `idx` is an integer, then the declaration at position `idx` in the model `self` is returned. If `idx` is a declaration, then the actual interpretation is returned. The elements can be retrieved using position or the actual declaration. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0, x < 2, f(x) == 0) >>> s.check() sat >>> m = s.model() >>> len(m) 2 >>> m[0] x >>> m[1] f >>> m[x] 1 >>> m[f] [else -> 0] >>> for d in m: print("%s -> %s" % (d, m[d])) x -> 1 f -> [else -> 0] Fz0Integer, Z3 declaration, or Z3 constant expectedN)rrErzrr:r7rrZ3_model_get_const_declZ3_model_get_func_declr rrer6rrr r))rfr<rr r r rds        zModelRef.__getitem__cCsg}tt|j|jD]&}|tt|j|j||jqtt|j|jD]&}|tt |j|j||jqX|S)aJReturn a list with all symbols that have an interpretation in the model `self`. >>> f = Function('f', IntSort(), IntSort()) >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0, x < 2, f(x) == 0) >>> s.check() sat >>> m = s.model() >>> m.decls() [x, f] ) rrr:r7rrrrrr)rfrrr r r declss $$zModelRef.declscCs8trtt|tdt|j|j|}t||S)zlTranslate `self` to the context `target`. That is, return a copy of `self` in the context `target`. r) r r)r rZrr:r7rr)rfrrr r r rszModelRef.translatecCs ||jSrrrnr r r rszModelRef.__copy__cCs ||jSrrrr r r rszModelRef.__deepcopy__N)F)F)rsrtrurvrlrorrrrrcrrrr>rrrrrrr r r r rs$  "-rcCst|}tt||Sr)r6r Z3_mk_modelr7rpr r r ModelsrcCst|tot|j|S)z?Return true if n is a Z3 expression of the form (_ as-array f).)r rZ3_is_as_arrayr:r7rr+r r r rsrcCs0trtt|dtt|j||jS)z]Return the function declaration f associated with a Z3 expression of the form (_ as-array f).z as-array Z3 expression expected.)r r)rrZ3_get_as_array_func_declr:r7rrr r r rsrc@s\eZdZdZddZifddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS) Statisticsz Statistics for `Solver.check()`.cCs"||_||_t|j|jdSr)statsr:Z3_stats_inc_refr7)rfrr:r r r rlszStatistics.__init__cCst|j|jSr)rrr:rr r r rszStatistics.__deepcopy__cCs$|jdk r t|j|jdSr)r:r7Z3_stats_dec_refrrnr r r roszStatistics.__del__cCstrt}d}|td|D]H\}}|rD|tdd}n|tdd}|td||fq$|td|St|j|j SdS)NT2%F
%s%s
) rioStringIOwriteugetvalueZ3_stats_to_stringr:r7r)rfr8evenr{rr r r rs zStatistics.__repr__cCstt|j|jS)zReturn the number of statistical counters. >>> x = Int('x') >>> s = Then('simplify', 'nlsat').solver() >>> s.add(x > 0) >>> s.check() sat >>> st = s.statistics() >>> len(st) 6 )r Z3_stats_sizer:r7rrnr r r rcs zStatistics.__len__cCsj|t|krtt|j|j|r>tt|j|j|}nt|j|j|}t |j|j||fS)aReturn the value of statistical counter at position `idx`. The result is a pair (key, value). >>> x = Int('x') >>> s = Then('simplify', 'nlsat').solver() >>> s.add(x > 0) >>> s.check() sat >>> st = s.statistics() >>> len(st) 6 >>> st[0] ('nlsat propagations', 2) >>> st[1] ('nlsat stages', 2) ) rErzZ3_stats_is_uintr:r7rrZ3_stats_get_uint_valueZ3_stats_get_double_valueZ3_stats_get_key)rfr<rUr r r rs  zStatistics.__getitem__csfddttDS)zReturn the list of statistical counters. >>> x = Int('x') >>> s = Then('simplify', 'nlsat').solver() >>> s.add(x > 0) >>> s.check() sat >>> st = s.statistics() cs g|]}tjj|qSr )rr:r7r)rBr<rnr r rDsz#Statistics.keys..)rrErnr rnr rs zStatistics.keyscCs~tt|D]d}|t|j|j|kr t|j|j|rXtt|j|j|St |j|j|Sq t ddS)a#Return the value of a particular statistical counter. >>> x = Int('x') >>> s = Then('simplify', 'nlsat').solver() >>> s.add(x > 0) >>> s.check() sat >>> st = s.statistics() >>> st.get_key_value('nlsat propagations') 2 z unknown keyN) rrErr:r7rrrrrr()rfrir<r r r get_key_values zStatistics.get_key_valuecCs6|dd}z ||WStk r0tYnXdS)aAccess the value of statistical using attributes. Remark: to access a counter containing blank spaces (e.g., 'nlsat propagations'), we should use '_' (e.g., 'nlsat_propagations'). >>> x = Int('x') >>> s = Then('simplify', 'nlsat').solver() >>> s.add(x > 0) >>> s.check() sat >>> st = s.statistics() >>> st.nlsat_propagations 2 >>> st.nlsat_stages 2 _rvN)replacerr(AttributeError)rfr,rir r r __getattr__1s   zStatistics.__getattr__N) rsrtrurvrlrrorrcrrrrr r r r rs  rc@sDeZdZdZddZifddZddZdd Zd d Zd d Z dS)CheckSatResultzRepresents the result of a satisfiability check: sat, unsat, unknown. >>> s = Solver() >>> s.check() sat >>> r = s.check() >>> isinstance(r, CheckSatResult) True cCs ||_dSr)rrr r r rlZszCheckSatResult.__init__cCs t|jSr)rrrr r r r]szCheckSatResult.__deepcopy__cCst|to|j|jkSr)r rrrr r r r`szCheckSatResult.__eq__cCs || Sr)rrr r r rcszCheckSatResult.__ne__cCsLtr(|jtkrdS|jtkr"dSdSn |jtkr6dS|jtkrDdSdSdS)Nz satz unsatzunknownsatunsatunknown)rr Z3_L_TRUE Z3_L_FALSErnr r r rfs    zCheckSatResult.__repr__cCs"t}tdt|}t||Srrrr r r rvs zCheckSatResult._repr_html_N) rsrtrurvrlrrrrrr r r r rOs  rc@sTeZdZdZdSddZddZddZd d ZdTd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+ZdUd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z!d@dAZ"dBdCZ#dDdEZ$dFdGZ%dHdIZ&ifdJdKZ'dLdMZ(dVdOdPZ)dQdRZ*dS)WSolverzw Solver API provides methods for implementing the main SMT 2.0 commands: push, pop, check, get-model, etc. NcCst|dks|dk stt||_d|_d|_|dkrDt|j|_n||_t|j|j|dk rp|d|dS)N(\Z smtlib2_log) rr6r:backtrack_levelsolver Z3_mk_solverr7Z3_solver_inc_refrH)rfr r:logFiler r r rls zSolver.__init__cCs.|jdk r*|jdk r*t|j|jdSr)r r:r7Z3_solver_dec_refrnr r r roszSolver.__del__cOs(t|||j}t|j|j|jdS)a5Set a configuration option. The method `help()` return a string containing all available options. >>> s = Solver() >>> # The option MBQI can be set using three different approaches. >>> s.set(mbqi=True) >>> s.set('MBQI', True) >>> s.set(':mbqi', True) N)r]r:Z3_solver_set_paramsr7r rrfrLrrr r r rHs z Solver.setcCst|j|jdS)aZCreate a backtracking point. >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0) >>> s [x > 0] >>> s.push() >>> s.add(x < 1) >>> s [x > 0, x < 1] >>> s.check() unsat >>> s.pop() >>> s.check() sat >>> s [x > 0] N)Z3_solver_pushr:r7r rnr r r rsz Solver.pushrcCst|j|j|dS)acBacktrack \c num backtracking points. >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0) >>> s [x > 0] >>> s.push() >>> s.add(x < 1) >>> s [x > 0, x < 1] >>> s.check() unsat >>> s.pop() >>> s.check() sat >>> s [x > 0] N) Z3_solver_popr:r7r )rfrr r r popsz Solver.popcCst|j|jS)a&Return the current number of backtracking points. >>> s = Solver() >>> s.num_scopes() 0 >>> s.push() >>> s.num_scopes() 1 >>> s.push() >>> s.num_scopes() 2 >>> s.pop() >>> s.num_scopes() 1 )Z3_solver_get_num_scopesr:r7r rnr r r num_scopesszSolver.num_scopescCst|j|jdS)zRemove all asserted constraints and backtracking points created using `push()`. >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0) >>> s [x > 0] >>> s.reset() >>> s [] N)Z3_solver_resetr:r7r rnr r r rs z Solver.resetcGszt|}t|j}|D]^}t|ts.t|trR|D]}t|j|j| q2q| |}t|j|j| qdS)zAssert constraints into the solver. >>> x = Int('x') >>> s = Solver() >>> s.assert_exprs(x > 0, x < 2) >>> s [x > 0, x < 2] N) rMrmr:r rlrIZ3_solver_assertr7r rrrfrLr3rCr%r r r r|s   zSolver.assert_exprscGs|j|dS)zAssert constraints into the solver. >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0, x < 2) >>> s [x > 0, x < 2] Nr}r~r r r rs z Solver.addcCs|||Srrrffmlr r r __iadd__s zSolver.__iadd__cGs|j|dS)zAssert constraints into the solver. >>> x = Int('x') >>> s = Solver() >>> s.append(x > 0, x < 2) >>> s [x > 0, x < 2] Nr}r~r r r rs z Solver.appendcGs|j|dS)zAssert constraints into the solver. >>> x = Int('x') >>> s = Solver() >>> s.insert(x > 0, x < 2) >>> s [x > 0, x < 2] Nr}r~r r r r s z Solver.insertcCs`t|trt||j}tt|tdtt|to8t|dt|j|j | | dS)aAssert constraint `a` and track it in the unsat core using the Boolean constant `p`. If `p` is a string, it will be automatically converted into a Boolean constant. >>> x = Int('x') >>> p3 = Bool('p3') >>> s = Solver() >>> s.set(unsat_core=True) >>> s.assert_and_track(x > 0, 'p1') >>> s.assert_and_track(x != 1, 'p2') >>> s.assert_and_track(x < 0, p3) >>> print(s.check()) unsat >>> c = s.unsat_core() >>> len(c) 2 >>> Bool('p1') in c True >>> Bool('p2') in c False >>> p3 in c True Boolean expression expectedN) r rSrr:r)r2reZ3_solver_assert_and_trackr7r rrfrkrr r r assert_and_track+s   zSolver.assert_and_trackcGsft|j}t|}t|}t|}t|D]}|||||<q,t|j |j ||}t |S)aCheck whether the assertions in the given solver plus the optional assumptions are consistent or not. >>> x = Int('x') >>> s = Solver() >>> s.check() sat >>> s.add(x > 0, x < 2) >>> s.check() sat >>> s.model().eval(x) 1 >>> s.add(x < 1) >>> s.check() unsat >>> s.reset() >>> s.add(2**x == 4) >>> s.check() unknown ) rmr:rMrErrrrZ3_solver_check_assumptionsr7r r)rf assumptionsr3r _assumptionsrrr r r checkIs   z Solver.checkcCs>ztt|j|j|jWStk r8tdYnXdS)a?Return a model for the last `check()`. This function raises an exception if a model is not available (e.g., last `check()` returned unsat). >>> s = Solver() >>> a = Int('a') >>> s.add(a + 2 == 0) >>> s.check() sat >>> s.model() [a = -2] model is not availableN)rZ3_solver_get_modelr:r7r r(rnr r r rfsz Solver.modelcCst|j|j|jdS)z9Import model converter from other into the current solverN) Z3_solver_import_model_converterr:r7r rr r r import_model_converteryszSolver.import_model_convertercCstt|j|j|jS)aReturn a subset (as an AST vector) of the assumptions provided to the last check(). These are the assumptions Z3 used in the unsatisfiability proof. Assumptions are available in Z3. They are used to extract unsatisfiable cores. They may be also used to "retract" assumptions. Note that, assumptions are not really "soft constraints", but they can be used to implement them. >>> p1, p2, p3 = Bools('p1 p2 p3') >>> x, y = Ints('x y') >>> s = Solver() >>> s.add(Implies(p1, x > 0)) >>> s.add(Implies(p2, y > x)) >>> s.add(Implies(p2, y < 1)) >>> s.add(Implies(p3, y > -3)) >>> s.check(p1, p2, p3) unsat >>> core = s.unsat_core() >>> len(core) 2 >>> p1 in core True >>> p2 in core True >>> p3 in core False >>> # "Retracting" p2 >>> s.check(p1, p3) sat )rIZ3_solver_get_unsat_corer:r7r rnr r r unsat_core}szSolver.unsat_corecst|tr.td|j}|D]}||q|}t|tr\td|j}|D]}||qH|}tt|tdtt|tdtd|jt|j|j|j |j j }t }fddt |Dt |fS)aDetermine fixed values for the variables based on the solver state and assumptions. >>> s = Solver() >>> a, b, c, d = Bools('a b c d') >>> s.add(Implies(a,b), Implies(b, c)) >>> s.consequences([a],[b,c,d]) (sat, [Implies(a, b), Implies(a, c)]) >>> s.consequences([Not(c),d],[a,b,c,d]) (sat, [Implies(d, d), Implies(Not(c), Not(c)), Implies(Not(c), Not(b)), Implies(Not(c), Not(a))]) Nzast vector expectedcsg|] }|qSr r r  consequencesr r rDsz'Solver.consequences..) r rGrIr:rr)Z3_solver_get_consequencesr7r rrErr)rfr$Z variablesZ_asmsrkZ_varsrrr r-r r.s(       zSolver.consequencescCst|j|j|dS)zParse assertions from a fileN)Z3_solver_from_filer:r7r rffilenamer r r from_fileszSolver.from_filecCst|j|j|dS)zParse assertions from a stringN)Z3_solver_from_stringr:r7r rr r r from_stringszSolver.from_stringccstd|j|_|dk r,|D]}|j|q|j}d|_tt|j|j|jj||j}t |dkrvt |drvdS|Vt |dkr,dSq,dS)aGet set of cubes The method takes an optional set of variables that restrict which variables may be used as a starting point for cubing. If vars is not None, then the first case split is based on a variable in this set. Nr rr) rIr:cube_vsrr Z3_solver_cuber7r rrEr)rfvarsrlvlrr r r cubes" z Solver.cubecCs|jS)a4Access the set of variables that were touched by the most recently generated cube. This set of variables can be used as a starting point for additional cubes. The idea is that variables that appear in clauses that are reduced by the most recent cube are likely more useful to cube on.)r6rnr r r cube_varsszSolver.cube_varscCstt|j|j|jS)zJReturn a proof for the last `check()`. Proof construction must be enabled.)rZ3_solver_get_proofr:r7r rnr r r proofsz Solver.proofcCstt|j|j|jS)zReturn an AST vector containing all added constraints. >>> s = Solver() >>> s.assertions() [] >>> a = Int('a') >>> s.add(a > 0) >>> s.add(a < 10) >>> s.assertions() [a > 0, a < 10] )rIZ3_solver_get_assertionsr:r7r rnr r r assertionss zSolver.assertionscCstt|j|j|jS)zFReturn an AST vector containing all currently inferred units. )rIZ3_solver_get_unitsr:r7r rnr r r unitssz Solver.unitscCstt|j|j|jS)z`Return an AST vector containing all atomic formulas in solver state that are not units. )rIZ3_solver_get_non_unitsr:r7r rnr r r non_unitsszSolver.non_unitscCs>|}tjt|}t|j|j|jt||||fS)zSReturn trail and decision levels of the solver state after a check() call. ) trailrrrEZ3_solver_get_levelsr:r7r r)rfrDZlevelsr r r trail_levelsszSolver.trail_levelscCstt|j|j|jS)z?Return trail of the solver state after a check() call. )rIZ3_solver_get_trailr:r7r rnr r r rDsz Solver.trailcCstt|j|j|jS)aFReturn statistics for the last `check()`. >>> s = SimpleSolver() >>> x = Int('x') >>> s.add(x > 0) >>> s.check() sat >>> st = s.statistics() >>> st.get_key_value('final checks') 1 >>> len(st) > 0 True >>> st[0] != 0 True )rZ3_solver_get_statisticsr:r7r rnr r r statisticsszSolver.statisticscCst|j|jS)aReturn a string describing why the last `check()` returned `unknown`. >>> x = Int('x') >>> s = SimpleSolver() >>> s.add(2**x == 4) >>> s.check() unknown >>> s.reason_unknown() '(incomplete (theory arithmetic))' )Z3_solver_get_reason_unknownr:r7r rnr r r reason_unknowns zSolver.reason_unknowncCstt|j|jdSz2Display a string describing all available options.N)printZ3_solver_get_helpr:r7r rnr r r help&sz Solver.helpcCstt|j|j|jSz%Return the parameter description set.)rWZ3_solver_get_param_descrsr:r7r rnr r r param_descrs*szSolver.param_descrscCst|S)z5Return a formatted string with all added constraints.rrnr r r r.szSolver.__repr__cCs8trtt|tdt|j|j|}t||S)zTranslate `self` to the context `target`. That is, return a copy of `self` in the context `target`. >>> c1 = Context() >>> c2 = Context() >>> s1 = Solver(ctx=c1) >>> s2 = s1.translate(c2) r) r r)r rZZ3_solver_translater:r7r r )rfrr r r r r2szSolver.translatecCs ||jSrrrnr r r r?szSolver.__copy__cCs ||jSrrrr r r rBszSolver.__deepcopy__cCst|j|jS)aReturn a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format. >>> x = Int('x') >>> s = Solver() >>> s.add(x > 0) >>> s.add(x < 2) >>> r = s.sexpr() )Z3_solver_to_stringr:r7r rnr r r rEs z Solver.sexprTcCst|j|j|S)z?Return a textual representation of the solver in DIMACS format.)Z3_solver_to_dimacs_stringr:r7r rr r r rQsz Solver.dimacsc Cs|}t|}|}|dkr$|d8}t|}t|D]}||||<q6|dkrb||}ntd|j}t|jdddd|||S)z:return SMTLIB2 formatted benchmark for solver's assertionsrrTz#benchmark generated from python APIrr) r?rErrrrr:Z3_benchmark_to_smtlib_stringr7)rfesrZsz1rrrXr r r to_smt2Us*  zSolver.to_smt2)NNN)r)N)T)+rsrtrurvrlrorHrrrrr|rrrrr"r&rr*r,r.r3r5r:r;r=r?rArCrFrDrIrKrOrRrrrrrrrXr r r r r sP            r cCs&t|}t|}tt||||S)apCreate a solver customized for the given logic. The parameter `logic` is a string. It should be contains the name of a SMT-LIB logic. See http://www.smtlib.org/ for the name of all available logics. >>> s = SolverFor("QF_LIA") >>> x = Int('x') >>> s.add(x > 0) >>> s.add(x < 2) >>> s.check() sat >>> s.model() [x = 1] )r6r;r Z3_mk_solver_for_logicr7)Zlogicr:rr r r SolverForhsrZcCst|}tt|||S)zReturn a simple general purpose solver with limited amount of preprocessing. >>> s = SimpleSolver() >>> x = Int('x') >>> s.add(x > 0) >>> s.check() sat )r6r Z3_mk_simple_solverr7)r:rr r r SimpleSolver}s r\c@sFeZdZdZdNddZifddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZdOddZdPddZdQddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Zd9d:Zd;d<Z d=d>Z!d?d@Z"dAdBZ#dCdDZ$dEdFZ%dGdHZ&dIdJZ'dRdLdMZ(dS)S FixedpointzEFixedpoint API provides methods for solving with recursive predicatesNcCs`|dks|dk stt||_d|_|dkr>t|j|_n||_t|j|jg|_dSr)rr6r: fixedpointZ3_mk_fixedpointr7Z3_fixedpoint_inc_refr8)rfr^r:r r r rls zFixedpoint.__init__cCst|j|jSr)Z FixedPointr^r:rr r r rszFixedpoint.__deepcopy__cCs.|jdk r*|jdk r*t|j|jdSr)r^r:r7Z3_fixedpoint_dec_refrnr r r roszFixedpoint.__del__cOs(t|||j}t|j|j|jdS)zjSet a configuration option. The method `help()` return a string containing all available options. N)r]r:Z3_fixedpoint_set_paramsr7r^rrr r r rHszFixedpoint.setcCstt|j|jdSrL)rMZ3_fixedpoint_get_helpr:r7r^rnr r r rOszFixedpoint.helpcCstt|j|j|jSrP)rWZ3_fixedpoint_get_param_descrsr:r7r^rnr r r rRszFixedpoint.param_descrscGst|}t|j}|D]r}t|ts.t|tr\|D]&}||}t|j|j | q2q| |}||}t|j|j | qdS)zBAssert constraints as background axioms for the fixedpoint solver.N) rMrmr:r rlrIabstractZ3_fixedpoint_assertr7r^rrrr r r r|s    zFixedpoint.assert_exprscGs|j|dSzYAssert constraints as background axioms for the fixedpoint solver. Alias for assert_expr.Nr}r~r r r rszFixedpoint.addcCs|||Srrrr r r rs zFixedpoint.__iadd__cGs|j|dSrgr}r~r r r rszFixedpoint.appendcGs|j|dSrgr}r~r r r rszFixedpoint.insertcCs|dkr d}t||j}|dkrF||}t|j|j||n:t|}|tt ||j|}t|j|j||dS)aDAssert rules defining recursive predicates to the fixedpoint solver. >>> a = Bool('a') >>> b = Bool('b') >>> s = Fixedpoint() >>> s.register_relation(a.decl()) >>> s.register_relation(b.decl()) >>> s.fact(a) >>> s.rule(b, a) >>> s.query(b) sat Nr) r;r:reZ3_fixedpoint_add_ruler7r^rrMrrrfheadr.r,r%r r r add_rules   zFixedpoint.add_rulecCs||||dS)zXAssert rules defining recursive predicates to the fixedpoint solver. Alias for add_rule.Nrk)rfrjr.r,r r r ruleszFixedpoint.rulecCs||d|dS)zXAssert facts defining recursive predicates to the fixedpoint solver. Alias for add_rule.Nrl)rfrjr,r r r factszFixedpoint.factcGst|}t|}|dkrht|dtrht|}d}|D]}|j||<|d}q8t|j|j ||}nB|dkrz|d}n t ||j}| |d}t |j|j | }t|S)zQuery the fixedpoint engine whether formula is derivable. You can also pass an tuple or list of recursive predicates. rrF)rMrEr rrrZ3_fixedpoint_query_relationsr:r7r^rreZ3_fixedpoint_queryrr)rfqueryr_declsrqrr r r rqs      zFixedpoint.querycGszt|}t|}|dkr2t|dtr2tddn@|dkrD|d}nt|}||d}t|j |j | |}t |S)zdQuery the fixedpoint engine whether formula is derivable starting at the given query level. rrFZ unsupported) rMrEr rr)rreZ3_fixedpoint_query_from_lvlr:r7r^rr)rfr9rqrrr r r query_from_lvls   zFixedpoint.query_from_lvlcCsV|dkr d}t||j}t|}|tt||j|}t|j|j| |dS)z update ruleNr) r;r:rMrerrZ3_fixedpoint_update_ruler7r^rrir r r update_rules  zFixedpoint.update_rulecCst|j|j}t||jS)z%Retrieve answer from last query call.)Z3_fixedpoint_get_answerr:r7r^rrr r r get_answerszFixedpoint.get_answercCst|j|j}t||jS)z+Retrieve a ground cex from last query call.)#Z3_fixedpoint_get_ground_sat_answerr:r7r^rrr r r get_ground_sat_answer$sz Fixedpoint.get_ground_sat_answercCstt|j|j|jS)z-retrieve rules along the counterexample trace)rI#Z3_fixedpoint_get_rules_along_tracer:r7r^rnr r r get_rules_along_trace)sz Fixedpoint.get_rules_along_tracecCs$t|jt|j|j}|dS)z2retrieve rule names along the counterexample trace;)r@r:(Z3_fixedpoint_get_rule_names_along_tracer7r^ry)rfrzr r r get_rule_names_along_trace-sz%Fixedpoint.get_rule_names_along_tracecCst|j|j|jS)z:Retrieve number of levels used for predicate in PDR engine)Z3_fixedpoint_get_num_levelsr:r7r^r)rf predicater r r get_num_levels5szFixedpoint.get_num_levelscCs$t|j|j||j}t||jS)z|Retrieve properties known about predicate for the level'th unfolding. -1 is treated as the limit (infinity) )Z3_fixedpoint_get_cover_deltar:r7r^rr)rflevelrrr r r get_cover_delta9szFixedpoint.get_cover_deltacCs t|j|j||j|jdS)zkAdd property to predicate for the level'th unfolding. -1 is treated as infinity (infinity) N)Z3_fixedpoint_add_coverr:r7r^r)rfrrpropertyr r r add_cover@szFixedpoint.add_covercGs,t|}|D]}t|j|j|jq dS)zRegister relation as recursiveN)rMZ3_fixedpoint_register_relationr:r7r^r)rfZ relationsr%r r r register_relationFszFixedpoint.register_relationcGs`t|}dd|D}t|}t|}t|D]}||||<q0t|j|j|j||dS)z#Control how relation is representedcSsg|] }t|qSr )r;rr r r rDOsz;Fixedpoint.set_predicate_representation..N) rMrEr.r*Z3_fixedpoint_set_predicate_representationr:r7r^r)rfr%ZrepresentationsrrLrr r r set_predicate_representationLs  z'Fixedpoint.set_predicate_representationcCstt|j|j||jS)z%Parse rules and queries from a string)rIZ3_fixedpoint_from_stringr:r7r^rr r r parse_stringVszFixedpoint.parse_stringcCstt|j|j||jS)z#Parse rules and queries from a file)rIZ3_fixedpoint_from_filer:r7r^)rfr%r r r parse_fileZszFixedpoint.parse_filecCstt|j|j|jS)z9retrieve rules that have been added to fixedpoint context)rIZ3_fixedpoint_get_rulesr:r7r^rnr r r get_rules^szFixedpoint.get_rulescCstt|j|j|jS)z>retrieve assertions that have been added to fixedpoint context)rIZ3_fixedpoint_get_assertionsr:r7r^rnr r r get_assertionsbszFixedpoint.get_assertionscCs|Sz?Return a formatted string with all added rules and constraints.rrnr r r rfszFixedpoint.__repr__cCst|j|jdtdS)Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format. r)Z3_fixedpoint_to_stringr:r7r^rrnr r r rjszFixedpoint.sexprcCs"t|\}}t|j|j||S)zReturn a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format. Include also queries. )rrr:r7r^)rfZqueriesrLrEr r r to_stringps zFixedpoint.to_stringcCstt|j|j|jS)z2Return statistics for the last `query()`. )rZ3_fixedpoint_get_statisticsr:r7r^rnr r r rIxszFixedpoint.statisticscCst|j|jS)zNReturn a string describing why the last `query()` returned `unknown`. ) Z3_fixedpoint_get_reason_unknownr:r7r^rnr r r rK}szFixedpoint.reason_unknowncGs&t|}|D]}|j|g7_q dS)zAdd variable or several variables. The added variable or variables will be bound in the rules and queries N)rMr8)rfr8rr r r declare_varszFixedpoint.declare_varTcCs.|jgkr|S|rt|j|St|j|SdSr)r8rr)rfrrr r r res   zFixedpoint.abstract)NN)NN)NN)N)T))rsrtrurvrlrrorHrOrRr|rrrrrkrmrnrqrurwryr{r}rrrrrrrrrrrrrrIrKrrer r r r r]sL       r]c@seZdZdZddZdS)rzFinite domain sort.cCs2tjd}t||j|r&|dStddS)z)Return the size of the finite domain sortrrz*Failed to retrieve finite domain sort sizeN)r c_ulonglongZ3_get_finite_domain_sort_sizerrr(rr r r rfs zFiniteDomainSortRef.sizeN)rsrtrurvrfr r r r rsrcCs0t|tst|}t|}tt||||S)z4Create a named finite domain sort of a given size sz)r r.r;r6rZ3_mk_finite_domain_sortr7)r,rr:r r r FiniteDomainSorts rcCs t|tS)zReturn True if `s` is a Z3 finite-domain sort. >>> is_finite_domain_sort(FiniteDomainSort('S', 100)) True >>> is_finite_domain_sort(IntSort()) False )r rr2r r r is_finite_domain_sortsrc@s eZdZdZddZddZdS)rQzFinite-domain expressions.cCstt|||jS)z7Return the sort of the finite-domain expression `self`.)rrrrr:rnr r r rszFiniteDomainRef.sortcCst||Sz9Return a Z3 floating point expression as a Python string.rrnr r r r'szFiniteDomainRef.as_stringN)rsrtrurvrr'r r r r rQsrQcCs t|tS)zReturn `True` if `a` is a Z3 finite-domain expression. >>> s = FiniteDomainSort('S', 100) >>> b = Const('b', s) >>> is_finite_domain(b) True >>> is_finite_domain(Int('x')) False )r rQrr r r is_finite_domains rc@s eZdZdZddZddZdS)rPr&cCs t|S)zReturn a Z3 finite-domain numeral as a Python long (bignum) numeral. >>> s = FiniteDomainSort('S', 100) >>> v = FiniteDomainVal(3, s) >>> v 3 >>> v.as_long() + 1 4 rrnr r r r(s zFiniteDomainNumRef.as_longcCst||S)zReturn a Z3 finite-domain numeral as a Python string. >>> s = FiniteDomainSort('S', 100) >>> v = FiniteDomainVal(42, s) >>> v.as_string() '42' r)rnr r r r'szFiniteDomainNumRef.as_stringN)rsrtrurvr(r'r r r r rPs rPcCs6trtt|d|j}tt|t||j|S)zReturn a Z3 finite-domain value. If `ctx=None`, then the global context is used. >>> s = FiniteDomainSort('S', 256) >>> FiniteDomainVal(255, s) 255 >>> FiniteDomainVal('100', s) 100 zExpected finite-domain sort) r r)rr:rPrJr7rIr)rUrr:r r r FiniteDomainVals rcCst|ot|j|S)aReturn `True` if `a` is a Z3 finite-domain value. >>> s = FiniteDomainSort('S', 100) >>> b = Const('b', s) >>> is_finite_domain_value(b) False >>> b = FiniteDomainVal(10, s) >>> b 10 >>> is_finite_domain_value(b) True )rrMr:rrr r r is_finite_domain_values rc@sDeZdZddZddZddZddZd d Zd d Zd dZ dS)OptimizeObjectivecCs||_||_||_dSr)_opt_value_is_max)rfoptris_maxr r r rlszOptimizeObjective.__init__cCs$|j}tt|j|j|j|jSr)rrZ3_optimize_get_lowerr:r7optimizerrfrr r r lowerszOptimizeObjective.lowercCs$|j}tt|j|j|j|jSr)rrZ3_optimize_get_upperr:r7rrrr r r r_szOptimizeObjective.uppercCs$|j}tt|j|j|j|jSr)rrIZ3_optimize_get_lower_as_vectorr:r7rrrr r r lower_valuesszOptimizeObjective.lower_valuescCs$|j}tt|j|j|j|jSr)rrIZ3_optimize_get_upper_as_vectorr:r7rrrr r r upper_values#szOptimizeObjective.upper_valuescCs|jr|S|SdSr)rr_rrnr r r r'szOptimizeObjective.valuecCsd|j|jfS)Nz%s:%s)rrrnr r r r-szOptimizeObjective.__str__N) rsrtrurlrr_rrrrr r r r rsrcCst|\}}||dSr) _on_models)r:fnmdlr r r _global_on_model4s rc@seZdZdZdBddZifddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ dCddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z!d@dAZ"dS)DOptimizezaOptimize API provides methods for solving using objective functions and weighted soft constraintsNcCs6t||_t|j|_d|_t|j|jdSr)r6r:Z3_mk_optimizer7r _on_models_idZ3_optimize_inc_ref)rfr:r r r rl?s zOptimize.__init__cCst|j|jSr)rrr:rr r r rEszOptimize.__deepcopy__cCs@|jdk r*|jdk r*t|j|j|jdk r>> x = Int('x') >>> p3 = Bool('p3') >>> s = Optimize() >>> s.assert_and_track(x > 0, 'p1') >>> s.assert_and_track(x != 1, 'p2') >>> s.assert_and_track(x < 0, p3) >>> print(s.check()) unsat >>> c = s.unsat_core() >>> len(c) 2 >>> Bool('p1') in c True >>> Bool('p2') in c False >>> p3 in c True rN) r rSrr:r)r2reZ3_optimize_assert_and_trackr7rrr!r r r r"qs   zOptimize.assert_and_trackrGcstrdnttr$dtts6tddkrBdtjfddtjj dkrt|t rfd d |DS|S) aBAdd soft constraint with optional weight and optional identifier. If no weight is supplied, then the penalty for violating the soft constraint is 1. Soft constraints are grouped by identifiers. Soft constraints that are added without identifiers are grouped by default. z%dz%fz'weight should be a string or an integerNrcs(tjj|}t|dSr4)Z3_optimize_assert_softr:r7rrr)rkr)idrfrr r asoftsz Optimize.add_soft..asoftrcsg|] }|qSr r ra)rr r rDsz%Optimize.add_soft..) rr rCrSr(r;r:sys version_inforr)rfrCrrr )rrrfrr add_softs    zOptimize.add_softcCs"t|t|j|j|ddS)z#Add objective function to maximize.Tr)rZ3_optimize_maximizer:r7rrrr r r maximizes zOptimize.maximizecCs"t|t|j|j|ddS)z#Add objective function to minimize.Fr)rZ3_optimize_minimizer:r7rrrr r r minimizes zOptimize.minimizecCst|j|jdS)zAcreate a backtracking point for added rules, facts and assertionsN)Z3_optimize_pushr:r7rrnr r r rsz Optimize.pushcCst|j|jdS)z0restore to previously created backtracking pointN)Z3_optimize_popr:r7rrnr r r rsz Optimize.popcGsRt|}t|}t|}t|D]}||||<q"tt|j|j ||S)z:Check satisfiability while optimizing objective functions.) rMrErrrrZ3_optimize_checkr:r7r)rfr$rr%rr r r r&s   zOptimize.checkcCst|j|jS)zIReturn a string that describes why the last `check()` returned `unknown`.)Z3_optimize_get_reason_unknownr:r7rrnr r r rKszOptimize.reason_unknowncCs>ztt|j|j|jWStk r8tdYnXdS)z$Return a model for the last check().r'N)rZ3_optimize_get_modelr:r7rr(rnr r r rszOptimize.modelcCstt|j|j|jSr)rIZ3_optimize_get_unsat_corer:r7rrnr r r r,szOptimize.unsat_corecCst|tstd|SNz8Expecting objective handle returned by maximize/minimize)r rr(rrfobjr r r rs zOptimize.lowercCst|tstd|Sr)r rr(r_rr r r r_s zOptimize.uppercCst|tstd|Sr)r rr(rrr r r rs zOptimize.lower_valuescCst|tstd|Sr)r rr(rrr r r rs zOptimize.upper_valuescCst|j|j|dS)z+Parse assertions and objectives from a fileN)Z3_optimize_from_filer:r7rr1r r r r3szOptimize.from_filecCst|j|j|dS)z-Parse assertions and objectives from a stringN)Z3_optimize_from_stringr:r7rrr r r r5szOptimize.from_stringcCstt|j|j|jS)z6Return an AST vector containing all added constraints.)rIZ3_optimize_get_assertionsr:r7rrnr r r r?szOptimize.assertionscCstt|j|j|jS)z"returns set of objective functions)rIZ3_optimize_get_objectivesr:r7rrnr r r objectivesszOptimize.objectivescCs|Srrrnr r r rszOptimize.__repr__cCst|j|jS)r)Z3_optimize_to_stringr:r7rrnr r r rszOptimize.sexprcCstt|j|j|jS)z/Return statistics for the last check`. )rZ3_optimize_get_statisticsr:r7rrnr r r rIszOptimize.statisticscCsLttd}t|j}||ft|<||_t|j|j|jt |t dS)a&Register a callback that is invoked with every incremental improvement to objective values. The callback takes a model as argument. The life-time of the model is limited to the callback so the model has to be (deep) copied if it is to be used after the callback )N) rErrr:rZZ3_optimize_register_model_ehr7rrrc_void_p _on_model_eh)rfZon_modelrrr r r set_on_models   zOptimize.set_on_model)N)rGN)#rsrtrurvrlrrorHrOrRr|rrr"rrrrrr&rKrr,rr_rrr3r5r?rrrrIrr r r r r<s@     rc@sTeZdZdZddZifddZddZdd Zd d Zd d Z ddZ ddZ dS) ApplyResultzAn ApplyResult object contains the subgoals produced by a tactic when applied to a goal. It also contains model and proof converters. cCs"||_||_t|j|jdSr)rr:Z3_apply_result_inc_refr7)rfrr:r r r rl!szApplyResult.__init__cCst|j|jSr)rrr:rr r r r&szApplyResult.__deepcopy__cCs$|jdk r t|j|jdSr)r:r7Z3_apply_result_dec_refrrnr r r ro)szApplyResult.__del__cCstt|j|jS)aReturn the number of subgoals in `self`. >>> a, b = Ints('a b') >>> g = Goal() >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b) >>> t = Tactic('split-clause') >>> r = t(g) >>> len(r) 2 >>> t = Then(Tactic('split-clause'), Tactic('split-clause')) >>> len(t(g)) 4 >>> t = Then(Tactic('split-clause'), Tactic('split-clause'), Tactic('propagate-values')) >>> len(t(g)) 1 )r Z3_apply_result_get_num_subgoalsr:r7rrnr r r rc-szApplyResult.__len__cCs.|t|krttt|j|j||jdS)avReturn one of the subgoals stored in ApplyResult object `self`. >>> a, b = Ints('a b') >>> g = Goal() >>> g.add(Or(a == 0, a == 1), Or(b == 0, b == 1), a > b) >>> t = Tactic('split-clause') >>> r = t(g) >>> r[0] [a == 0, Or(b == 0, b == 1), a > b] >>> r[1] [a == 1, Or(b == 0, b == 1), a > b] r)rErzrlZ3_apply_result_get_subgoalr:r7rr;r r r r@s zApplyResult.__getitem__cCst|Srrrnr r r rQszApplyResult.__repr__cCst|j|jS)z_Return a textual representation of the s-expression representing the set of subgoals in `self`.)Z3_apply_result_to_stringr:r7rrnr r r rTszApplyResult.sexprcsRt}|dkrtdjS|dkr0dStfddttDSdS)aReturn a Z3 expression consisting of all subgoals. >>> x = Int('x') >>> g = Goal() >>> g.add(x > 1) >>> g.add(Or(x == 2, x == 3)) >>> r = Tactic('simplify')(g) >>> r [[Not(x <= 1), Or(x == 2, x == 3)]] >>> r.as_expr() And(Not(x <= 1), Or(x == 2, x == 3)) >>> r = Tactic('split-clause')(g) >>> r [[x > 1, x == 2], [x > 1, x == 3]] >>> r.as_expr() Or(And(x > 1, x == 2), And(x > 1, x == 3)) rFrcsg|]}|qSr )rr rnr r rDpsz'ApplyResult.as_expr..N)rErr:rrrrr rnr rXs   zApplyResult.as_exprN) rsrtrurvrlrrorcrrrrr r r r rs rc@sXeZdZdZdddZifddZddZdd d Zd d Zd dZ ddZ ddZ dS)rka$Tactics transform, solver and/or simplify sets of constraints (Goal). A Tactic can be converted into a Solver using the method solver(). Several combinators are available for creating new tactics using the built-in ones: Then(), OrElse(), FailIf(), Repeat(), When(), Cond(). NcCst||_d|_t|tr"||_nRtr8tt|tdzt|j t||_Wn t k rrt d|YnXt |j |jdS)Nztactic name expectedzunknown tactic '%s') r6r:tacticr TacticObjr r)rS Z3_mk_tacticr7r(Z3_tactic_inc_ref)rfrr:r r r rls  zTactic.__init__cCst|j|jSr)rkrr:rr r r rszTactic.__deepcopy__cCs.|jdk r*|jdk r*t|j|jdSr)rr:r7Z3_tactic_dec_refrnr r r roszTactic.__del__cCstt|j|j|j|S)aCreate a solver using the tactic `self`. The solver supports the methods `push()` and `pop()`, but it will always solve each `check()` from scratch. >>> t = Then('simplify', 'nlsat') >>> s = t.solver() >>> x = Real('x') >>> s.add(x**2 == 2, x > 0) >>> s.check() sat >>> s.model() [x = 1.4142135623?] )r Z3_mk_solver_from_tacticr:r7r)rfrr r r r sz Tactic.solvercOstrtt|ttfdt|}t|dks:t|dkrjt|||j}t t |j |j |j |j|jSt t|j |j |j |jSdS)zApply tactic `self` to the given goal or Z3 Boolean expression using the given options. >>> x, y = Ints('x y') >>> t = Tactic('solve-eqs') >>> t.apply(And(x == 0, y >= x + 1)) [[y >= 1]] z'Z3 Goal or Boolean expressions expectedrN)r r)r rlr2_to_goalrEr]r:rZ3_tactic_apply_exr7rrmrZ3_tactic_apply)rfrmr[r\rr r r rs"z Tactic.applycOs|j|f||S)zApply tactic `self` to the given goal or Z3 Boolean expression using the given options. >>> x, y = Ints('x y') >>> t = Tactic('solve-eqs') >>> t(And(x == 0, y >= x + 1)) [[y >= 1]] )r)rfrmr[r\r r r rszTactic.__call__cCstt|j|jdS)zYDisplay a string containing a description of the available options for the `self` tactic.N)rMZ3_tactic_get_helpr:r7rrnr r r rOsz Tactic.helpcCstt|j|j|jSrP)rWZ3_tactic_get_param_descrsr:r7rrnr r r rRszTactic.param_descrs)N)N) rsrtrurvrlrror rrrOrRr r r r rkys    rkcCs,t|tr$t|jd}|||S|SdS)Nrp)r r2rlr:r)rkrmr r r rs    rcCst|tr|St||SdSr)r rk)rr:r r r _to_tactics rcCsJt||}t||}tr,t|j|jkdtt|j|j|j|jSr)rr r)r:rkZ3_tactic_and_thenr7rt1t2r:r r r _and_thens   rcCsJt||}t||}tr,t|j|jkdtt|j|j|j|jSr)rr r)r:rkZ3_tactic_or_elser7rrr r r _or_elses   rcOs^trtt|dkd|dd}t|}|d}t|dD]}t|||d|}q@|S)aReturn a tactic that applies the tactics in `*ts` in sequence. >>> x, y = Ints('x y') >>> t = AndThen(Tactic('simplify'), Tactic('solve-eqs')) >>> t(And(x == 0, y > x + 1)) [[Not(y <= 1)]] >>> t(And(x == 0, y > x + 1)).as_expr() Not(y <= 1) r[rr:Nrr)r r)rEryrrtsksr:rrrr r r AndThens  rcOs t||S)a-Return a tactic that applies the tactics in `*ts` in sequence. Shorthand for AndThen(*ts, **ks). >>> x, y = Ints('x y') >>> t = Then(Tactic('simplify'), Tactic('solve-eqs')) >>> t(And(x == 0, y > x + 1)) [[Not(y <= 1)]] >>> t(And(x == 0, y > x + 1)).as_expr() Not(y <= 1) )r)rrr r r Thens rcOs^trtt|dkd|dd}t|}|d}t|dD]}t|||d|}q@|S)aZReturn a tactic that applies the tactics in `*ts` until one of them succeeds (it doesn't fail). >>> x = Int('x') >>> t = OrElse(Tactic('split-clause'), Tactic('skip')) >>> # Tactic split-clause fails if there is no clause in the given goal. >>> t(x == 0) [[x == 0]] >>> t(Or(x == 0, x == 1)) [[x == 0], [x == 1]] r[rr:Nrr)r r)rEryrrrr r r OrElse s  rcs~trtt|dkdt|ddfdd|D}t|}t|}t|D]}||j||<qTtt ||S)zReturn a tactic that applies the tactics in `*ts` in parallel until one of them succeeds (it doesn't fail). >>> x = Int('x') >>> t = ParOr(Tactic('simplify'), Tactic('fail')) >>> t(x + 1 == 2) [[x == 1]] r[rr:Ncsg|]}t|qSr )r)rBrrpr r rD, szParOr..) r r)rEr6ryrrrrkZ3_tactic_par_orr7)rrrrrr rpr ParOr! s  rcCsJt||}t||}tr,t|j|jkdtt|j|j|j|jS)a9Return a tactic that applies t1 and then t2 to every subgoal produced by t1. The subgoals are processed in parallel. >>> x, y = Ints('x y') >>> t = ParThen(Tactic('split-clause'), Tactic('propagate-values')) >>> t(And(Or(x == 1, x == 2), y == x + 1)) [[x == 1, y == 2], [x == 2, y == 3]] r)rr r)r:rkZ3_tactic_par_and_thenr7rrr r r ParThen4 s  rcCs t|||S)zAlias for ParThen(t1, t2, ctx).)rrr r r ParAndThenD srcOsB|dd}t||}t|||j}tt|j|j|j|jS)zReturn a tactic that applies tactic `t` using the given configuration options. >>> x, y = Ints('x y') >>> t = With(Tactic('simplify'), som=True) >>> t((x + 1)*(y + 2) == 0) [[2*x + y + x*y == -2]] r:N) rrr]r:rkZ3_tactic_using_paramsr7rr)rrLrr:rr r r WithI s  rcCs(t|d}tt|j|j|j|jS)a Return a tactic that applies tactic `t` using the given configuration options. >>> x, y = Ints('x y') >>> p = ParamsRef() >>> p.set("som", True) >>> t = WithParams(Tactic('simplify'), p) >>> t((x + 1)*(y + 2) == 0) [[2*x + y + x*y == -2]] N)rrkrr:r7rr)rrr r r WithParamsW s r cCs&t||}tt|j|j||jS)a)Return a tactic that keeps applying `t` until the goal is not modified anymore or the maximum number of iterations `max` is reached. >>> x, y = Ints('x y') >>> c = And(Or(x == 0, x == 1), Or(y == 0, y == 1), x > y) >>> t = Repeat(OrElse(Tactic('split-clause'), Tactic('skip'))) >>> r = t(c) >>> for subgoal in r: print(subgoal) [x == 0, y == 0, x > y] [x == 0, y == 1, x > y] [x == 1, y == 0, x > y] [x == 1, y == 1, x > y] >>> t = Then(t, Tactic('propagate-values')) >>> t(c) [[x == 1, y == 0]] )rrkZ3_tactic_repeatr:r7r)rmaxr:r r r Repeate s r cCs&t||}tt|j|j||jS)zReturn a tactic that applies `t` to a given goal for `ms` milliseconds. If `t` does not terminate in `ms` milliseconds, then it fails. )rrkZ3_tactic_try_forr:r7r)rmsr:r r r TryForz s rcs&tfddttDS)zsReturn a list of all available tactics in Z3. >>> l = tactics() >>> l.count('simplify') == 1 True csg|]}t|qSr )Z3_get_tactic_namer7r rpr r rD sztactics..)r6rZ3_get_num_tacticsr7rpr rpr tactics srcCst|}t||S)zhReturn a short description for the tactic named `name`. >>> d = tactic_description('simplify') )r6Z3_tactic_get_descrr7rr r r tactic_description srcCstr`d}tdtD]<}|r.tdd}n tdd}td|tt|dfqtdn tD]}td |t|fqfd S) z?Display a (tabular) description of all available tactics in Z3.TrrFrr(r%s : %sN)rrMrinsert_line_breaksr)rrr r r describe_tactics s   rc@sfeZdZdZdddZifddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ dS)rjzProbes are used to inspect a goal (aka problem) and collect information that may be used to decide which solver and/or preprocessing step will be used. NcCst||_d|_t|tr"||_nt|tr@t|j||_nt|r`t|jt||_nt|t r|rt|jd|_qt|jd|_nNt rt t|t dzt |j||_Wn tk rtd|YnXt|j|jdS)N?zprobe name expectedzunknown probe '%s')r6r:rr ZProbeObjrCZ3_probe_constr7rrRr r)rS Z3_mk_prober(Z3_probe_inc_ref)rfrr:r r r rl s&    zProbe.__init__cCst|j|jSr)rjrr:rr r r r szProbe.__deepcopy__cCs.|jdk r*|jdk r*t|j|jdSr)rr:r7Z3_probe_dec_refrnr r r ro sz Probe.__del__cCs&tt|j|jt||jj|jS)a*Return a probe that evaluates to "true" when the value returned by `self` is less than the value returned by `other`. >>> p = Probe('size') < 10 >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0) >>> g.add(x < 10) >>> p(g) 1.0 )rj Z3_probe_ltr:r7r _to_proberr r r r s z Probe.__lt__cCs&tt|j|jt||jj|jS)a-Return a probe that evaluates to "true" when the value returned by `self` is greater than the value returned by `other`. >>> p = Probe('size') > 10 >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0) >>> g.add(x < 10) >>> p(g) 0.0 )rj Z3_probe_gtr:r7rr!rr r r r s z Probe.__gt__cCs&tt|j|jt||jj|jS)a6Return a probe that evaluates to "true" when the value returned by `self` is less than or equal to the value returned by `other`. >>> p = Probe('size') <= 2 >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0) >>> g.add(x < 10) >>> p(g) 1.0 )rj Z3_probe_ler:r7rr!rr r r r  s z Probe.__le__cCs&tt|j|jt||jj|jS)a9Return a probe that evaluates to "true" when the value returned by `self` is greater than or equal to the value returned by `other`. >>> p = Probe('size') >= 2 >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0) >>> g.add(x < 10) >>> p(g) 1.0 )rj Z3_probe_ger:r7rr!rr r r r s z Probe.__ge__cCs&tt|j|jt||jj|jS)a)Return a probe that evaluates to "true" when the value returned by `self` is equal to the value returned by `other`. >>> p = Probe('size') == 2 >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0) >>> g.add(x < 10) >>> p(g) 1.0 )rj Z3_probe_eqr:r7rr!rr r r r!s z Probe.__eq__cCs$||}tt|j|j|jS)a-Return a probe that evaluates to "true" when the value returned by `self` is not equal to the value returned by `other`. >>> p = Probe('size') != 2 >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0) >>> g.add(x < 10) >>> p(g) 0.0 )rrjrr:r7r)rfrrr r r r!s z Probe.__ne__cCs8trtt|ttfdt|}t|j|j |j S)aEvaluate the probe `self` in the given goal. >>> p = Probe('size') >>> x = Int('x') >>> g = Goal() >>> g.add(x > 0) >>> g.add(x < 10) >>> p(g) 2.0 >>> g.add(x < 20) >>> p(g) 3.0 >>> p = Probe('num-consts') >>> p(g) 1.0 >>> p = Probe('is-propositional') >>> p(g) 0.0 >>> p = Probe('is-qflia') >>> p(g) 1.0 z&Z3 Goal or Boolean expression expected) r r)r rlr2rZ3_probe_applyr:r7rrm)rfrmr r r r"!szProbe.__call__)N)rsrtrurvrlrrorrr rrrrr r r r rj s  rjcCs t|tS)zyReturn `True` if `p` is a Z3 probe. >>> is_probe(Int('x')) False >>> is_probe(Probe('memory')) True )r rj)rr r r r?!srcCst|r |St||SdSr)rrjrr:r r r r!J!sr!cs&tfddttDS)zoReturn a list of all available probes in Z3. >>> l = probes() >>> l.count('memory') == 1 True csg|]}t|qSr )Z3_get_probe_namer7r rpr r rDY!szprobes..)r6rZ3_get_num_probesr7rpr rpr probesQ!sr*cCst|}t||S)zdReturn a short description for the probe named `name`. >>> d = probe_description('memory') )r6Z3_probe_get_descrr7rr r r probe_description\!sr,cCstr`d}tdtD]<}|r.tdd}n tdd}td|tt|dfqtdn tD]}td |t|fqfd S) z>Display a (tabular) description of all available probes in Z3.TrrFrrrrrN)rrMr*rr,)rrr r r describe_probese!s   r-c Csltrtt|dkdt|}t|d|}t|dD],}t|||jt||d|j|}q:|S)Nrrr)r r)rEr!rrjr7r)r%rLr:rrrr r r _probe_naryx!s*r.cCs tt||Sr)r. Z3_probe_andrLr:r r r r!srcCs tt||Sr)r. Z3_probe_orr0r r r r!srcCs$t||}tt|j|j|jS)aReturn a tactic that fails if the probe `p` evaluates to true. Otherwise, it returns the input goal unmodified. In the following example, the tactic applies 'simplify' if and only if there are more than 2 constraints in the goal. >>> t = OrElse(FailIf(Probe('size') > 2), Tactic('simplify')) >>> x, y = Ints('x y') >>> g = Goal() >>> g.add(x > 0) >>> g.add(y > 0) >>> t(g) [[x > 0, y > 0]] >>> g.add(x == y + 1) >>> t(g) [[Not(x <= 0), Not(y <= 0), x == 1 + y]] )r!rkZ3_tactic_fail_ifr:r7rr'r r r FailIf!s r3cCs2t||}t||}tt|j|j|j|jS)aReturn a tactic that applies tactic `t` only if probe `p` evaluates to true. Otherwise, it returns the input goal unmodified. >>> t = When(Probe('size') > 2, Tactic('simplify')) >>> x, y = Ints('x y') >>> g = Goal() >>> g.add(x > 0) >>> g.add(y > 0) >>> t(g) [[x > 0, y > 0]] >>> g.add(x == y + 1) >>> t(g) [[Not(x <= 0), Not(y <= 0), x == 1 + y]] )r!rrkZ3_tactic_whenr:r7rr)rrr:r r r When!s  r5cCs@t||}t||}t||}tt|j|j|j|j|jS)zReturn a tactic that applies tactic `t1` to a goal if probe `p` evaluates to true, and `t2` otherwise. >>> t = Cond(Probe('is-qfnra'), Tactic('qfnra'), Tactic('smt')) )r!rrkZ3_tactic_condr:r7rr)rrrr:r r r rl!s   rlcOsvtrtt|dt|dks,t|dkrXt|||j}tt|| |j |jStt || |jSdS)aSimplify the expression `a` using the given options. This function has many options. Use `help_simplify` to obtain the complete list. >>> x = Int('x') >>> y = Int('y') >>> simplify(x + 1 + y + x + 1) 2 + 2*x + y >>> simplify((x + 1)*(y + 1), som=True) 1 + x + y + x*y >>> simplify(Distinct(x, y, 1), blast_distinct=True) And(Not(x == y), Not(x == 1), Not(y == 1)) >>> simplify(And(x == 0, y == 1), elim_and=True) Not(Or(Not(x == 0), Not(y == 1))) rrN) r r)rrEr]r:rZ3_simplify_exrrr Z3_simplify)rkr[r\rr r r rK!s rKcCstttdS)zMReturn a string describing all options available for Z3 `simplify` procedure.N)rMZ3_simplify_get_helprxr7r r r r help_simplify!sr:cCsttttS)zEReturn the set of parameter descriptions for Z3 `simplify` procedure.)rWZ3_simplify_get_param_descrsrxr7r r r r simplify_param_descrs!sr<cGst|tr2t|}t|tr2tdd|Dr2|}tr^tt|dttdd|Ddt|}t |}t |}t |D],}||d ||<||d ||<qt t |j| ||||jS) abApply substitution m on t, m is a list of pairs of the form (from, to). Every occurrence in t of from is replaced with to. >>> x = Int('x') >>> y = Int('y') >>> substitute(x + 1, (x, y + 1)) y + 1 + 1 >>> f = Function('f', IntSort(), IntSort()) >>> substitute(f(x) + f(y), (f(x), IntVal(1)), (f(y), IntVal(1))) 1 + 1 css|]}t|tVqdSr)r rFrr r r !szsubstitute..rcSsHg|]@}t|toBt|doBt|doB|d|dqS)rr)r rFrrrrr r r rD!s. zsubstitute..z3Z3 invalid substitution, expression pairs expected.rr)r rFrMrGrr r)rrErrrr Z3_substituter:r7)rrm1rZ_from_torr r r substitute!s$     rAcGs|tr,tt|dttdd|Ddt|}t|}t|D]}||||<qFtt |j ||||j S)a;Substitute the free variables in t with the expression in m. >>> v0 = Var(0, IntSort()) >>> v1 = Var(1, IntSort()) >>> x = Int('x') >>> f = Function('f', IntSort(), IntSort(), IntSort()) >>> # replace v0 with x+1 and v1 with x >>> substitute_vars(f(v0, v1), x + 1, x) f(x + 1, x) rcSsg|] }t|qSr r)rBr+r r r rD"sz#substitute_vars..z6Z3 invalid substitution, list of expressions expected.) r r)rrrErrrrZ3_substitute_varsr:r7)rrrr@rr r r substitute_vars"s   rCcGst|}t|dkrdSt|}|dkr8tdd|dSt||}t|dr^tdd|dSt|\}}tt| |||SdS)zCreate the sum of the Z3 expressions. >>> a, b, c = Ints('a b c') >>> Sum(a, b, c) a + b + c >>> Sum([a, b, c]) a + b + c >>> A = IntVector('a', 5) >>> Sum(A) a__0 + a__1 + a__2 + a__3 + a__4 rNcSs||Srr rr r r +"zSum..cSs||Srr rr r r rD."rE) rMrErr`rcrrrDrr7rqr r r Sum"s     rFcGst|}t|dkrdSt|}|dkr8tdd|dSt||}t|dr^tdd|dSt|\}}tt| |||SdS)zCreate the product of the Z3 expressions. >>> a, b, c = Ints('a b c') >>> Product(a, b, c) a*b*c >>> Product([a, b, c]) a*b*c >>> A = IntVector('a', 5) >>> Product(A) a__0*a__1*a__2*a__3*a__4 rrNcSs||Srr rr r r rDE"rEzProduct..cSs||Srr rr r r rDH"rE) rMrErr`rcrrrDrr7rqr r r Product4"s     rGcGszt|}tr tt|dkdt|}tr>> a, b, c = Bools('a b c') >>> f = AtMost(a, b, c, 2) r$Non empty list of arguments expectedNrp) rMr r)rErrcrr2 Z3_mk_atmostr7rLr:Zargs1r{rrr r r AtMostN"s rLcGszt|}tr tt|dkdt|}tr>> a, b, c = Bools('a b c') >>> f = AtLeast(a, b, c, 2) rrHNrprI) rMr r)rErrcrr2 Z3_mk_atleastr7rKr r r AtLeast`"s rNcCs$|\}}t|s t|r ||fS|Sr)r)rCrkrr r r _reorder_pb_argr"srOcCst|}t|dkr2t|dtdtjdfSdd|D}t|\}}trdtt|dkdt |}trt|dk dt ||}t |\}}tjt|}t t|D]}t ||d||||<q||||fS)NrcSsg|] }t|qSr )rOrAr r r rD}"sz#_pb_args_coeffs..rHrpZ coefficient)rOrEr6rrr*zipr r)rrcrrr-)rLrZcoeffsr:rr_coeffsrr r r _pb_args_coeffsy"s"    rRcCs4t|dt|\}}}}tt||||||S)zCreate a Pseudo-Boolean inequality k constraint. >>> a, b, c = Bools('a b c') >>> f = PbLe(((a,1),(b,3),(c,2)), 3) r{)r-rRr2 Z3_mk_pbler7rLr{r:rrrQr r r PbLe"s rUcCs4t|dt|\}}}}tt||||||S)zCreate a Pseudo-Boolean inequality k constraint. >>> a, b, c = Bools('a b c') >>> f = PbGe(((a,1),(b,3),(c,2)), 3) r{)r-rRr2 Z3_mk_pbger7rTr r r PbGe"s rWcCs4t|dt|\}}}}tt||||||S)zCreate a Pseudo-Boolean inequality k constraint. >>> a, b, c = Bools('a b c') >>> f = PbEq(((a,1),(b,3),(c,2)), 3) r{)r-rRr2 Z3_mk_pbeqr7rTr r r PbEq"s rYcOs|dd}t}|jf||j||r4t||}|tkrNtdnF|tkrtdzt|Wqt k rYdSXn t|dS)aSolve the constraints `*args`. This is a simple function for creating demonstrations. It creates a solver, configure it using the options in `keywords`, adds the constraints in `args`, and invokes check. >>> a = Int('a') >>> solve(a > 0, a < 2) [a = 1] showF no solutionfailed to solveN rr rHrrMr&rrrr(rLr\rZr3rr r r solve"s     r_cOs|dd}tr"tt|td|jf||j||rLtdt||}|t krftdnR|t krtdzt| Wqt k rYdSXn|rtdt| dS) a%Solve the constraints `*args` using solver `s`. This is a simple function for creating demonstrations. It is similar to `solve`, but it uses the given solver `s`. It configures solver `s` using the options in `keywords`, adds the constraints in `args`, and invokes check. rZFSolver object expectedzProblem:r[r\Nz Solution: rr r)r r rHrrMr&rrrr(r3rLr\rZrr r r solve_using"s(     rccKstrtt|dt}|jf||t||r@t||}|t krZtdn2|t krxtdt| ntdt| dS)aTry to prove the given claim. This is a simple function for creating demonstrations. It tries to prove `claim` by showing the negation is unsatisfiable. >>> p, q = Bools('p q') >>> prove(Not(And(p, q)) == Or(Not(p), Not(q))) proved Z3 Boolean expression expectedZprovedzfailed to proveZcounterexampleN r r)rr rHrrrMr&rrrZclaimrZr\r3rr r r prove"s   rgcOs|dd}t}|jf||j||rProblem:no solutionfailed to solveNSolution:r]r^r r r _solve_html#s&     rlcOs|dd}tr"tt|td|jf||j||rLtdt||}|t krftdnR|t krtdzt| Wqt k rYdSXn|rtdt| dS) z3Version of function `solve_using` used in RiSE4Fun.rZFr`rhrirjNrkrarbr r r _solve_using_html#s(     rmcKstrtt|dt}|jf||t||r@t||}|t krZtdn2|t krxtdt| ntdt| dS)z-Version of function `prove` used in RiSE4Fun.rdz provedzfailed to provezcounterexampleNrerfr r r _prove_html8#s  rncCst|}t|}t|}d}|D]P}||}trTtt|tdtt|dt||||<|j ||<|d}q$|||fS)Nrrrr) rEr.rr r)r rSrr;r)r>r:r_namesZ_sortsrr{rr r r _dict2sarrayL#s    rpcCst|}t|}t|}d}|D]p}||}tr\tt|tdtt|pVt|dt ||||<t|r| j ||<n |j ||<|d}q$|||fS)Nrrz#Z3 declaration or constant expectedr) rEr.rr r)r rSrrer;r6r)rr:rrorrrr{rr r r _dict2darray\#s    rqc CsHt|}t||\}}}t||\}}} tt|||||||| |S)a\Parse a string in SMT 2.0 format using the given sorts and decls. The arguments sorts and decls are Python dictionaries used to initialize the symbol table used for the SMT 2.0 parser. >>> parse_smt2_string('(declare-const x Int) (assert (> x 0)) (assert (< x 10))') [x > 0, x < 10] >>> x, y = Ints('x y') >>> f = Function('f', IntSort(), IntSort()) >>> parse_smt2_string('(assert (> (+ foo (g bar)) 0))', decls={ 'foo' : x, 'bar' : y, 'g' : f}) [x + f(y) > 0] >>> parse_smt2_string('(declare-const a U) (assert (> a 0))', sorts={ 'U' : IntSort() }) [a > 0] )r6rprqrIZ3_parse_smtlib2_stringr7) r3r>rr:sszsnamesssortsdszdnamesddeclsr r r parse_smt2_stringo#sryc CsHt|}t||\}}}t||\}}} tt|||||||| |S)zzParse a file in SMT 2.0 format using the given sorts and decls. This function is similar to parse_smt2_string(). )r6rprqrIZ3_parse_smtlib2_filer7) r%r>rr:rsrtrurvrwrxr r r parse_smt2_file#sr{ 5cCsTttkrt|Sttkr t|Sttkr0t|Sttkr@t|Stt krPt |SdS)z+Retrieves the global default rounding mode.N) _dflt_rounding_modeZ3_OP_FPA_RM_TOWARD_ZERORTZZ3_OP_FPA_RM_TOWARD_NEGATIVERTNZ3_OP_FPA_RM_TOWARD_POSITIVERTP!Z3_OP_FPA_RM_NEAREST_TIES_TO_EVENRNE!Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAYRNArpr r r get_default_rounding_mode#srcCs,t|r|antttkd|adS)Nzillegal rounding mode) is_fprm_valuer6rr~r)_ROUNDING_MODES)rmr:r r r set_default_rounding_mode#srcCs ttt|Sr)FPSort_dflt_fpsort_ebits_dflt_fpsort_sbitsrpr r r get_default_fp_sort#srcCs |a|adSr)rrebitssbitsr:r r r set_default_fp_sort#srcCst|Sr)rrpr r r _dflt_rm#srcCst|Sr)rrpr r r _dflt_fps#srcCsd}|D]4}t|r|dkr&|}q||kr4qd}q>qg}tt|D]d}||}t|tov|dov|d}|st|st|t t fr| t |d||qN| |qNt ||S)Nz2**())is_fprrrEr rScontainsendswithrrCrRrFPValrc)rbr:Z first_fp_sortrkrrZis_reprr r r _coerce_fp_expr_list#s"   rc@s(eZdZdZddZddZddZdS) rzFloating-point sort.cCstt||jS)zRetrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`. >>> b = FPSort(8, 24) >>> b.ebits() 8 )rZ3_fpa_get_ebitsrrrnr r r r#szFPSortRef.ebitscCstt||jS)zRetrieves the number of bits reserved for the significand in the FloatingPoint sort `self`. >>> b = FPSort(8, 24) >>> b.sbits() 24 )rZ3_fpa_get_sbitsrrrnr r r r#szFPSortRef.sbitscCs8t|r$tr t|j|jkd|St|d||jSdS)zTry to cast `val` as a floating-point expression. >>> b = FPSort(8, 24) >>> b.cast(1.0) 1 >>> b.cast(1.0).sexpr() '(fp #b0 #x7f #b00000000000000000000000)' rN)rr r)r:rrr r r r#s zFPSortRef.castN)rsrtrurvrrrr r r r r#srcCst|}tt||Sz"Floating-point 16-bit (half) sort.)r6rZ3_mk_fpa_sort_16r7rpr r r Float16$srcCst|}tt||Sr)r6rZ3_mk_fpa_sort_halfr7rpr r r FloatHalf$srcCst|}tt||Sz$Floating-point 32-bit (single) sort.)r6rZ3_mk_fpa_sort_32r7rpr r r Float32$srcCst|}tt||Sr)r6rZ3_mk_fpa_sort_singler7rpr r r FloatSingle $srcCst|}tt||Sz$Floating-point 64-bit (double) sort.)r6rZ3_mk_fpa_sort_64r7rpr r r Float64&$srcCst|}tt||Sr)r6rZ3_mk_fpa_sort_doubler7rpr r r FloatDouble,$srcCst|}tt||Sz(Floating-point 128-bit (quadruple) sort.)r6rZ3_mk_fpa_sort_128r7rpr r r Float1282$srcCst|}tt||Sr)r6rZ3_mk_fpa_sort_quadrupler7rpr r r FloatQuadruple8$src@seZdZdZdS)rz#"Floating-point rounding mode sort.N)rsrtrurvr r r r r>$srcCs t|tS)zReturn True if `s` is a Z3 floating-point sort. >>> is_fp_sort(FPSort(8, 24)) True >>> is_fp_sort(IntSort()) False )r rr2r r r is_fp_sortB$srcCs t|tS)zReturn True if `s` is a Z3 floating-point rounding mode sort. >>> is_fprm_sort(FPSort(8, 24)) False >>> is_fprm_sort(RNE().sort()) True )r rr2r r r is_fprm_sortM$src@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.S)/rOzFloating-point expressions.cCstt|||jS)zReturn the sort of the floating-point expression `self`. >>> x = FP('1.0', FPSort(8, 24)) >>> x.sort() FPSort(8, 24) >>> x.sort() == FPSort(8, 24) True )rrrrr:rnr r r r]$s z FPRef.sortcCs |S)zRetrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`. >>> b = FPSort(8, 24) >>> b.ebits() 8 )rrrnr r r rh$sz FPRef.ebitscCs |S)zRetrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`. >>> b = FPSort(8, 24) >>> b.sbits() 24 )rrrnr r r rp$sz FPRef.sbitscCst||Srrrnr r r r'x$szFPRef.as_stringcCst|||jSr)fpLEQr:rr r r r |$sz FPRef.__le__cCst|||jSr)fpLTr:rr r r r$sz FPRef.__lt__cCst|||jSr)fpGEQr:rr r r r$sz FPRef.__ge__cCst|||jSr)fpGTr:rr r r r$sz FPRef.__gt__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `self + other`. >>> x = FP('x', FPSort(8, 24)) >>> y = FP('y', FPSort(8, 24)) >>> x + y x + y >>> (x + y).sort() FPSort(8, 24) rr:fpAddrr4r r r r$s z FPRef.__add__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `other + self`. >>> x = FP('x', FPSort(8, 24)) >>> 10 + x 1.25*(2**3) + x rr4r r r r$szFPRef.__radd__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `self - other`. >>> x = FP('x', FPSort(8, 24)) >>> y = FP('y', FPSort(8, 24)) >>> x - y x - y >>> (x - y).sort() FPSort(8, 24) rr:fpSubrr4r r r r$s z FPRef.__sub__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `other - self`. >>> x = FP('x', FPSort(8, 24)) >>> 10 - x 1.25*(2**3) - x rr4r r r r$szFPRef.__rsub__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `self * other`. >>> x = FP('x', FPSort(8, 24)) >>> y = FP('y', FPSort(8, 24)) >>> x * y x * y >>> (x * y).sort() FPSort(8, 24) >>> 10 * y 1.25*(2**3) * y rr:fpMulrr4r r r r$s z FPRef.__mul__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `other * self`. >>> x = FP('x', FPSort(8, 24)) >>> y = FP('y', FPSort(8, 24)) >>> x * y x * y >>> x * 10 x * 1.25*(2**3) rr4r r r r$s zFPRef.__rmul__cCs|S)z!Create the Z3 expression `+self`.r rnr r r r $sz FPRef.__pos__cCst|S)zhCreate the Z3 expression `-self`. >>> x = FP('x', Float32()) >>> -x -x )fpNegrnr r r r $sz FPRef.__neg__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `self / other`. >>> x = FP('x', FPSort(8, 24)) >>> y = FP('y', FPSort(8, 24)) >>> x / y x / y >>> (x / y).sort() FPSort(8, 24) >>> 10 / y 1.25*(2**3) / y rr:fpDivrr4r r r r$s z FPRef.__div__cCs&t||g|j\}}tt|||jS)zCreate the Z3 expression `other / self`. >>> x = FP('x', FPSort(8, 24)) >>> y = FP('y', FPSort(8, 24)) >>> x / y x / y >>> x / 10 x / 1.25*(2**3) rr4r r r r$s zFPRef.__rdiv__cCs ||S)z1Create the Z3 expression division `self / other`.rrr r r r$szFPRef.__truediv__cCs ||S)z1Create the Z3 expression division `other / self`.rrr r r r$szFPRef.__rtruediv__cCs t||S)z,Create the Z3 expression mod `self % other`.fpRemrr r r r%sz FPRef.__mod__cCs t||S)z,Create the Z3 expression mod `other % self`.rrr r r r%szFPRef.__rmod__N)rsrtrurvrrrr'r rrrrrrrrrr r rrrrrrr r r r rOZ$s.        rOc@seZdZdZddZdS)rRz(Floating-point rounding mode expressionscCst||Srrrnr r r r'%szFPRMRef.as_stringN)rsrtrurvr'r r r r rR %srRcCst|}tt||Srr6rR$Z3_mk_fpa_round_nearest_ties_to_evenr7rpr r r RoundNearestTiesToEven%srcCst|}tt||Srrrpr r r r%srcCst|}tt||Srr6rR$Z3_mk_fpa_round_nearest_ties_to_awayr7rpr r r RoundNearestTiesToAway%srcCst|}tt||Srrrpr r r r#%srcCst|}tt||Srr6rRZ3_mk_fpa_round_toward_positiver7rpr r r RoundTowardPositive(%srcCst|}tt||Srrrpr r r r-%srcCst|}tt||Srr6rRZ3_mk_fpa_round_toward_negativer7rpr r r RoundTowardNegative2%srcCst|}tt||Srrrpr r r r7%srcCst|}tt||Srr6rRZ3_mk_fpa_round_toward_zeror7rpr r r RoundTowardZero<%srcCst|}tt||Srrrpr r r rA%srcCs t|tS)zReturn `True` if `a` is a Z3 floating-point rounding mode expression. >>> rm = RNE() >>> is_fprm(rm) True >>> rm = 1.0 >>> is_fprm(rm) False )r rRrr r r is_fprmF%s rcCst|ot|j|jS)zHReturn `True` if `a` is a Z3 floating-point rounding mode numeral value.)rrMr:rrr r r rS%src@seZdZdZddZddZddZdd Zd d Zd$d dZ d%ddZ d&ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#S)'rNzThe sign of the numeral. >>> x = FPVal(+1.0, FPSort(8, 24)) >>> x.sign() False >>> x = FPVal(-1.0, FPSort(8, 24)) >>> x.sign() True cCs<t}t|j|tt}|dkr2td|j dkS)NFz'error retrieving the sign of a numeral.r) rr*Z3_fpa_get_numeral_signr:r7rbyreflr(r)rfrZnsignr r r signe%s z FPNumRef.signcCstt|j||jSr)rHZ3_fpa_get_numeral_sign_bvr:r7rrnr r r sign_as_bvq%szFPNumRef.sign_as_bvcCst|j|Sr)%Z3_fpa_get_numeral_significand_stringr:r7rrnr r r significand{%szFPNumRef.significandcCs2tjd}t|j||s*td|dS)Nrz.error retrieving the significand of a numeral.r)rr%Z3_fpa_get_numeral_significand_uint64r:r7rr()rfrr r r significand_as_long%s zFPNumRef.significand_as_longcCstt|j||jSr)rH!Z3_fpa_get_numeral_significand_bvr:r7rrnr r r significand_as_bv%szFPNumRef.significand_as_bvTcCst|j||Sr)"Z3_fpa_get_numeral_exponent_stringr:r7rrfbiasedr r r exponent%szFPNumRef.exponentcCs4tjd}t|j|||s,td|dS)Nrz+error retrieving the exponent of a numeral.r)rZ c_longlong!Z3_fpa_get_numeral_exponent_int64r:r7rr()rfrrr r r exponent_as_long%s zFPNumRef.exponent_as_longcCstt|j|||jSr)rHZ3_fpa_get_numeral_exponent_bvr:r7rrr r r exponent_as_bv%szFPNumRef.exponent_as_bvcCst|j|Sr)Z3_fpa_is_numeral_nanr:r7rrnr r r isNaN%szFPNumRef.isNaNcCst|j|Sr)Z3_fpa_is_numeral_infr:r7rrnr r r isInf%szFPNumRef.isInfcCst|j|Sr)Z3_fpa_is_numeral_zeror:r7rrnr r r isZero%szFPNumRef.isZerocCst|j|Sr)Z3_fpa_is_numeral_normalr:r7rrnr r r isNormal%szFPNumRef.isNormalcCst|j|Sr)Z3_fpa_is_numeral_subnormalr:r7rrnr r r isSubnormal%szFPNumRef.isSubnormalcCst|j|Sr)Z3_fpa_is_numeral_positiver:r7rrnr r r isPositive%szFPNumRef.isPositivecCst|j|Sr)Z3_fpa_is_numeral_negativer:r7rrnr r r isNegative%szFPNumRef.isNegativecCs$t|j|}d||fS)Nz FPVal(%s, %s))r*r:r7rrrr r r r'%szFPNumRef.as_stringN)T)T)T)rsrtrurvrrrrrrrrrrrrrrrr'r r r r rNZ%s"       rNcCs t|tS)zReturn `True` if `a` is a Z3 floating-point expression. >>> b = FP('b', FPSort(8, 24)) >>> is_fp(b) True >>> is_fp(b + 1.0) True >>> is_fp(Int('x')) False )r rOrr r r r%s rcCst|ot|j|jS)zReturn `True` if `a` is a Z3 floating-point numeral value. >>> b = FP('b', FPSort(8, 24)) >>> is_fp_value(b) False >>> b = FPVal(1.0, FPSort(8, 24)) >>> b 1 >>> is_fp_value(b) True )rrMr:rrr r r is_fp_value%s rcCst|}tt||||S)aReturn a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used. >>> Single = FPSort(8, 24) >>> Double = FPSort(11, 53) >>> Single FPSort(8, 24) >>> x = Const('x', Single) >>> eq(x, FP('x', FPSort(8, 24))) True )r6rZ3_mk_fpa_sortr7rr r r r%s rc Csjt|trt|rd}n|dkr@td|}|dkr:dSdSn`|tdkrRd}nN|tdkrdd }n<|}|d }|d }t|d t|}|d t|}nt|tr|rd}nd}nt |rt|}n~t|tr:| d}|dkr|}nF|ddkr.|d |}tt ||ddt |}n t ddnt rLt dd|d krZ|S|d |SdS)NNaNrr-0.0+0.0+inf+oo-inf-oorr/rz1.00.0z*(2**rIrFz1String does not have floating-point numeral form.z>Python value cannot be used to create floating-point numerals.)r rCmathisnancopysignas_integer_ratiorSrIrRrfindrr)r ) rUexprZsonerrZdenZrvsZinxr r r _to_float_str&sH          "   r cCs(tt|tdtt||j|jS)zCreate a Z3 floating-point NaN term. >>> s = FPSort(8, 24) >>> set_fpa_pretty(True) >>> fpNaN(s) NaN >>> pb = get_fpa_pretty() >>> set_fpa_pretty(False) >>> fpNaN(s) fpNaN(FPSort(8, 24)) >>> set_fpa_pretty(pb) rW)r)r rrN Z3_mk_fpa_nanrrr:r2r r r fpNaN:&s r cCs*tt|tdtt||jd|jS)aCreate a Z3 floating-point +oo term. >>> s = FPSort(8, 24) >>> pb = get_fpa_pretty() >>> set_fpa_pretty(True) >>> fpPlusInfinity(s) +oo >>> set_fpa_pretty(False) >>> fpPlusInfinity(s) fpPlusInfinity(FPSort(8, 24)) >>> set_fpa_pretty(pb) rWFr)r rrN Z3_mk_fpa_infrrr:r2r r r fpPlusInfinityK&s rcCs*tt|tdtt||jd|jS)z$Create a Z3 floating-point -oo term.rWTr r2r r r fpMinusInfinity\&srcCs:tt|tdtt|tdtt||j||jS)z+Create a Z3 floating-point +oo or -oo term.rWexpected Boolean flag) r)r rrRrNr rrr:r3negativer r r fpInfinityb&srcCs*tt|tdtt||jd|jS)z%Create a Z3 floating-point +0.0 term.rWFr)r rrNZ3_mk_fpa_zerorrr:r2r r r fpPlusZeroi&srcCs*tt|tdtt||jd|jS)z%Create a Z3 floating-point -0.0 term.rWTrr2r r r fpMinusZeroo&srcCs:tt|tdtt|tdtt||j||jS)z-Create a Z3 floating-point +0.0 or -0.0 term.rWr) r)r rrRrNrrrr:rr r r fpZerou&srcCst|}t|r|}d}n|dkr*t|}tt|d|dkrDd}t|}|dks\|dkrdt|S|dkrtt|S|dks|dkrt|S|d ks|d ks|d krt|S|d ks|d ks|dkrt |St t | ||j |SdS)aReturn a floating-point value of value `val` and sort `fps`. If `ctx=None`, then the global context is used. >>> v = FPVal(20.0, FPSort(8, 24)) >>> v 1.25*(2**4) >>> print("0x%.8x" % v.exponent_as_long(False)) 0x00000004 >>> v = FPVal(2.25, FPSort(8, 24)) >>> v 1.125*(2**1) >>> v = FPVal(-2.25, FPSort(8, 24)) >>> v -1.125*(2**1) >>> FPVal(-0.0, FPSort(8, 24)) -0.0 >>> FPVal(0.0, FPSort(8, 24)) +0.0 >>> FPVal(+0.0, FPSort(8, 24)) +0.0 NrWrrnanrrrrrz+Infrrz-Inf)r6rrr)r r rrrrrNrJr7r)r!rZfpsr:rUr r r r|&s*rcCs@t|tr|dkr|j}nt|}tt|t|||j|S)a]Return a floating-point constant named `name`. `fpsort` is the floating-point sort. If `ctx=None`, then the global context is used. >>> x = FP('x', FPSort(8, 24)) >>> is_fp(x) True >>> x.ebits() 8 >>> x.sort() FPSort(8, 24) >>> word = FPSort(8, 24) >>> x2 = FP('x', word) >>> eq(x, x2) True N) r rr:r6rOrtr7r;r)r,fpsortr:r r r FP&srcs0tt|tr|d}fdd|DS)aReturn an array of floating-point constants. >>> x, y, z = FPs('x y z', FPSort(8, 24)) >>> x.sort() FPSort(8, 24) >>> x.sbits() 24 >>> x.ebits() 8 >>> fpMul(RNE(), fpAdd(RNE(), x, y), z) fpMul(RNE(), fpAdd(RNE(), x, y), z) rvcsg|]}t|qSr )rrwr:rr r rD&szFPs..r)rzrr:r rr FPs&s   rcCs.t|}t|g|\}tt|||S)a^Create a Z3 floating-point absolute value expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FPVal(1.0, s) >>> fpAbs(x) fpAbs(1) >>> y = FPVal(-20.0, s) >>> y -1.25*(2**4) >>> fpAbs(y) fpAbs(-1.25*(2**4)) >>> fpAbs(-1.25*(2**4)) fpAbs(-1.25*(2**4)) >>> fpAbs(x).sort() FPSort(8, 24) )r6rrO Z3_mk_fpa_absr7rr)r r r fpAbs&srcCs.t|}t|g|\}tt|||S)zCreate a Z3 floating-point addition expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FP('x', s) >>> fpNeg(x) -x >>> fpNeg(x).sort() FPSort(8, 24) )r6rrO Z3_mk_fpa_negr7rr)r r r r&s rcCsVt|}t|g|\}tr8tt|dtt|dt|||||S)NCFirst argument must be a Z3 floating-point rounding mode expression6Second argument must be a Z3 floating-point expression r6rr r)rrrOr7r)r%rrkr:r r r _mk_fp_unary&s r$cCsBt|}t|g|\}tr*tt|dt||||S)N5First argument must be a Z3 floating-point expressionr6rr r)rr2r7r)r%rkr:r r r _mk_fp_unary_pred's r'cCsht|}t||g|\}}trDtt|dtt|p>t|dt||||||S)Nr!z?Second or third argument must be a Z3 floating-point expressionr#)r%rrkrr:r r r _mk_fp_bin 's r(cCsTt|}t||g|\}}tr6tt|p0t|dt|||||SNz?First or second argument must be a Z3 floating-point expression)r6rr r)rrOr7rr%rkrr:r r r _mk_fp_bin_norm's r+cCsTt|}t||g|\}}tr6tt|p0t|dt|||||Sr)r&r*r r r _mk_fp_bin_pred's r,cCszt|}t|||g|\}}}trPtt|dtt|pJt|pJt|dt|||||||S)Nr!zGSecond, third or fourth argument must be a Z3 floating-point expressionr#)r%rrkrrWr:r r r _mk_fp_tern&'sr-cCstt||||S)a4Create a Z3 floating-point addition expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) >>> fpAdd(rm, x, y) fpAdd(RNE(), x, y) >>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ x + y >>> fpAdd(rm, x, y).sort() FPSort(8, 24) )r( Z3_mk_fpa_addrrkrr:r r r r0'srcCstt||||S)zCreate a Z3 floating-point subtraction expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) >>> fpSub(rm, x, y) fpSub(RNE(), x, y) >>> fpSub(rm, x, y).sort() FPSort(8, 24) )r( Z3_mk_fpa_subr/r r r rA's rcCstt||||S)zCreate a Z3 floating-point multiplication expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) >>> fpMul(rm, x, y) fpMul(RNE(), x, y) >>> fpMul(rm, x, y).sort() FPSort(8, 24) )r( Z3_mk_fpa_mulr/r r r rP's rcCstt||||S)zCreate a Z3 floating-point division expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) >>> fpDiv(rm, x, y) fpDiv(RNE(), x, y) >>> fpDiv(rm, x, y).sort() FPSort(8, 24) )r( Z3_mk_fpa_divr/r r r r_'s rcCstt|||S)zCreate a Z3 floating-point remainder expression. >>> s = FPSort(8, 24) >>> x = FP('x', s) >>> y = FP('y', s) >>> fpRem(x, y) fpRem(x, y) >>> fpRem(x, y).sort() FPSort(8, 24) )r+ Z3_mk_fpa_remrLr r r rn's rcCstt|||S)zCreate a Z3 floating-point minimum expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) >>> fpMin(x, y) fpMin(x, y) >>> fpMin(x, y).sort() FPSort(8, 24) )r+ Z3_mk_fpa_minrLr r r fpMin|'s r5cCstt|||S)zCreate a Z3 floating-point maximum expression. >>> s = FPSort(8, 24) >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) >>> fpMax(x, y) fpMax(x, y) >>> fpMax(x, y).sort() FPSort(8, 24) )r+ Z3_mk_fpa_maxrLr r r fpMax's r7cCstt|||||S)z>Create a Z3 floating-point fused multiply-add expression. )r- Z3_mk_fpa_fma)rrkrrWr:r r r fpFMA'sr9cCstt|||S)z7Create a Z3 floating-point square root expression. )r$Z3_mk_fpa_sqrtrrkr:r r r fpSqrt'sr<cCstt|||S)z;Create a Z3 floating-point roundToIntegral expression. )r$Z3_mk_fpa_round_to_integralr;r r r fpRoundToIntegral'sr>cCs tt||S)zCreate a Z3 floating-point isNaN expression. >>> s = FPSort(8, 24) >>> x = FP('x', s) >>> y = FP('y', s) >>> fpIsNaN(x) fpIsNaN(x) )r'Z3_mk_fpa_is_nanr)r r r fpIsNaN's r@cCs tt||S)zCreate a Z3 floating-point isInfinite expression. >>> s = FPSort(8, 24) >>> x = FP('x', s) >>> fpIsInf(x) fpIsInf(x) )r'Z3_mk_fpa_is_infiniter)r r r fpIsInf'srBcCs tt||S)z2Create a Z3 floating-point isZero expression. )r'Z3_mk_fpa_is_zeror)r r r fpIsZero'srDcCs tt||S)z4Create a Z3 floating-point isNormal expression. )r'Z3_mk_fpa_is_normalr)r r r fpIsNormal'srFcCs tt||S)z7Create a Z3 floating-point isSubnormal expression. )r'Z3_mk_fpa_is_subnormalr)r r r fpIsSubnormal'srHcCs tt||S)z6Create a Z3 floating-point isNegative expression. )r'Z3_mk_fpa_is_negativer)r r r fpIsNegative'srJcCs tt||S)z6Create a Z3 floating-point isPositive expression. )r'Z3_mk_fpa_is_positiver)r r r fpIsPositive'srLcCs trtt|pt|ddSr))r r)rrr r r _check_fp_args'srMcCstt|||S)zCreate the Z3 floating-point expression `other < self`. >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpLT(x, y) x < y >>> (x < y).sexpr() '(fp.lt x y)' )r, Z3_mk_fpa_ltrLr r r r's rcCstt|||S)zCreate the Z3 floating-point expression `other <= self`. >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpLEQ(x, y) x <= y >>> (x <= y).sexpr() '(fp.leq x y)' )r, Z3_mk_fpa_leqrLr r r r's rcCstt|||S)zCreate the Z3 floating-point expression `other > self`. >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpGT(x, y) x > y >>> (x > y).sexpr() '(fp.gt x y)' )r, Z3_mk_fpa_gtrLr r r r's rcCstt|||S)zCreate the Z3 floating-point expression `other >= self`. >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpGEQ(x, y) x >= y >>> (x >= y).sexpr() '(fp.geq x y)' )r, Z3_mk_fpa_geqrLr r r r (s rcCstt|||S)zCreate the Z3 floating-point expression `fpEQ(other, self)`. >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpEQ(x, y) fpEQ(x, y) >>> fpEQ(x, y).sexpr() '(fp.eq x y)' )r, Z3_mk_fpa_eqrLr r r fpEQ(s rScCstt|||S)zCreate the Z3 floating-point expression `Not(fpEQ(other, self))`. >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpNEQ(x, y) Not(fpEQ(x, y)) >>> (x != y).sexpr() '(distinct x y)' )rrSrLr r r fpNEQ"(s rTcCstt|ot|ot|dt|dkdt|}t||jko`|jko`|jkndtt||j |j |j |S)aCreate the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectors sgn, sig, and exp. >>> s = FPSort(8, 24) >>> x = fpFP(BitVecVal(1, 1), BitVecVal(2**7-1, 8), BitVecVal(2**22, 23)) >>> print(x) fpFP(1, 127, 4194304) >>> xv = FPVal(-1.5, s) >>> print(xv) -1.5 >>> slvr = Solver() >>> slvr.add(fpEQ(x, xv)) >>> slvr.check() sat >>> xv = FPVal(+1.5, s) >>> print(xv) 1.5 >>> slvr = Solver() >>> slvr.add(fpEQ(x, xv)) >>> slvr.check() unsat rWrrV) r)rrrfr6r:rO Z3_mk_fpa_fpr7r)Zsgnrr!r:r r r fpFP.(s .rVcCst|}t|r2t|r2tt||j|j|St|rht|rht|rhtt ||j|j|j|St|rt |rt|rtt ||j|j|j|St|rt|rt|rtt ||j|j|j|St ddS)aCreate a Z3 floating-point conversion expression from other term sorts to floating-point. From a bit-vector term in IEEE 754-2008 format: >>> x = FPVal(1.0, Float32()) >>> x_bv = fpToIEEEBV(x) >>> simplify(fpToFP(x_bv, Float32())) 1 From a floating-point term with different precision: >>> x = FPVal(1.0, Float32()) >>> x_db = fpToFP(RNE(), x, Float64()) >>> x_db.sort() FPSort(11, 53) From a real term: >>> x_r = RealVal(1.5) >>> simplify(fpToFP(RNE(), x_r, Float32())) 1.5 From a signed bit-vector term: >>> x_signed = BitVecVal(-5, BitVecSort(32)) >>> simplify(fpToFP(RNE(), x_signed, Float32())) -1.25*(2**2) zKUnsupported combination of arguments for conversion to floating-point term.N)r6rrrOZ3_mk_fpa_to_fp_bvr7rrrZ3_mk_fpa_to_fp_floatrZ3_mk_fpa_to_fp_realZ3_mk_fpa_to_fp_signedr()Za1Za2a3r:r r r fpToFPK(sr\cCs>tt|dtt|dt|}tt||j|j|S)aCreate a Z3 floating-point conversion expression that represents the conversion from a bit-vector term to a floating-point term. >>> x_bv = BitVecVal(0x3F800000, 32) >>> x_fp = fpBVToFP(x_bv, Float32()) >>> x_fp fpToFP(1065353216) >>> simplify(x_fp) 1 rz1Second argument must be a Z3 floating-point sort.)r)rrr6rOrWr7r)rrr:r r r fpBVToFPr(s r]cCsPtt|dtt|dtt|dt|}tt||j|j|j|S)afCreate a Z3 floating-point conversion expression that represents the conversion from a floating-point term to a floating-point term of different precision. >>> x_sgl = FPVal(1.0, Float32()) >>> x_dbl = fpFPToFP(RNE(), x_sgl, Float64()) >>> x_dbl fpToFP(RNE(), 1) >>> simplify(x_dbl) 1 >>> x_dbl.sort() FPSort(11, 53) DFirst argument must be a Z3 floating-point rounding mode expression.z7Second argument must be a Z3 floating-point expression.0Third argument must be a Z3 floating-point sort.) r)rrrr6rOrXr7rrrrr:r r r fpFPToFP(s racCsPtt|dtt|dtt|dt|}tt||j|j|j|S)aCreate a Z3 floating-point conversion expression that represents the conversion from a real term to a floating-point term. >>> x_r = RealVal(1.5) >>> x_fp = fpRealToFP(RNE(), x_r, Float32()) >>> x_fp fpToFP(RNE(), 3/2) >>> simplify(x_fp) 1.5 r^z5Second argument must be a Z3 expression or real sort.r_) r)rrrr6rOrYr7rr`r r r fpRealToFP(s rbcCsPtt|dtt|dtt|dt|}tt||j|j|j|S)acCreate a Z3 floating-point conversion expression that represents the conversion from a signed bit-vector term (encoding an integer) to a floating-point term. >>> x_signed = BitVecVal(-5, BitVecSort(32)) >>> x_fp = fpSignedToFP(RNE(), x_signed, Float32()) >>> x_fp fpToFP(RNE(), 4294967291) >>> simplify(x_fp) -1.25*(2**2) r^rr_) r)rrrr6rOrZr7rr`r r r fpSignedToFP(s rccCsPtt|dtt|dtt|dt|}tt||j|j|j|S)amCreate a Z3 floating-point conversion expression that represents the conversion from an unsigned bit-vector term (encoding an integer) to a floating-point term. >>> x_signed = BitVecVal(-5, BitVecSort(32)) >>> x_fp = fpUnsignedToFP(RNE(), x_signed, Float32()) >>> x_fp fpToFPUnsigned(RNE(), 4294967291) >>> simplify(x_fp) 1*(2**32) r^rr_) r)rrrr6rOZ3_mk_fpa_to_fp_unsignedr7rr`r r r fpUnsignedToFP(s recCsVtr0tt|dtt|dtt|dt|}tt||j |j |j |S)zhCreate a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression.r!rz-Third argument must be Z3 floating-point sort) r r)rrrr6rOrdr7rrrUr3r:r r r fpToFPUnsigned(s rgcCsXtr0tt|dtt|dtt|dt|}tt||j |j | |S)aCCreate a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector. >>> x = FP('x', FPSort(8, 24)) >>> y = fpToSBV(RTZ(), x, BitVecSort(32)) >>> print(is_fp(x)) True >>> print(is_bv(y)) True >>> print(is_fp(y)) False >>> print(is_bv(x)) False r!r")Third argument must be Z3 bit-vector sort) r r)rrrgr6rIZ3_mk_fpa_to_sbvr7rrfrfr r r fpToSBV(s rjcCsXtr0tt|dtt|dtt|dt|}tt||j |j | |S)aECreate a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector. >>> x = FP('x', FPSort(8, 24)) >>> y = fpToUBV(RTZ(), x, BitVecSort(32)) >>> print(is_fp(x)) True >>> print(is_bv(y)) True >>> print(is_fp(y)) False >>> print(is_bv(x)) False r!r"rh) r r)rrrgr6rIZ3_mk_fpa_to_ubvr7rrfrfr r r fpToUBV(s rlcCs2trtt|dt|}tt||j|S)a$Create a Z3 floating-point conversion expression, from floating-point expression to real. >>> x = FP('x', FPSort(8, 24)) >>> y = fpToReal(x) >>> print(is_fp(x)) True >>> print(is_real(y)) True >>> print(is_fp(y)) False >>> print(is_real(x)) False r%)r r)rr6rDZ3_mk_fpa_to_realr7rrUr:r r r fpToReal)srocCs2trtt|dt|}tt||j|S)a.rief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. The size of the resulting bit-vector is automatically determined. Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion knows only one NaN and it will always produce the same bit-vector representation of that NaN. >>> x = FP('x', FPSort(8, 24)) >>> y = fpToIEEEBV(x) >>> print(is_fp(x)) True >>> print(is_bv(y)) True >>> print(is_fp(y)) False >>> print(is_bv(x)) False r%)r r)rr6rIZ3_mk_fpa_to_ieee_bvr7rrnr r r fpToIEEEBV)srqc@s eZdZdZddZddZdS)rzSequence sort.cCst||jS)zDetermine if sort is a string >>> s = StringSort() >>> s.is_string() True >>> s = SeqSort(IntSort()) >>> s.is_string() False )Z3_is_string_sortrrrnr r r is_string:)s zSeqSortRef.is_stringcCstt||j|jSr)rZ3_get_seq_sort_basisrrr:rnr r r basisE)szSeqSortRef.basisN)rsrtrurvrsrur r r r r7)s rcCst|}tt||S)zNCreate a string sort >>> s = StringSort() >>> print(s) String )r6rZ3_mk_string_sortr7rpr r r StringSortI)srwcCstt||j|jS)zCreate a sequence sort over elements provided in the argument >>> s = SeqSort(IntSort()) >>> s == Unit(IntVal(1)).sort() True )rZ3_mk_seq_sortrrr:r2r r r SeqSortS)sryc@speZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZdS)rSzSequence expression.cCstt|||jSr)rrrrr:rnr r r r_)sz SeqRef.sortcCs t||Srrrr r r rb)szSeqRef.__add__cCs t||Srrzrr r r re)szSeqRef.__radd__cCs4t|rt||j}tt||||jSr)rrr:r Z3_mk_seq_nthrrrr r r rh)s zSeqRef.__getitem__cCs4t|rt||j}tt||||jSr)rrr:rS Z3_mk_seq_atrrrr r r atm)s z SeqRef.atcCst|t||Sr)rrrrrrnr r r rsr)szSeqRef.is_stringcCst||Sr) Z3_is_stringrrrnr r r is_string_valueu)szSeqRef.is_string_valuecCsN|r>> print (is_seq(Unit(IntVal(0)))) True >>> print (is_seq(StringVal("abc"))) True )r rSrr r r r)srcCst|to|S)zhReturn `True` if `a` is a Z3 string expression. >>> print (is_string(StringVal("ab"))) True )r rSrsrr r r rs)srscCst|to|S)zreturn 'True' if 'a' is a Z3 string constant expression. >>> print (is_string_value(StringVal("a"))) True >>> print (is_string_value(StringVal("a") + StringVal("b"))) False )r rSrrr r r r)srcCs6ddd|D}t|}tt|t|||S)zcreate a string expressionrcss.|]&}t|dkrt|n dt|VqdS)z\u{%x}N)ordrS)rBZchr r r r=)szStringVal..)joinr6rS Z3_mk_lstringr7rEr9r r r r[)sr[cCs*t|}tt|t||t|j|S)ztReturn a string constant named `name`. If `ctx=None`, then the global context is used. >>> x = String('x') )r6rSrtr7r;rwrrr r r String)srcs.tt|tr|d}fdd|DS)z$Return a tuple of String constants. rvcsg|]}t|qSr )rrwrpr r rD)szStrings..rrr rpr Strings)s  rcCs t|||Sz3Extract substring or subsequence starting at offsetrr3rrr r r SubString)srcCs t|||Srrrr r r SubSeq)srcCsPt|tr"tt||j|jSt|trDtt ||j|jSt ddS)a6Create the empty sequence of the given sort >>> e = Empty(StringSort()) >>> e2 = StringVal("") >>> print(e.eq(e2)) True >>> e3 = Empty(SeqSort(IntSort())) >>> print(e3) Empty(Seq(Int)) >>> e4 = Empty(ReSort(SeqSort(IntSort()))) >>> print(e4) Empty(ReSort(Seq(Int))) z9Non-sequence, non-regular expression sort passed to EmptyN) r rrSZ3_mk_seq_emptyrrr:rrTZ3_mk_re_emptyr(r2r r r Empty)s  rcCs.t|tr"tt||j|jStddS)zCreate the regular expression that accepts the universal language >>> e = Full(ReSort(SeqSort(IntSort()))) >>> print(e) Full(ReSort(Seq(Int))) >>> e1 = Full(ReSort(StringSort())) >>> print(e1) Full(ReSort(String)) z8Non-sequence, non-regular expression sort passed to FullN)r rrT Z3_mk_re_fullrrr:r(r2r r r Full)s rcCstt|||jS)zCreate a singleton sequence)rSZ3_mk_seq_unitrrr:rr r r Unit*srcCs>t||}t||}t||}tt||||jS)zCheck if 'a' is a prefix of 'b' >>> s1 = PrefixOf("ab", "abc") >>> simplify(s1) True >>> s2 = PrefixOf("bc", "abc") >>> simplify(s2) False )rrr2Z3_mk_seq_prefixrrr:rLr r r PrefixOf*s   rcCs>t||}t||}t||}tt||||jS)zCheck if 'a' is a suffix of 'b' >>> s1 = SuffixOf("ab", "abc") >>> simplify(s1) False >>> s2 = SuffixOf("bc", "abc") >>> simplify(s2) True )rrr2Z3_mk_seq_suffixrrr:rLr r r SuffixOf*s   rcCs>t||}t||}t||}tt||||jS)a Check if 'a' contains 'b' >>> s1 = Contains("abc", "ab") >>> simplify(s1) True >>> s2 = Contains("abc", "bc") >>> simplify(s2) True >>> x, y, z = Strings('x y z') >>> s3 = Contains(Concat(x,y,z), y) >>> simplify(s3) True )rrr2Z3_mk_seq_containsrrr:rLr r r Contains%*s   rcCsdt||}|dkr t|r |j}t||}t||}t||}tt|||||jS)z}Replace the first occurrence of 'src' by 'dst' in 's' >>> r = Replace("aaa", "a", "b") >>> simplify(r) "baa" N)rrr:rrSZ3_mk_seq_replacerr)r3srcdstr:r r r Replace8*s    rcCsz|dkrtd}d}t|r"|j}t|||}t||}t||}t|rTt||}tt|| | | |jS)zRetrieve the index of substring within a string starting at a specified offset. >>> simplify(IndexOf("abcabc", "bc", 0)) 1 >>> simplify(IndexOf("abcabc", "bc", 2)) 4 Nr) rrr:rrrrDZ3_mk_seq_indexrr)r3substrrr:r r r IndexOfG*s    rcCsDd}t|||}t||}t||}tt||||jS)z4Retrieve the last index of substring within a stringN)rrrDZ3_mk_seq_last_indexrrr:)r3rr:r r r LastIndexOf[*s    rcCs"t|}tt|||jS)zgObtain the length of a sequence 's' >>> l = Length(StringVal("abc")) >>> simplify(l) 3 )rrDZ3_mk_seq_lengthrrr:r2r r r Lengthd*srcCs"t|}tt|||jS)zConvert string expression to integer >>> a = StrToInt("1") >>> simplify(1 == a) True >>> b = StrToInt("2") >>> simplify(1 == b) False >>> c = StrToInt(IntToStr(2)) >>> simplify(1 == c) False )rrDZ3_mk_str_to_intrrr:r2r r r StrToIntn*s rcCs*t|st|}tt|||jS)z$Convert integer expression to string)rrZrSZ3_mk_int_to_strrrr:r2r r r IntToStr~*srcCs$t||}tt|||jS)zThe regular expression that accepts sequence 's' >>> s1 = Re("ab") >>> s2 = Re(StringVal("ab")) >>> s3 = Re(Unit(BoolVal(True))) )rrTZ3_mk_seq_to_rerrr:r9r r r Re*s rc@seZdZdZddZdS)rzRegular expression sort.cCstt||j|jSr)rZ3_get_re_sort_basisrrr:rnr r r ru*szReSortRef.basisN)rsrtrurvrur r r r r*srcCsft|r"tt|j|j|jS|dks4t|trZt|}tt|t ||jSt ddS)NzWRegular expression sort constructor expects either a string or a context or no argument) rr Z3_mk_re_sortr:r7rr rZr6rvr(r9r r r ReSort*s rc@seZdZdZddZdS)rTzRegular expressions.cCs t||Sr)Unionrr r r r*sz ReRef.__add__N)rsrtrurvrr r r r rT*srTcCs t|tSr)r rTr2r r r r*srcCs,t||j}tt||||jS)zCreate regular expression membership test >>> re = Union(Re("a"),Re("b")) >>> print (simplify(InRe("a", re))) True >>> print (simplify(InRe("b", re))) True >>> print (simplify(InRe("c", re))) False )rr:r2Z3_mk_seq_in_rerr)r3rer r r InRe*s rcGst|}t|}tr>> re = Union(Re("a"), Re("b"), Re("c")) >>> print (simplify(InRe("d", re))) False rAt least one argument expected.cSsg|] }t|qSr rrar r r rD*szUnion..rr) rMrEr r)rr:rrrrTZ3_mk_re_unionr7rLrr:rrr r r r*s   rcGst|}t|}tr>> re = Intersect(Re("a"), Re("b"), Re("c")) rrcSsg|] }t|qSr rrar r r rD*szIntersect..rr) rMrEr r)rr:rrrrTZ3_mk_re_intersectr7rr r r Intersect*s   rcCstt|||jS)zCreate the regular expression accepting one or more repetitions of argument. >>> re = Plus(Re("a")) >>> print(simplify(InRe("aa", re))) True >>> print(simplify(InRe("ab", re))) False >>> print(simplify(InRe("", re))) False )rT Z3_mk_re_plusrrr:rr r r Plus*s rcCstt|||jS)zCreate the regular expression that optionally accepts the argument. >>> re = Option(Re("a")) >>> print(simplify(InRe("a", re))) True >>> print(simplify(InRe("", re))) True >>> print(simplify(InRe("aa", re))) False )rTZ3_mk_re_optionrrr:rr r r Option*s rcCstt|||jS)z)Create the complement regular expression.)rTZ3_mk_re_complementrrr:rr r r Complement*srcCstt|||jS)zCreate the regular expression accepting zero or more repetitions of argument. >>> re = Star(Re("a")) >>> print(simplify(InRe("aa", re))) True >>> print(simplify(InRe("ab", re))) False >>> print(simplify(InRe("", re))) True )rT Z3_mk_re_starrrr:rr r r Star*s rcCstt|||||jS)aCreate the regular expression accepting between a lower and upper bound repetitions >>> re = Loop(Re("a"), 1, 3) >>> print(simplify(InRe("aa", re))) True >>> print(simplify(InRe("aaaa", re))) False >>> print(simplify(InRe("", re))) False )rT Z3_mk_re_looprrr:)rlohir r r Loop +s rcCs0t||}t||}tt||j|j|jS)zCreate the range regular expression over two sequences of length 1 >>> range = Range("a","z") >>> print(simplify(InRe("b", range))) True >>> print(simplify(InRe("bb", range))) False )rrTZ3_mk_re_rangerrr:)rrr:r r r Range+s  rcCstt||j||jSr)rZ3_mk_partial_orderrrr:rkrBr r r PartialOrder(+srcCstt||j||jSr)rZ3_mk_linear_orderrrr:rr r r LinearOrder,+srcCstt||j||jSr)rZ3_mk_tree_orderrrr:rr r r TreeOrder0+srcCstt||j||jSr)rZ3_mk_piecewise_linear_orderrrr:rr r r PiecewiseLinearOrder4+srcCstt||j|jS)zGiven a binary relation R, such that the two arguments have the same sort create the transitive closure relation R+. The transitive closure R+ is a new relation. )rZ3_mk_transitive_closurerrr:)r%r r r TransitiveClosure8+src@s4eZdZddZddZddZddZd d Zd S) PropClosurescCsi|_d|_dSr)baseslockrnr r r rlA+szPropClosures.__init__cCs"tjdkrddl}|jt_dSr#)rfr threadingthreadLock)rr r r set_threadedE+s zPropClosures.set_threadedcCs.|jr|j|j|}|jr*|j|Srracquirerreleaserfr:rr r r ryJ+s    zPropClosures.getcCs.|jr|j||j|<|jr*|jdSrrrr r r rHR+s   zPropClosures.setcCs<|jr|jt|jd}||j|<|jr8|j|S)Nr)rrrErr)rfrrr r r rY+s   zPropClosures.insertN)rsrtrurlrryrHrr r r r r@+s rcCstdkrtadSr)_prop_closuresrr r r r ensure_prop_closuresf+srcCst|dSr)rryrrpr r r user_prop_pushl+srcCst||dSr)rryr)r:rr r r user_prop_popp+srcCs0ttd|}t|j|t|jSr)rrZUsePropagateBaserHrfreshrr)rr:Znew_propr r r user_prop_fresht+s rcCs6t|}||_||tt||d|_dSr)rrycbfixedrrrr:)r:rrrpropr r r user_prop_fixed{+s rcCs"t|}||_|d|_dSr)rryrfinal)r:rrr r r user_prop_final+s rcCs&t|}||_|||d|_dSr)rryrrr:rrUyrr r r user_prop_eq+s  rcCs&t|}||_|||d|_dSr)rryrdiseqrr r r user_prop_diseq+s  rc@seZdZdddZddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZgfddZddZdS)UserPropagateBaseNcCs|dks|dkstt||_d|_d|_t||_d|_d|_ d|_ d|_ |rt |_t |jj||j_t|t|j_t|t|rt||jt|jtttdSr)rrr _ctxrrrrrrrrrZrmr:rarYrbrcrdZZ3_solver_propagate_initrrr_user_prop_push_user_prop_pop_user_prop_fresh)rfr3r:r r r rl+s0    zUserPropagateBase.__init__cCs|jrd|j_dSr)rr:rnr r r ro+szUserPropagateBase.__del__cCs|jr |jS|jjSdSr)rr r:rnr r r r:+szUserPropagateBase.ctxcCs |Srrrnr r r r+szUserPropagateBase.ctx_refcCs2|jr t|jrtt||jjt||_dSr)rrrZZ3_solver_propagate_fixedrr _user_prop_fixed)rfrr r r add_fixed+s  zUserPropagateBase.add_fixedcCs2|jr t|jrtt||jjt||_dSr)rrrZZ3_solver_propagate_finalrr _user_prop_final)rfrr r r add_final+s  zUserPropagateBase.add_finalcCs2|jr t|jrtt||jjt||_dSr)rrrZZ3_solver_propagate_eqrr  _user_prop_eq)rfrr r r add_eq+s  zUserPropagateBase.add_eqcCs2|jr t|jrtt||jjt||_dSr)rrrZZ3_solver_propagate_diseqrr _user_prop_diseq)rfrr r r add_diseq+s  zUserPropagateBase.add_diseqcCs tddS)Nzpush needs to be overwrittenr'rnr r r r+szUserPropagateBase.pushcCs tddS)Nzpop needs to be overwrittenr')rfrr r r r+szUserPropagateBase.popcCs tddS)Nzfresh needs to be overwrittenr'rnr r r r+szUserPropagateBase.freshcCs*|js t|jrtt||jj|jSr)r rrZ3_solver_propagate_registerrr)rfrXr r r r+s  zUserPropagateBase.addc Cst|}tj|}t|D]}||||<qt|}tj|}tj|} t|D]$}||d||<||d| |<qVt|jt|j||||| |j dS)Nrr) rErrrZ3_solver_propagate_consequencer:r7rrr) rfrXidseqsZ num_fixedZ_idsrZnum_eqsZ_lhsZ_rhsr r r propagate+s(     zUserPropagateBase.propagatecCs|jtd||gddS)NF)r)rrr:)rfrr r r conflict,szUserPropagateBase.conflict)N)rsrtrurlror:rrrrrrrrrrrr r r r r+s  r)N)N)N)N)N)N)rW)N)N)N)N)N)N)N)rN)N)N)N)N)N)N)N)N)N)N)N)N)N)rUN)N)N)N)rN)N)N)F)N)N)N)N)N)N)N)N)N)NN)NN)N)N)N)N)N)N)N)r N)N)N)N)N)N)N)N)N)N)N)N)F)F)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)r)NNN)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)NNN)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)N)r)N(rvrrZz3typesz3constsZ z3printerZ fractionsrrrrrrrtypingrr r rrrr"r$r&r)r-r0r4r;r@rMrOrVrYrZrwrxr6ryr|r~rrrrrrrrrrrrrrrrrrrrrr$r(rr+r/rrrYr1r`rcrr,rerfrhrirorrrsrur{r~rrrrr2rrrrrrrrrrmrrrrrrrrrrrrr@rrrrArrrrrrrrDrrrrMrFrrrrrrrrrrr r!r"r#r$r%rCrErGrZrErrIrrrMrNrOrQrTrVrWrYrZr[rr_rarcrdrrgrIrHrrrrrrhrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrJrrrrrrrrrrrrrrrrrrrrrrrr r rrrrrrrr!r'rrrKrErHrMrNr]rWrlrIrrrrrrrrrrrrrZ Z3_L_UNDEFrr rZr\r]rrrrQrrPrrrrrZon_model_eh_typerrrrkrrrrrrrrrrrr r rrrrrjrr!r*r,r-r.rrr3r5rlrKr:r<rArCrFrGrLrNrOrRrUrWrYr_rcrgrlrmrnrprqryr{rr~rrr frozensetrrrrrrrrrrrrrrrrrrrrrrrrOrRrrrrrrrrrrrrrNrrrr r rrrrrrrrrrrr$r'r(r+r,r-rrrrrr5r7r9r<r>r@rBrDrFrHrJrLrMrrrrrSrTrVr\r]rarbrcrergrjrlrorqrrwryrSrrrrsrr[rrrrrrrrrrrrrrrrrrrrTrrrrrrrrrrrrrrrrrrrrrrrrrZ push_eh_typerZ pop_eh_typerZ fresh_eh_typerZ fixed_eh_typerZ final_eh_typerZ eq_eh_typerrrr r r r  s'           2m X   "0  !     $             !'  ;#I      !a"           !  ,    .                        /     !           X  `a  !.:6!}mv /h      a]R              #  3  ,.           '    1             #