Search code examples
pythonz3smtz3py

Z3Py: Create model object


I would like to create a Z3 model object such as the one that is returned by (get-model)/s.model() with s = Solver(). I am starting with a list of tuples (name, value) where name is a string representing the Z3 variable that is used in the model and value the value that is assigned to the variable (real or Boolean). So something like

def myZ3Model(tuples):
    """ Returns a Z3 model based on the values of the given tuples. """
    <magic>
    return model

t = [('a', True), ('b', 42), ('c', False)]
myZ3Model(t) --> [a = True, b = 42, c = False]

I already came up with a quite 'hacky' way to do this: Initialize a formula that is the conjunction of all the variables equal to their assigned values and let a solver return a model for this formula. However, I would like to know if there is a more elegant way to achieve my goal...


Solution

  • This is a rather bizarre thing to do. Models are results of calls to the solver. You seem to want to be able to create a model out of thin air with no constraints to solve?

    Having said that, this is just programming after all, and you can surely create such constraints from your list, ask Z3 to solve them. This would do what you are asking for:

    from z3 import *
    
    def myZ3Model(tuples):
        s = Solver()
    
        for (n, v) in tuples:
            if isinstance(v, bool):
                s.add(Bool(n) == v)
            else:
                s.add(Real(n) == v)
    
        s.check()
        return s.model() 
    

    With this definition, you can now say:

    t = [('a', True), ('b', 42), ('c', False)]
    print myZ3Model(t)
    

    which will do what you want. A few caveats:

    • The construction only supports Bool and Real as you specified, clearly needs to be extended if you want other types.

    • Note that the code does involve solving the constraints as specified: This should have no performance penalties as the constraints will always be trivial to satisfy. But you still end up calling the solver.