How to add toUpperCase function in Z3? - z3

I have tried the following code in Z3. But Z3 said model is not available.
(declare-const s String)
(declare-fun toUppercase (String) (String))
(assert (= (str.len s) (str.len (toUppercase s))))
(assert (forall ((i Int) (x String))
(let ((a!1 (and (not (= (str.at x i) "a"))
(not (= (str.at x i) "b"))
(not (= (str.at x i) "c"))
(not (= (str.at x i) "d"))
(not (= (str.at x i) "e"))
(not (= (str.at x i) "f"))
(not (= (str.at x i) "g"))
(not (= (str.at x i) "h"))
(not (= (str.at x i) "i"))
(not (= (str.at x i) "j"))
(not (= (str.at x i) "k"))
(not (= (str.at x i) "l"))
(not (= (str.at x i) "m"))
(not (= (str.at x i) "n"))
(not (= (str.at x i) "o"))
(not (= (str.at x i) "p"))
(not (= (str.at x i) "q"))
(not (= (str.at x i) "r"))
(not (= (str.at x i) "s"))
(not (= (str.at x i) "t"))
(not (= (str.at x i) "u"))
(not (= (str.at x i) "v"))
(not (= (str.at x i) "w"))
(not (= (str.at x i) "x"))
(not (= (str.at x i) "y"))
(not (= (str.at x i) "z"))
(= (str.at x i) (str.at (toUppercase x) i)))))
(let ((a!2 (or (and (= (str.at x i) "a") (= (str.at (toUppercase x) i) "A"))
(and (= (str.at x i) "b") (= (str.at (toUppercase x) i) "B"))
(and (= (str.at x i) "c") (= (str.at (toUppercase x) i) "C"))
(and (= (str.at x i) "d") (= (str.at (toUppercase x) i) "D"))
(and (= (str.at x i) "e") (= (str.at (toUppercase x) i) "E"))
(and (= (str.at x i) "f") (= (str.at (toUppercase x) i) "F"))
(and (= (str.at x i) "g") (= (str.at (toUppercase x) i) "G"))
(and (= (str.at x i) "h") (= (str.at (toUppercase x) i) "H"))
(and (= (str.at x i) "i") (= (str.at (toUppercase x) i) "I"))
(and (= (str.at x i) "j") (= (str.at (toUppercase x) i) "J"))
(and (= (str.at x i) "k") (= (str.at (toUppercase x) i) "K"))
(and (= (str.at x i) "l") (= (str.at (toUppercase x) i) "L"))
(and (= (str.at x i) "m") (= (str.at (toUppercase x) i) "M"))
(and (= (str.at x i) "n") (= (str.at (toUppercase x) i) "N"))
(and (= (str.at x i) "o") (= (str.at (toUppercase x) i) "O"))
(and (= (str.at x i) "p") (= (str.at (toUppercase x) i) "P"))
(and (= (str.at x i) "q") (= (str.at (toUppercase x) i) "Q"))
(and (= (str.at x i) "r") (= (str.at (toUppercase x) i) "R"))
(and (= (str.at x i) "s") (= (str.at (toUppercase x) i) "S"))
(and (= (str.at x i) "t") (= (str.at (toUppercase x) i) "T"))
(and (= (str.at x i) "u") (= (str.at (toUppercase x) i) "U"))
(and (= (str.at x i) "v") (= (str.at (toUppercase x) i) "V"))
(and (= (str.at x i) "w") (= (str.at (toUppercase x) i) "W"))
(and (= (str.at x i) "x") (= (str.at (toUppercase x) i) "X"))
(and (= (str.at x i) "y") (= (str.at (toUppercase x) i) "Y"))
(and (= (str.at x i) "z") (= (str.at (toUppercase x) i) "Z"))
a!1)))
(=> (and (>= i 0) (< i (str.len x))) a!2)))))
(assert (str.prefixof "hE" s))
(check-sat)
(get-model)
I was thinking maybe I could implement a replaceAll function to replace all lower-case characters with upper-case characters. But I cannot get the replaceAll function work as well.
This is my first try using define-fun-rec:
(set-option :smt.mbqi true)
(define-fun-rec replaceAll ((x!1 String) (x!2 String) (x!3 String)) (String)
(let ((I (str.indexof x!1 x!2) ))
(if (= I -1) x!1
(replaceAll (str.replace x!1 x!2 x!3) x!2 x!3)
)
)
)
(declare-const a String)
(simplify (replaceAll "aba" "a" "A"))
(assert (= (replaceAll a "a" "A") "Ab"))
(check-sat)
(get-model)
(exit)
This is my 2nd try using conditional macros:
(declare-fun replaceAll (String String String String) Bool)
(assert (forall ((x!1 String) (x!2 String) (x!3 String) (x!4 String))
(=> (= -1 (str.indexof x!1 x!2)) (replaceAll x!1 x!2 x!3 x!4))))
(assert (forall ((S String) (r String) (T String) (R String))
(=>
(>= (str.indexof S r) 0)
(exists ((U String) (M String) (S1 String) (R1 String))
(and (= S (str.++ U M S1))
(= R (str.++ U T R1))
(= M r)
(= (str.len U) (str.indexof S r))
(replaceAll S1 r T R1))
)
)))
(declare-const a String)
(assert (= a "ab"))
(assert (replaceAll a "a" "A" "Ab") )
(check-sat)
(get-model)
I would appreciate any guidance you could offer. Thank you.

