Z3不能用test证明使用Kleene代数的两个简单程序之间的等价性,但Mathematica和Reduce可以
我们的问题是要证明这一点 将Kleene代数与test结合使用 当b的值由p保持时,我们有交换性条件bp=pb;并将两个程序之间的等价性简化为方程 在b的值不被p保持的情况下,我们有交换性条件pc=cp;并将两个程序之间的等价性简化为方程 我试图用下面的SMT-LIB代码来证明第一个等式Z3不能用test证明使用Kleene代数的两个简单程序之间的等价性,但Mathematica和Reduce可以,z3,abstract-algebra,Z3,Abstract Algebra,我们的问题是要证明这一点 将Kleene代数与test结合使用 当b的值由p保持时,我们有交换性条件bp=pb;并将两个程序之间的等价性简化为方程 在b的值不被p保持的情况下,我们有交换性条件pc=cp;并将两个程序之间的等价性简化为方程 我试图用下面的SMT-LIB代码来证明第一个等式 (declare-sort S) (declare-fun sum (S S) S) (declare-fun mult (S S) S) (declare-fun neg (S) S) (assert
(declare-sort S)
(declare-fun sum (S S) S)
(declare-fun mult (S S) S)
(declare-fun neg (S) S)
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z)) (sum (mult x y) (mult y z))) ) )
(assert (forall ((x S) (y S) (z S)) (= (mult (sum y z) x) (sum (mult y x) (mult z x))) ) )
(assert (forall ((x S) (y S) (z S)) (= (mult x (mult y z)) (mult (mult x y) z)) ))
(check-sat)
(push)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(assert (= (mult b p) (mult p b)) )
(check-sat)
(pop)
(declare-sort S)
(declare-fun e () S)
(declare-fun O () S)
(declare-fun mult (S S) S)
(declare-fun sum (S S) S)
(declare-fun leq (S S) Bool)
(declare-fun negation (S) S)
(declare-fun test (S) Bool)
(assert (forall ((x S) (y S)) (= (sum x y) (sum y x ))))
(assert (forall ((x S) (y S) (z S)) (= (sum (sum x y) z) (sum x (sum y z)))))
(assert (forall ((x S)) (= (sum O x) x)))
(assert (forall ((x S)) (= (sum x x) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult (mult x y) z) (mult x (mult y z)))))
(assert (forall ((x S)) (= (mult e x) x)))
(assert (forall ((x S)) (= (mult x e) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z) ) (sum (mult x y) (mult x z)))))
(assert (forall ((x S) (y S) (z S)) (= (mult (sum x y) z ) (sum (mult x z) (mult y z)))))
(assert (forall ((x S)) (= (mult x O) O)))
(assert (forall ((x S)) (= (mult O x) O)))
(assert (forall ((x S) (y S)) (= (leq x y) (= (sum x y) y))))
(assert (forall ((x S) (y S)) (=> (and (test x) (test y) ) (= (mult x y) (mult y x))) ) )
(assert (forall ((x S)) (=> (test x) (= (sum x (negation x)) e) )))
(assert (forall ((x S)) (=> (test x) (= (mult x (negation x)) O) )))
(check-sat)
(push)
;; bpq + b`pr = p(bq + b`r)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(assert (=> (test b) (= (mult p b) (mult b p)) ))
(assert (=> (test b) (= (mult p (negation b)) (mult (negation b) p))))
(check-sat)
(assert (not (=> (test b) (= (sum (mult b (mult p q)) (mult (negation b) (mult p r) ))
(mult p (sum (mult b q) (mult (negation b) r))))) ) )
(check-sat)
(pop)
(echo "Proved: bpq + b`pr = p(bq + b`r)")
(declare-sort S)
(declare-fun e () S)
(declare-fun O () S)
(declare-fun mult (S S) S)
(declare-fun sum (S S) S)
(declare-fun leq (S S) Bool)
(declare-fun negation (S) S)
(declare-fun test (S) Bool)
(assert (forall ((x S) (y S)) (= (sum x y) (sum y x ))))
(assert (forall ((x S) (y S) (z S)) (= (sum (sum x y) z) (sum x (sum y z)))))
(assert (forall ((x S)) (= (sum O x) x)))
(assert (forall ((x S)) (= (sum x x) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult (mult x y) z) (mult x (mult y z)))))
(assert (forall ((x S)) (= (mult e x) x)))
(assert (forall ((x S)) (= (mult x e) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z) ) (sum (mult x y) (mult x z)))))
(assert (forall ((x S) (y S) (z S)) (= (mult (sum x y) z ) (sum (mult x z) (mult y z)))))
(assert (forall ((x S)) (= (mult x O) O)))
(assert (forall ((x S)) (= (mult O x) O)))
(assert (forall ((x S) (y S)) (= (leq x y) (= (sum x y) y))))
(assert (forall ((x S) (y S)) (=> (and (test x) (test y) ) (= (mult x y) (mult y x))) ) )
(assert (forall ((x S)) (=> (test x) (= (sum x (negation x)) e) )))
(assert (forall ((x S)) (=> (test x) (= (mult x (negation x)) O) )))
(assert (forall ((x S)) (=> (test x) (test (negation x)) )) )
(assert (forall ((x S)) (=> (test x) (= (mult x x) x) )) )
(check-sat)
(push)
(declare-fun c () S)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(check-sat)
(assert (not (=> (and (test b) (test c))
(= (mult (sum (mult b c) (mult (negation b) (negation c)))
(sum (mult b (mult p q)) (mult (negation b) (mult p r) ) ))
(sum (mult b (mult c (mult p q)))
(mult (negation b) (mult (negation c) (mult p r) ) ) ))) ) )
(check-sat)
(pop)
(echo "Proved: part 1")
(push)
;;
(assert (=> (test c) (= (mult p c) (mult c p)) ))
(assert (=> (test c) (= (mult p (negation c)) (mult (negation c) p))))
(check-sat)
(assert (not (=> (test c)
(= (mult (sum (mult b c) (mult (negation b) (negation c)))
(mult p (sum (mult c q) (mult (negation c) r))))
(sum (mult b (mult c (mult p q)))
(mult (negation b) (mult (negation c) (mult p r) ) ) ))) ) )
(check-sat)
(pop)
(echo "Proved: part 2")
但我获得了超时
;也就是说Z3不能处理交换性条件bp=pb。请联机运行此示例
Z3不能证明这些方程,但Mathematica和Reduce可以。Z3没有定理证明器那么强大。你同意吗?第一个方程是用Z3和以下SMT-LIB代码证明的
(declare-sort S)
(declare-fun sum (S S) S)
(declare-fun mult (S S) S)
(declare-fun neg (S) S)
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z)) (sum (mult x y) (mult y z))) ) )
(assert (forall ((x S) (y S) (z S)) (= (mult (sum y z) x) (sum (mult y x) (mult z x))) ) )
(assert (forall ((x S) (y S) (z S)) (= (mult x (mult y z)) (mult (mult x y) z)) ))
(check-sat)
(push)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(assert (= (mult b p) (mult p b)) )
(check-sat)
(pop)
(declare-sort S)
(declare-fun e () S)
(declare-fun O () S)
(declare-fun mult (S S) S)
(declare-fun sum (S S) S)
(declare-fun leq (S S) Bool)
(declare-fun negation (S) S)
(declare-fun test (S) Bool)
(assert (forall ((x S) (y S)) (= (sum x y) (sum y x ))))
(assert (forall ((x S) (y S) (z S)) (= (sum (sum x y) z) (sum x (sum y z)))))
(assert (forall ((x S)) (= (sum O x) x)))
(assert (forall ((x S)) (= (sum x x) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult (mult x y) z) (mult x (mult y z)))))
(assert (forall ((x S)) (= (mult e x) x)))
(assert (forall ((x S)) (= (mult x e) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z) ) (sum (mult x y) (mult x z)))))
(assert (forall ((x S) (y S) (z S)) (= (mult (sum x y) z ) (sum (mult x z) (mult y z)))))
(assert (forall ((x S)) (= (mult x O) O)))
(assert (forall ((x S)) (= (mult O x) O)))
(assert (forall ((x S) (y S)) (= (leq x y) (= (sum x y) y))))
(assert (forall ((x S) (y S)) (=> (and (test x) (test y) ) (= (mult x y) (mult y x))) ) )
(assert (forall ((x S)) (=> (test x) (= (sum x (negation x)) e) )))
(assert (forall ((x S)) (=> (test x) (= (mult x (negation x)) O) )))
(check-sat)
(push)
;; bpq + b`pr = p(bq + b`r)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(assert (=> (test b) (= (mult p b) (mult b p)) ))
(assert (=> (test b) (= (mult p (negation b)) (mult (negation b) p))))
(check-sat)
(assert (not (=> (test b) (= (sum (mult b (mult p q)) (mult (negation b) (mult p r) ))
(mult p (sum (mult b q) (mult (negation b) r))))) ) )
(check-sat)
(pop)
(echo "Proved: bpq + b`pr = p(bq + b`r)")
(declare-sort S)
(declare-fun e () S)
(declare-fun O () S)
(declare-fun mult (S S) S)
(declare-fun sum (S S) S)
(declare-fun leq (S S) Bool)
(declare-fun negation (S) S)
(declare-fun test (S) Bool)
(assert (forall ((x S) (y S)) (= (sum x y) (sum y x ))))
(assert (forall ((x S) (y S) (z S)) (= (sum (sum x y) z) (sum x (sum y z)))))
(assert (forall ((x S)) (= (sum O x) x)))
(assert (forall ((x S)) (= (sum x x) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult (mult x y) z) (mult x (mult y z)))))
(assert (forall ((x S)) (= (mult e x) x)))
(assert (forall ((x S)) (= (mult x e) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z) ) (sum (mult x y) (mult x z)))))
(assert (forall ((x S) (y S) (z S)) (= (mult (sum x y) z ) (sum (mult x z) (mult y z)))))
(assert (forall ((x S)) (= (mult x O) O)))
(assert (forall ((x S)) (= (mult O x) O)))
(assert (forall ((x S) (y S)) (= (leq x y) (= (sum x y) y))))
(assert (forall ((x S) (y S)) (=> (and (test x) (test y) ) (= (mult x y) (mult y x))) ) )
(assert (forall ((x S)) (=> (test x) (= (sum x (negation x)) e) )))
(assert (forall ((x S)) (=> (test x) (= (mult x (negation x)) O) )))
(assert (forall ((x S)) (=> (test x) (test (negation x)) )) )
(assert (forall ((x S)) (=> (test x) (= (mult x x) x) )) )
(check-sat)
(push)
(declare-fun c () S)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(check-sat)
(assert (not (=> (and (test b) (test c))
(= (mult (sum (mult b c) (mult (negation b) (negation c)))
(sum (mult b (mult p q)) (mult (negation b) (mult p r) ) ))
(sum (mult b (mult c (mult p q)))
(mult (negation b) (mult (negation c) (mult p r) ) ) ))) ) )
(check-sat)
(pop)
(echo "Proved: part 1")
(push)
;;
(assert (=> (test c) (= (mult p c) (mult c p)) ))
(assert (=> (test c) (= (mult p (negation c)) (mult (negation c) p))))
(check-sat)
(assert (not (=> (test c)
(= (mult (sum (mult b c) (mult (negation b) (negation c)))
(mult p (sum (mult c q) (mult (negation c) r))))
(sum (mult b (mult c (mult p q)))
(mult (negation b) (mult (negation c) (mult p r) ) ) ))) ) )
(check-sat)
(pop)
(echo "Proved: part 2")
输出是
sat
sat
unsat
Proved: bpq + b`pr = p(bq + b`r)
sat
sat
unsat
Proved: part 1
sat
unsat
Proved: part 2
sat
sat
unsat
Proved: part 1
sat
timeout
请在线运行此证明第二个方程式通过以下程序使用Z3间接证明 此间接过程使用以下SMT-LIB代码实现
(declare-sort S)
(declare-fun sum (S S) S)
(declare-fun mult (S S) S)
(declare-fun neg (S) S)
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z)) (sum (mult x y) (mult y z))) ) )
(assert (forall ((x S) (y S) (z S)) (= (mult (sum y z) x) (sum (mult y x) (mult z x))) ) )
(assert (forall ((x S) (y S) (z S)) (= (mult x (mult y z)) (mult (mult x y) z)) ))
(check-sat)
(push)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(assert (= (mult b p) (mult p b)) )
(check-sat)
(pop)
(declare-sort S)
(declare-fun e () S)
(declare-fun O () S)
(declare-fun mult (S S) S)
(declare-fun sum (S S) S)
(declare-fun leq (S S) Bool)
(declare-fun negation (S) S)
(declare-fun test (S) Bool)
(assert (forall ((x S) (y S)) (= (sum x y) (sum y x ))))
(assert (forall ((x S) (y S) (z S)) (= (sum (sum x y) z) (sum x (sum y z)))))
(assert (forall ((x S)) (= (sum O x) x)))
(assert (forall ((x S)) (= (sum x x) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult (mult x y) z) (mult x (mult y z)))))
(assert (forall ((x S)) (= (mult e x) x)))
(assert (forall ((x S)) (= (mult x e) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z) ) (sum (mult x y) (mult x z)))))
(assert (forall ((x S) (y S) (z S)) (= (mult (sum x y) z ) (sum (mult x z) (mult y z)))))
(assert (forall ((x S)) (= (mult x O) O)))
(assert (forall ((x S)) (= (mult O x) O)))
(assert (forall ((x S) (y S)) (= (leq x y) (= (sum x y) y))))
(assert (forall ((x S) (y S)) (=> (and (test x) (test y) ) (= (mult x y) (mult y x))) ) )
(assert (forall ((x S)) (=> (test x) (= (sum x (negation x)) e) )))
(assert (forall ((x S)) (=> (test x) (= (mult x (negation x)) O) )))
(check-sat)
(push)
;; bpq + b`pr = p(bq + b`r)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(assert (=> (test b) (= (mult p b) (mult b p)) ))
(assert (=> (test b) (= (mult p (negation b)) (mult (negation b) p))))
(check-sat)
(assert (not (=> (test b) (= (sum (mult b (mult p q)) (mult (negation b) (mult p r) ))
(mult p (sum (mult b q) (mult (negation b) r))))) ) )
(check-sat)
(pop)
(echo "Proved: bpq + b`pr = p(bq + b`r)")
(declare-sort S)
(declare-fun e () S)
(declare-fun O () S)
(declare-fun mult (S S) S)
(declare-fun sum (S S) S)
(declare-fun leq (S S) Bool)
(declare-fun negation (S) S)
(declare-fun test (S) Bool)
(assert (forall ((x S) (y S)) (= (sum x y) (sum y x ))))
(assert (forall ((x S) (y S) (z S)) (= (sum (sum x y) z) (sum x (sum y z)))))
(assert (forall ((x S)) (= (sum O x) x)))
(assert (forall ((x S)) (= (sum x x) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult (mult x y) z) (mult x (mult y z)))))
(assert (forall ((x S)) (= (mult e x) x)))
(assert (forall ((x S)) (= (mult x e) x)))
(assert (forall ((x S) (y S) (z S)) (= (mult x (sum y z) ) (sum (mult x y) (mult x z)))))
(assert (forall ((x S) (y S) (z S)) (= (mult (sum x y) z ) (sum (mult x z) (mult y z)))))
(assert (forall ((x S)) (= (mult x O) O)))
(assert (forall ((x S)) (= (mult O x) O)))
(assert (forall ((x S) (y S)) (= (leq x y) (= (sum x y) y))))
(assert (forall ((x S) (y S)) (=> (and (test x) (test y) ) (= (mult x y) (mult y x))) ) )
(assert (forall ((x S)) (=> (test x) (= (sum x (negation x)) e) )))
(assert (forall ((x S)) (=> (test x) (= (mult x (negation x)) O) )))
(assert (forall ((x S)) (=> (test x) (test (negation x)) )) )
(assert (forall ((x S)) (=> (test x) (= (mult x x) x) )) )
(check-sat)
(push)
(declare-fun c () S)
(declare-fun b () S)
(declare-fun p () S)
(declare-fun q () S)
(declare-fun r () S)
(check-sat)
(assert (not (=> (and (test b) (test c))
(= (mult (sum (mult b c) (mult (negation b) (negation c)))
(sum (mult b (mult p q)) (mult (negation b) (mult p r) ) ))
(sum (mult b (mult c (mult p q)))
(mult (negation b) (mult (negation c) (mult p r) ) ) ))) ) )
(check-sat)
(pop)
(echo "Proved: part 1")
(push)
;;
(assert (=> (test c) (= (mult p c) (mult c p)) ))
(assert (=> (test c) (= (mult p (negation c)) (mult (negation c) p))))
(check-sat)
(assert (not (=> (test c)
(= (mult (sum (mult b c) (mult (negation b) (negation c)))
(mult p (sum (mult c q) (mult (negation c) r))))
(sum (mult b (mult c (mult p q)))
(mult (negation b) (mult (negation c) (mult p r) ) ) ))) ) )
(check-sat)
(pop)
(echo "Proved: part 2")
相应的输出是
sat
sat
unsat
Proved: bpq + b`pr = p(bq + b`r)
sat
sat
unsat
Proved: part 1
sat
unsat
Proved: part 2
sat
sat
unsat
Proved: part 1
sat
timeout
该输出是在本地获得的。在线执行代码时,输出为
sat
sat
unsat
Proved: bpq + b`pr = p(bq + b`r)
sat
sat
unsat
Proved: part 1
sat
unsat
Proved: part 2
sat
sat
unsat
Proved: part 1
sat
timeout
请联机运行此示例
Z3不能直接证明第二个方程式,但可以证明Mathematica和Reduce。你能在rise4fun上发布一个可执行的程序吗?嗨,发布了一个可执行程序的程序。非常感谢。