问题
As an extension to a previous Z3-related question Using Resolution theorem proving with Z3 and built on top of @alias 's answer at https://stackoverflow.com/a/62721185/13861050
I've added a few more functions and relations:
FEMALE = Function('FEMALE', Thing, BoolSort())
ANIMAL = Function('ANIMAL', Thing, BoolSort())
LIVING_THING = Function('LIVING_THING', Thing, BoolSort())
ENTITY = Function('ENTITY', Thing, BoolSort())
s.add(ForAll([x], Implies(WOMAN(x), FEMALE(x))))
s.add(ForAll([x], Implies(LIVING_THING(x), ENTITY(x))))
s.add(ForAll([x], Implies(ANIMAL(x), LIVING_THING(x))))
s.add(ForAll([x], Implies(WOMAN(x), ANIMAL(x))))
So my question is: Is there a shorter (but still performant / computationally efficient) way of specifying hierarchical relations such as s.add(ForAll([x], Implies(ANIMAL(x), LIVING_THING(x))))
. I mean something like s.add(LIVING_THING(ANIMAL))
which currently doesn't work because the argument ANIMAL
is a function.
Also, I'd like to specify certain properties to some functions such as being symmetric (as a more basic case). I've defined:
isMarriedTo = Function('isMarriedTo', Thing, Thing, BoolSort())
loves = Function('loves', Thing, Thing, BoolSort())
s.add(ForAll([x, y], Implies(SAMEWEIGHT(x, y), SAMEWEIGHT(y, x))))
s.add(ForAll([x, y], Implies(isMarriedTo(x, y), isMarriedTo(y, x))))
s.add(ForAll([x, y], Implies(loves(x, y), loves(y, x))))
The last two constraints basically mean that both the functions SAMEWEIGHT
, isMarriedTo
and loves
are symmetric. So Is there a more elegant way of specifying the symmetric property (and in the future, many other such meta properties) for a list of functions, e.g. something like:
- SymmetricFunctionType is defined by
ForAll([x, y], Implies(SymmetricFunctionType(x, y), SymmetricFunctionType(y, x)))
- the functions
SAMEWEIGHT
,isMarriedTo
andloves
, etc. belong to the classSymmetricFunctionType
. In other words what's the idiomatic way of doing that in Z3?
回答1:
SMTLib is essentially a first-order logic. (More precisely, it's a first-order many-sorted logic.)
This pretty much disallows any construct that takes functions as arguments. So, you cannot write properties that say "this function is symmetric" or second order statements of the form LIVING_THING(ANIMAL)
where ANIMAL
is a function.
For most practical purposes, this doesn't impose too much of a restriction. Keep in mind that SMTLib is not really intended to be hand-written: It's usually used as an intermediate language: Some higher-level front-end generates SMTLib and translates results back, generating all the instances it needs as it makes progress. The same thing is true for polymorphism: You cannot write functions that "uniformly" work over different sorts, for instance. You have to write a separate instance for each case you need. (This is usually known as the process of monomorphisation.)
Another important point to make is that while SMTLib does allow quantifiers, the decidable fragment is usually the quantifier-free subset of combinations of logics. Once you throw quantifiers in, it's more likely that you'll start getting unknown
answers. If you want to reason with quantifiers, you're better off using a proper theorem prover like Isabelle, Coq, etc., all of which allow SMTLib as an engine that you can call to discharge goals.
SMTLib v3
Note that there's a new version of SMTLib that's currently being developed, which will include higher-order features directly in the language. In particular, the core logic will move to simply-typed higher-order logic, from the current many-sorted first-order logic. (Details: http://smtlib.cs.uiowa.edu/version3.shtml). Of course, this is a relatively new development, and it'll be a while before the standard settles and solvers start supporting these new features in a consistent way. So, some of what you are trying to do might indeed be possible in the (somewhat) near future. Currently, your only option is to create instances separately.
来源:https://stackoverflow.com/questions/62725916/z3-whats-a-more-convenient-and-efficient-method-for-defining-class-hierarchies