This is going to be out of scope of what the String procedure can handle with respect to how it saturates constraints.
You are basically describing a transducer. There is currently no support for reasoning about transducers other than instantiating axioms about them.
There are tools that handle transducers natively and constraint solving around them. For example, the Bek/Bex tools (http://rise4fun.com/bex, http://rise4fun.com/bek) and the automata toolkit (http://research.microsoft.com/~margus, https://github.com/AutomataDotNet/Automata).

Related

How can I optimize an smtlib query reasoning about partial orders?

I am working on trying to do type inference in Z3 for a compiler and the compiler generates a Z3 query over a fully defined partial order, and then attempts to find the maximal type for all the variables such that a fixed set of constraints is satisfied.
The query looks something like this:
(declare-datatypes () ((Sort
(|SortInt| )
(|SortExp| )
(|SortKItem| )
(|SortKLabel| )
(|SortK| )
)))
(define-fun <=Sort ((s1 Sort) (s2 Sort)) Bool (or
(and (= s1 |SortKItem|) (= s2 |SortK|))
(and (= s1 |SortExp|) (= s2 |SortKItem|))
(and (= s1 |SortExp|) (= s2 |SortK|))
(and (= s1 |SortInt|) (= s2 |SortKItem|))
(and (= s1 |SortInt|) (= s2 |SortExp|))
(and (= s1 |SortInt|) (= s2 |SortK|))
(and (= s1 |SortKItem|) (= s2 |SortKItem|))
(and (= s1 |SortKLabel|) (= s2 |SortKLabel|))
(and (= s1 |SortExp|) (= s2 |SortExp|))
(and (= s1 |SortK|) (= s2 |SortK|))
(and (= s1 |SortInt|) (= s2 |SortInt|))
))
(define-fun <=SortSyntax ((s1 Sort) (s2 Sort)) Bool (or
(and (= s1 |SortKItem|) (= s2 |SortK|))
(and (= s1 |SortExp|) (= s2 |SortKItem|))
(and (= s1 |SortExp|) (= s2 |SortK|))
(and (= s1 |SortInt|) (= s2 |SortKItem|))
(and (= s1 |SortInt|) (= s2 |SortExp|))
(and (= s1 |SortInt|) (= s2 |SortK|))
(and (= s1 |SortKItem|) (= s2 |SortKItem|))
(and (= s1 |SortKLabel|) (= s2 |SortKLabel|))
(and (= s1 |SortExp|) (= s2 |SortExp|))
(and (= s1 |SortK|) (= s2 |SortK|))
(and (= s1 |SortInt|) (= s2 |SortInt|))
))
(push)
(declare-const |FreshVarSort_6_8_6_36_#KRewrite| Sort)
(declare-const |VarA| Sort)
(declare-const |VarB| Sort)
(declare-const |VarC| Sort)
(declare-datatypes() ((SolutionVariables (SolVars (|Sol_VarA| Sort) (|Sol_VarB| Sort) (|Sol_VarC| Sort) ))))
(declare-datatypes() ((Solution (Sol (vars SolutionVariables) (|Sol_FreshVarSort_6_8_6_36_#KRewrite| Sort) ))))
(define-fun theSolution () Solution (Sol (SolVars |VarA| |VarB| |VarC| ) |FreshVarSort_6_8_6_36_#KRewrite| ))
(define-fun lt ((s1 Solution) (s2 Solution)) Bool (and true (<=SortSyntax (|Sol_VarA| (vars s1)) (|Sol_VarA| (vars s2))) (<=SortSyntax (|Sol_VarB| (vars s1)) (|Sol_VarB| (vars s2))) (<=SortSyntax (|Sol_VarC| (vars s1)) (|Sol_VarC| (vars s2))) (distinct (vars s1) (vars s2))))
(assert (and true (distinct (|Sol_FreshVarSort_6_8_6_36_#KRewrite| theSolution) |SortKLabel|) ))
(define-fun |constraint4_SortExp| ((s Solution)) Bool (and true (<=Sort (|Sol_VarA| (vars s)) |SortExp|) ))
(define-fun |constraint6_SortExp| ((s Solution)) Bool (and true (<=Sort (|Sol_VarB| (vars s)) |SortExp|) ))
(define-fun |constraint3_SortExp| ((s Solution)) Bool (and true (<=Sort |SortExp| |SortExp|) (|constraint4_SortExp| s) (|constraint6_SortExp| s) ))
(define-fun |constraint8_SortExp| ((s Solution)) Bool (and true (<=Sort (|Sol_VarC| (vars s)) |SortExp|) ))
(define-fun |constraint2_(Sol_FreshVarSort_6_8_6_36_#KRewrite s)| ((s Solution)) Bool (and true (<=Sort |SortExp| (|Sol_FreshVarSort_6_8_6_36_#KRewrite| s)) (|constraint3_SortExp| s) (|constraint8_SortExp| s) ))
(define-fun |constraint12_SortInt| ((s Solution)) Bool (and true (<=Sort (|Sol_VarA| (vars s)) |SortInt|) ))
(define-fun |constraint14_SortInt| ((s Solution)) Bool (and true (<=Sort (|Sol_VarB| (vars s)) |SortInt|) ))
(define-fun |constraint11_SortInt| ((s Solution)) Bool (and true (<=Sort |SortInt| |SortInt|) (|constraint12_SortInt| s) (|constraint14_SortInt| s) ))
(define-fun |constraint16_SortInt| ((s Solution)) Bool (and true (<=Sort (|Sol_VarC| (vars s)) |SortInt|) ))
(define-fun |constraint10_(Sol_FreshVarSort_6_8_6_36_#KRewrite s)| ((s Solution)) Bool (and true (<=Sort |SortInt| (|Sol_FreshVarSort_6_8_6_36_#KRewrite| s)) (|constraint11_SortInt| s) (|constraint16_SortInt| s) ))
(define-fun |constraint1_Sort#RuleBody| ((s Solution)) Bool (and true (= (|Sol_FreshVarSort_6_8_6_36_#KRewrite| s) |SortK|) (|constraint2_(Sol_FreshVarSort_6_8_6_36_#KRewrite s)| s) (|constraint10_(Sol_FreshVarSort_6_8_6_36_#KRewrite s)| s) ))
(define-fun |constraint0_Sort#RuleContent| ((s Solution)) Bool (and true (|constraint1_Sort#RuleBody| s) ))
(define-fun |constraint21_SortExp| ((s Solution)) Bool (and true (<=Sort |SortExp| |SortExp|) (|constraint6_SortExp| s) (|constraint8_SortExp| s) ))
(define-fun |constraint20_(Sol_FreshVarSort_6_8_6_36_#KRewrite s)| ((s Solution)) Bool (and true (<=Sort |SortExp| (|Sol_FreshVarSort_6_8_6_36_#KRewrite| s)) (|constraint4_SortExp| s) (|constraint21_SortExp| s) ))
(define-fun |constraint19_Sort#RuleBody| ((s Solution)) Bool (and true (= (|Sol_FreshVarSort_6_8_6_36_#KRewrite| s) |SortK|) (|constraint20_(Sol_FreshVarSort_6_8_6_36_#KRewrite s)| s) (|constraint10_(Sol_FreshVarSort_6_8_6_36_#KRewrite s)| s) ))
(define-fun |constraint18_Sort#RuleContent| ((s Solution)) Bool (and true (|constraint19_Sort#RuleBody| s) ))
(define-fun amb0 ((s Solution)) Bool (or (|constraint0_Sort#RuleContent| s) (|constraint18_Sort#RuleContent| s) ))
(assert (amb0 theSolution))
(assert (not (exists ((s Solution)) (and (lt theSolution s) (amb0 s) (distinct (|Sol_FreshVarSort_6_8_6_36_#KRewrite| s) |SortKLabel|) ))))
(check-sat)
(get-model)
(assert (or false (distinct |VarA| |SortInt|) (distinct |VarB| |SortInt|) (distinct |VarC| |SortInt|) ))
(check-sat)
(pop)
This is a smaller query and runs fine. The problem is, when the number of sorts and variables and disjunctions in the constraints increases, z3 starts to take a significant amount of time to solve the constraints.
What I am wondering is, are there any specific tactics I could use or ways I could refactor the way the query is generated so queries of this type are faster on complex examples?
I can provide a larger query if it would be useful, but it's several hundred kilobytes.

SMT: check uniqueness and totality of function

Given is a function and a description of its behavior:
add: (ℤ ∪ {Error, None})² → (ℤ ∪ {Error, None})
For x ∈ (ℤ ∪ {Error, None}):
add(x, None) = add(None, x) = None
For x ∈ (ℤ ∪ {Error}):
add(x, Error) = add(Error, x) = Error
For x, y ∈ ℤ:
add(x, y) = x + y
How can I transform this description to SMT (I'm using Z3) and check whether the description defines a total function?
To give you an idea what I want to achieve: in the end I want to generate Python code implementing this function with the minimum number of branches. For example:
def add(x, y):
if x is None or y is None:
return None
if x is Error or y is Error:
return Error
return x + y
This is what I tried so far:
(declare-datatypes () ((ABC (int (val Int)) error none)))
(declare-fun f (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f none x) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f x none) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f error x) error))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (is-int x) (is-int y)) (= (f x y) (int (+ (val x) (val y)))))))
(check-sat)
(get-model)
This timeouts.
EDIT: In Simplify function interpretation in model I described a simpler axiomatization of f where int is a single case, resulting in finitely many cases. Can I somehow tell Z3 that the concrete val in int doesn't matter and there are effectively finitely many cases?
To check uniqueness: Your axiomatization is good; you just need to "replicate" it for two functions then ask for two values such that they differ:
(declare-datatypes () ((ABC (int (val Int)) error none)))
(declare-fun f (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f none x) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f x none) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f error x) error))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (is-int x) (is-int y)) (= (f x y) (int (+ (val x) (val y)))))))
(declare-fun g (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (g none x) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (g x none) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (g error x) error))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (g x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (is-int x) (is-int y)) (= (g x y) (int (+ (val x) (val y)))))))
; check that there is no {x,y} such that f and g differ on:
(declare-const x ABC)
(declare-const y ABC)
(assert (not (= (f x y) (g x y))))
(check-sat)
(get-model)
Z3 quickly returns unsat for this; meaning f and g cannot differ. Now, you can try commenting out some of the asserts for f and/or g and ask for a model. Depending on which asserts you comment out, Z3 might come up with a model for f and g such that they have different behavior; OR it can still time-out, trying to construct a model to do so. In the presence of quantifiers, you can't really expect anything better from an SMT solver.

z3 and z3PY giving different results

When I tried following in z3, I got result timeout
(set-option :smt.mbqi true)
(declare-fun R(Int) Int)
(declare-fun Q(Int) Int)
(declare-var X Int)
(declare-var Y Int)
(declare-const k Int)
(assert (>= X 0))
(assert (> Y 0))
(assert (forall ((n Int)) (=> (= n 0) (= (Q n) 0))))
(assert (forall ((n Int)) (=> (= n 0) (= (R n) X))))
(assert (forall ((n Int)) (=> (> n 0) (= (R (+ n 1) ) (+ (R n) (* 2 Y))))))
(assert (forall ((n Int)) (=> (> n 0) (= (Q (+ n 1) ) (- (Q n) 2)))))
(assert (forall ((n Int)) (=> (> n 0) (= X (+ (* (Q n) Y) (R n))))))
(assert (forall ((n Int)) (= X (+ (* (Q n) Y) (R n)))))
(assert (= X (+ (* (Q k) Y) (R k))))
(assert (not (= (* X 2) (+ (* (Q (+ k 1)) Y) (R (+ k 1))))))
(check-sat)
Same when I tried in z3py using following code, I got result unsat which is wrong
from z3 import *
x=Int('x')
y=Int('y')
k=Int('k')
n1=Int('n1')
r=Function('r',IntSort(),IntSort())
q=Function('q',IntSort(),IntSort())
s=Solver()
s.add(x>=0)
s.add(y>0)
s.add(ForAll(n1,Implies(n1==0,r(0)==x)))
s.add(ForAll(n1,Implies(n1==0,q(0)==0)))
s.add(ForAll(n1,Implies(n1>0,r(n1+1)==r(n1)-(2*y))))
s.add(ForAll(n1,Implies(n1>0,q(n1+1)==q(n1)+(2))))
s.add(x==q(k)*y+r(k))
s.add(not(2*x==q(k+1)*y+r(k+1)))
if sat==s.check():
print s.check()
print s.model()
else :
print s.check()
Looking forward to Suggestions.
My suggestion is to use replace the built-in not operator by the Z3 function called Not, e.g.
not(2*x==q(k+1)*y+r(k+1))
is simplified to False by Python before Z3 gets to see it, while
Not(2*x==q(k+1)*y+r(k+1))
has the desired meaning.

How to produce the model for partial orders?

I am trying to use Z3 to produce a model for a set of SAT assertions describing a partial order theory. I tried the subtype example in Z3 guide but it seems I cannot get a concrete model. Is there a way that Z3 can produce a model that describes the orders among elements and satisfies all assertions I made?
For example, following are the constraints for "subtype". Is it possible that Z3 may produce a model like "int-type *<* real-type *<* complex-type *<* obj-type *<* root-type" and "string-type *<* obj-type *<* root-type" (if I use "*<*" to denote subtype relation)?
(set-option :produce-models true)
(declare-sort Type)
(declare-fun subtype (Type Type) Bool)
(assert (forall ((x Type)) (subtype x x)))
(assert (forall ((x Type) (y Type))
(=> (and (subtype x y) (subtype y x))
(= x y))))
(assert (forall ((x Type) (y Type) (z Type))
(=> (and (subtype x y) (subtype y z))
(subtype x z))))
(assert (forall ((x Type) (y Type) (z Type))
(=> (and (subtype x y) (subtype x z))
(or (subtype y z) (subtype z y)))))
(declare-const obj-type Type)
(declare-const int-type Type)
(declare-const real-type Type)
(declare-const complex-type Type)
(declare-const string-type Type)
(assert (forall ((x Type)) (subtype x obj-type)))
(assert (subtype int-type real-type))
(assert (subtype real-type complex-type))
(assert (not (subtype string-type real-type)))
(declare-const root-type Type)
(assert (subtype obj-type root-type))
(check-sat)
(get-model)
Currently, I got
sat
(model
;; universe for Type:
;; Type!val!0 Type!val!3 Type!val!2 Type!val!4 Type!val!1
;; -----------
;; definitions for universe elements:
(declare-fun Type!val!0 () Type)
(declare-fun Type!val!3 () Type)
(declare-fun Type!val!2 () Type)
(declare-fun Type!val!4 () Type)
(declare-fun Type!val!1 () Type)
;; cardinality constraint:
(forall ((x Type))
(or (= x Type!val!0)
(= x Type!val!3)
(= x Type!val!2)
(= x Type!val!4)
(= x Type!val!1)))
;; -----------
(define-fun complex-type () Type
Type!val!2)
(define-fun real-type () Type
Type!val!1)
(define-fun obj-type () Type
Type!val!4)
(define-fun root-type () Type
Type!val!4)
(define-fun string-type () Type
Type!val!3)
(define-fun int-type () Type
Type!val!0)
(define-fun subtype!73 ((x!1 Type) (x!2 Type)) Bool
(ite (and (= x!1 Type!val!3) (= x!2 Type!val!1)) false
(ite (and (= x!1 Type!val!2) (= x!2 Type!val!3)) false
(ite (and (= x!1 Type!val!4) (= x!2 Type!val!1)) false
(ite (and (= x!1 Type!val!4) (= x!2 Type!val!3)) false
(ite (and (= x!1 Type!val!2) (= x!2 Type!val!1)) false
(ite (and (= x!1 Type!val!1) (= x!2 Type!val!3)) false
(ite (and (= x!1 Type!val!4) (= x!2 Type!val!0)) false
(ite (and (= x!1 Type!val!4) (= x!2 Type!val!2)) false
(ite (and (= x!1 Type!val!0) (= x!2 Type!val!3)) false
(ite (and (= x!1 Type!val!2) (= x!2 Type!val!0)) false
(ite (and (= x!1 Type!val!1) (= x!2 Type!val!0)) false
(ite (and (= x!1 Type!val!3) (= x!2 Type!val!0)) false
true)))))))))))))
(define-fun k!72 ((x!1 Type)) Type
(ite (= x!1 Type!val!1) Type!val!1
(ite (= x!1 Type!val!4) Type!val!4
(ite (= x!1 Type!val!3) Type!val!3
(ite (= x!1 Type!val!0) Type!val!0
Type!val!2)))))
(define-fun subtype ((x!1 Type) (x!2 Type)) Bool
(subtype!73 (k!72 x!1) (k!72 x!2)))
)
Thank you in advance for any help you could give.
I think that your line
(assert (forall ((x Type)) (subtype x obj-type)))
is wrong.
The correct is
(assert (forall ((x Type)) (subtype x root-type)))
The possible correct model is obtained here

Sort name issue in Z3

In a previous post Z3 group some group axioms were proved using a sort named S to represent the group. Please run the code code with sort named S But now when the name of the sort is changed to G the code does not work. Please look the issue on line code with sort named G It is necessary to use the name S for the sort or it is an issue of Z3? Please let me know.
A simplified version of the issue.
$ z3 -version
Z3 version 4.3.1
Using the name S:
$ cat S.smt
(declare-sort S)
(declare-fun f (S S) S)
(declare-const a S)
(declare-const b S)
(assert (= (f a a) a))
(assert (= (f a b) b))
(assert (= (f b a) b))
(assert (= (f b b) a))
(check-sat)
;; Restrict the search to models of size at most 2.
(assert (forall ((x S)) (or (= x a) (= x b))))
;; Associativity
(assert (not (forall ((x S) (y S) (z S)) (= (f x (f y z)) (f (f x y) z)))))
(check-sat)
$ z3 -smt2 S.smt
sat
unsat
Using the name G:
$ cat G.smt
(declare-sort G)
(declare-fun f (G G) G)
(declare-const a G)
(declare-const b G)
(assert (= (f a a) a))
(assert (= (f a b) b))
(assert (= (f b a) b))
(assert (= (f b b) a))
(check-sat)
;; Restrict the search to models of size at most 2
(assert (forall ((x G)) (or (= x a) (= x b))))
;; Associativity
(assert (not (forall ((x G) (y G) (z G)) (= (f x (f y z)) (f (f x y) z)))))
(check-sat)
$ z3 -smt2 G.smt
sat
unknown
Please let ne know if the following code with the sort named G is correct. Many thanks
(declare-sort G)
(declare-fun f (G G) G)
(declare-const a G)
(declare-const b G)
(declare-const c G)
(assert (forall ((x G) (y G))
(= (f x y) (f y x))))
(assert (forall ((x G))
(= (f x a) x)))
(assert (= (f b b) c))
(assert (= (f b c) a))
(assert (= (f c c) b))
(check-sat)
(get-model)
(push)
;; prove the left-module axiom
(assert (not (forall ((x G)) (= (f a x) x ))) )
(check-sat)
(pop)
(push)
;; prove the right-module axiom
(assert (not (forall ((x G)) (= (f x a) x ))) )
(check-sat)
(pop)
(declare-fun x () G)
(declare-fun y () G)
(declare-fun z () G)
(push)
;; prove the right-inverse axiom
(assert (not (=> (and (or (= x a) (= x b) (= x c))) (exists ((y G)) (= (f x y) a)))))
(check-sat)
(pop)
(push)
;; prove the left-inverse axiom
(assert (not (=> (and (or (= x a) (= x b) (= x c))) (exists ((y G)) (= (f y x ) a)))))
(check-sat)
(pop)
(push)
;; prove the associativity axiom
(assert (not (=> (and (or (= x a) (= x b) (= x c)) (or (= y a) (= y b) (= y c))
(or (= z a) (= z b) (= z c)))
(= (f x (f y z)) (f (f x y) z)))))
(check-sat)
(pop)
(push)
;; prove the commutative property
(assert (not (=> (and (or (= x a) (= x b) (= x c)) (or (= y a) (= y b) (= y c)))
(= (f x y ) (f y x )))))
(check-sat)
(pop)
and the corresponding output is the expected
sat unsat unsat unsat unsat unsat unsat
Please run this code online here

Resources