问题
Does z3 provide a cross product function for two lists? If not is it possible to define one without using higher order functions or using the provided list functions? I have been having trouble trying to define one. I know how to define one using map but I don't think that is supported in z3.
回答1:
You can declare the cross product function in SMT 2.0.
However, any non-trivial property will require a proof by induction. Z3 currently does not support proofs by induction. Thus, it will only be able to prove very simple facts.
BTW, by cross-product of lists, I'm assuming you want a function that given the lists [a, b]
and [c, d]
returns the list or pairs [(a, c), (a, d), (b, c), (b, d)]
.
Here is a script that defines the product
function.
The script also demonstrates some limitations of the SMT 2.0 language. For example, SMT 2.0 does not support the definition of parametric axioms or functions. So, I used uninterpreted sorts to "simulate" that. I also had to define the auxiliary functions append
and product-aux
. You can try this example online at: http://rise4fun.com/Z3/QahiP
The example also proves the following trivial fact that if l = product([a], [b])
, then first(head(l))
must be a
.
If you are insterested in proving non-trivial properties. I see two options. We can try to prove the base case and inductive cases using Z3. The main disadvantage in this approach is that we have to manually create these cases, and mistakes can be made. Another option is to use an interactive theorem prover such as Isabelle. BTW, Isabelle has a much richer input language, and provides tactics for invoking Z3.
For more information about algebraic datatypes in Z3, go to the online tutorial http://rise4fun.com/Z3/tutorial/guide (Section Datatypes).
;; List is a builtin datatype in Z3
;; It has the constructors insert and nil
;; Declaring Pair type using algebraic datatypes
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
;; SMT 2.0 does not support parametric function definitions.
;; So, I'm using two uninterpreted sorts.
(declare-sort T1)
(declare-sort T2)
;; Remark: We can "instantiate" these sorts to interpreted sorts (Int, Real) by replacing the declarations above
;; with the definitions
;; (define-sort T1 () Int)
;; (define-sort T2 () Real)
(declare-fun append ((List (Pair T1 T2)) (List (Pair T1 T2))) (List (Pair T1 T2)))
;; Remark: I'm using (as nil (Pair T1 T2)) because nil is overloaded. So, I must tell which one I want.
(assert (forall ((l (List (Pair T1 T2))))
(= (append (as nil (List (Pair T1 T2))) l) l)))
(assert (forall ((h (Pair T1 T2)) (t (List (Pair T1 T2))) (l (List (Pair T1 T2))))
(= (append (insert h t) l) (insert h (append t l)))))
;; Auxiliary definition
;; Given [a, b, c], d returns [(a, d), (b, d), (c, d)]
(declare-fun product-aux ((List T1) T2) (List (Pair T1 T2)))
(assert (forall ((v T2))
(= (product-aux (as nil (List T1)) v)
(as nil (List (Pair T1 T2))))))
(assert (forall ((h T1) (t (List T1)) (v T2))
(= (product-aux (insert h t) v)
(insert (mk-pair h v) (product-aux t v)))))
(declare-fun product ((List T1) (List T2)) (List (Pair T1 T2)))
(assert (forall ((l (List T1)))
(= (product l (as nil (List T2))) (as nil (List (Pair T1 T2))))))
(assert (forall ((l (List T1)) (h T2) (t (List T2)))
(= (product l (insert h t))
(append (product-aux l h) (product l t)))))
(declare-const a T1)
(declare-const b T2)
(declare-const l (List (Pair T1 T2)))
(assert (= (product (insert a (as nil (List T1))) (insert b (as nil (List T2))))
l))
(assert (not (= (first (head l)) a)))
(check-sat)
回答2:
There isn't an #include directive for the smt-lib format. Z3 provides several other ways to provide input. The Python input format leverages all of Python, so importing files is naturally supported. There is a tutorial on Z3Py on http://rise4fun.com/z3py
来源:https://stackoverflow.com/questions/10642565/cross-product-in-z3