Exemple #1
0
def to_command(model: ModelRef, before: EncodedState,
               after: EncodedState) -> Command:
    for p in before.keys():
        installed_before = bool(model.eval(before[p]))
        installed_after = bool(model.eval(after[p]))

        if (not installed_before) and installed_after:
            return Command(CommandSort.INSTALL, p)
        elif installed_before and (not installed_after):
            return Command(CommandSort.UNINSTALL, p)
    return None
Exemple #2
0
def extract_model(m: z3.ModelRef, sig: Signature, label: str = "") -> Model:
    M = Model(sig)
    M.label = label
    z3_to_model_elems = {}
    # add elements
    for sort in sorted(sig.sorts):
        univ = m.get_universe(sorts_to_z3[sort])
        assert len(univ) > 0
        for e in sorted(univ, key=str):
            z3_to_model_elems[str(e)] = M.add_elem(str(e), sort)
    # assign constants
    for const, sort in sorted(sig.constants.items()):
        M.add_constant(
            const,
            str(
                m.eval(z3.Const(const, sorts_to_z3[sort]),
                       model_completion=True)))
    # assign relations
    for rel, sorts in sorted(sig.relations.items()):
        univs = [m.get_universe(sorts_to_z3[s]) for s in sorts]
        for t in itertools.product(*univs):
            ev = m.eval(z3_rel_func[rel](*t), model_completion=True)
            if ev:
                M.add_relation(rel, [str(x) for x in t])
    for func, (sorts, _) in sorted(sig.functions.items()):
        univs = [m.get_universe(sorts_to_z3[s]) for s in sorts]
        for t in itertools.product(*univs):
            ev = m.eval(z3_rel_func[func](*t), model_completion=True)
            M.add_function(func, [str(x) for x in t], str(ev))
    return M
Exemple #3
0
 def _solution_from_model(self, model: z3.ModelRef) -> SchedulingSolution:
     plan: List[Set[BehaviorInstance]] = [
         set() for _ in range(self._n_steps)
     ]
     for s in self._sequences.values():
         for i, b in enumerate(s):
             bhv_fun = self._bhv_dt.get_constructor(
                 b.component_instance().id() + "_" + b.behavior().name() +
                 "_" + str(i))
             step = model.eval(self._toint_fun.z3_func()(
                 self._schedule_fun.z3_func()(
                     bhv_fun.z3_func()))).as_long()
             plan[step].add(b)
     return SchedulingSolution(plan)
Exemple #4
0
    def model_to_first_order_structure(
            z3model: z3.ModelRef) -> FirstOrderStructure:
        '''
        Convert z3 model to a BareFirstOrderStructure.

        Note that all declarations of the bare structure are not
        related to the program's declarations.
        '''
        assert isinstance(z3model, z3.ModelRef), f'{type(z3model)}\n{z3model}'
        struct = BareFirstOrderStructure({}, {}, {}, {})

        # create universe

        sorts: Dict[str, Sort] = {
            'Bool': BoolSort,
            'Int': IntSort,
        }
        sort_decls: Dict[Sort, SortDecl] = {
        }  # TODO: remove once Universe maps sorts and not SortDecls
        elements: Dict[Tuple[Sort, z3.ExprRef], Element] = {}
        z3elements: Dict[Tuple[Sort, Element], z3.ExprRef] = {}
        for z3sort in sorted(z3model.sorts(), key=str):
            z3elems = sorted(z3model.get_universe(z3sort), key=str)
            name = z3sort.name()
            sort = UninterpretedSort(name)
            sort.decl = SortDecl(name)
            sorts[sort.name] = sort
            sort_decls[sort] = sort.decl
            struct.univs[sort.decl] = ()
            for i, x in enumerate(z3elems):
                e = f'{sort.name}{i}'  # TODO: someday this will just be i
                assert (sort, x) not in elements, (sort, i, x, e)
                elements[sort, x] = e
                assert (sort, e) not in z3elements, (sort, i, x, e)
                z3elements[sort, e] = x
                struct.univs[sort.decl] += (e, )

        # interpret relations, constants, functions

        def _eval_bool(expr: z3.ExprRef) -> bool:
            assert z3.is_bool(expr), expr
            ans = z3model.eval(expr, model_completion=True)
            assert z3.is_bool(ans), (expr, ans)
            return bool(ans)

        def _eval_int(expr: z3.ExprRef) -> str:  # TODO: this should return int
            assert z3.is_int(expr), expr
            ans = z3model.eval(expr, model_completion=True)
            assert z3.is_int_value(ans), (expr, ans)
            return str(ans.as_long())

        def _eval_elem(sort: Sort) -> Callable[[z3.ExprRef], Element]:
            def _eval(expr: z3.ExprRef) -> Element:
                assert sorts[expr.sort().name()] is sort, expr
                ans = z3model.eval(expr, model_completion=True)
                assert (sort, ans) in elements, (sort, expr, ans)
                return elements[sort, ans]

            return _eval

        for z3decl in sorted(z3model.decls(), key=str):
            name = z3decl.name()
            dom = tuple(sorts[z3decl.domain(i).name()]
                        for i in range(z3decl.arity()))
            rng = sorts[z3decl.range().name()]
            decl: Union[RelationDecl, ConstantDecl, FunctionDecl]
            if rng is BoolSort:
                decl = RelationDecl(name, tuple(dom), mutable=False)
            elif len(dom) == 0:
                decl = ConstantDecl(name, rng, mutable=False)
            else:
                decl = FunctionDecl(name, tuple(dom), rng, mutable=False)

            _eval: Callable[[z3.ExprRef], Union[bool, int, Element]]
            if rng is BoolSort:
                _eval = _eval_bool
            elif rng is IntSort:
                _eval = _eval_int
            elif isinstance(rng, UninterpretedSort):
                _eval = _eval_elem(rng)
            else:
                assert False, (decl, rng)
            domains = [struct.univs[sort_decls[sort]] for sort in dom]
            fi = {
                row: _eval(
                    z3decl(*(z3elements[sort, e]
                             for sort, e in zip(dom, row))))
                for row in product(*domains)
            }
            if isinstance(decl, RelationDecl):
                assert decl not in struct.rel_interps
                assert all(isinstance(v, bool) for v in fi.values())
                assert all(
                    len(k) == len(dom) and all(
                        e in struct.univs[sort_decls[sort]]
                        for e, sort in zip(k, dom)) for k in fi.keys())
                struct.rel_interps[decl] = cast(RelationInterp, fi)
            elif isinstance(decl, FunctionDecl):
                assert decl not in struct.func_interps
                assert all(isinstance(v, Element) for v in fi.values())
                if isinstance(rng, UninterpretedSort):
                    assert all(v in struct.univs[sort_decls[rng]]
                               for v in fi.values())
                elif rng is IntSort:
                    assert all(isinstance(int(v), int) for v in fi.values())
                else:
                    assert False, (decl, rng)
                assert all(
                    len(k) == len(dom) and all(
                        e in struct.univs[sort_decls[sort]]
                        for e, sort in zip(k, dom)) for k in fi.keys())
                struct.func_interps[decl] = cast(FunctionInterp, fi)
            elif isinstance(decl, ConstantDecl):
                assert decl not in struct.const_interps
                assert list(fi.keys()) == [()]
                v = fi[()]
                assert isinstance(v, Element)
                if isinstance(rng, UninterpretedSort):
                    assert v in struct.univs[sort_decls[rng]]
                elif rng is IntSort:
                    assert isinstance(int(v), int)
                else:
                    assert False, (decl, rng)
                struct.const_interps[decl] = cast(Element, fi[()])

        return struct
Exemple #5
0
    def _old_model_to_trace(z3model: z3.ModelRef,
                            num_states: int,
                            allow_undefined: bool = False) -> Trace:
        '''
        Convert z3 model to Trace with given number of states.

        If allow_undefined is True, the resulting trace may leave some symbols undefined.
        '''
        trace = Trace(num_states)
        keys = Z3Translator._get_keys(num_states)

        def rename(s: str) -> str:
            return s.replace('!val!', '').replace('@uc_', '')

        def _eval(expr: z3.ExprRef) -> z3.ExprRef:
            ans = z3model.eval(expr, model_completion=True)
            assert bool(ans) is True or bool(ans) is False, (expr, ans)
            return ans

        prog = syntax.the_program

        for z3sort in sorted(z3model.sorts(), key=str):
            sort = prog.scope.get_sort(str(z3sort))
            assert sort is not None
            univ = z3model.get_universe(z3sort)
            trace.univs[sort] = tuple(sorted(rename(str(x)) for x in univ))

        model_decls = z3model.decls()
        all_decls = model_decls
        for z3decl in sorted(all_decls, key=str):
            z3name = str(z3decl)
            for i, k in enumerate(keys):
                if z3name.startswith(k):
                    name = z3name[len(k + '_'):]
                    R = trace.rel_interps[i]
                    C = trace.const_interps[i]
                    F = trace.func_interps[i]
                    break
            else:
                name = z3name
                R = trace.immut_rel_interps
                C = trace.immut_const_interps
                F = trace.immut_func_interps

            decl = prog.scope.get(name)
            assert not isinstance(decl, syntax.Sort) and \
                not isinstance(decl, syntax.SortInferencePlaceholder)
            if decl is not None:
                if isinstance(decl, RelationDecl):
                    if decl.arity:
                        rl: RelationInterp = {}
                        domains = [
                            z3model.get_universe(z3decl.domain(i))
                            for i in range(z3decl.arity())
                        ]
                        if not any(x is None for x in domains):
                            # Note: if any domain is None, we silently drop this symbol.
                            # It's not entirely clear that this is an ok thing to do.
                            g = product(*domains)
                            for row in g:
                                relation_expr = z3decl(*row)
                                ans = _eval(relation_expr)
                                rl[tuple(rename(str(col))
                                         for col in row)] = bool(ans)
                            assert decl not in R
                            R[decl] = rl
                    else:
                        ans = z3model.eval(z3decl())
                        assert decl not in R
                        R[decl] = {(): bool(ans)}
                elif isinstance(decl, FunctionDecl):
                    fl: FunctionInterp = {}
                    domains = [
                        z3model.get_universe(z3decl.domain(i))
                        for i in range(z3decl.arity())
                    ]
                    if not any(x is None for x in domains):
                        # Note: if any domain is None, we silently drop this symbol.
                        # It's not entirely clear that this is an ok thing to do.
                        g = product(*domains)
                        for row in g:
                            ans = z3model.eval(z3decl(*row))
                            if z3.is_int_value(ans):
                                ans_str = str(ans.as_long())
                            else:
                                ans_str = rename(ans.decl().name())

                            fl[tuple(rename(str(col))
                                     for col in row)] = ans_str
                        assert decl not in F
                        F[decl] = fl
                else:
                    assert isinstance(decl, ConstantDecl)
                    v = z3model.eval(z3decl())
                    if z3.is_int_value(v) or isinstance(v, CVC4Int):
                        v_str = str(v.as_long())
                    else:
                        v_str = rename(v.decl().name())

                    assert decl not in C
                    C[decl] = v_str
            else:
                if name.startswith(TRANSITION_INDICATOR +
                                   '_') and z3model.eval(z3decl()):
                    name = name[len(TRANSITION_INDICATOR + '_'):]
                    istr, name = name.split('_', maxsplit=1)
                    i = int(istr)
                    if i < len(trace.transitions):
                        trace.transitions[i] = name
                    else:
                        # TODO: not sure what's going on here with check_bmc and pd.check_k_state_implication
                        # assert False
                        pass

        if allow_undefined:
            return trace

        def get_univ(d: SortDecl) -> Tuple[Element, ...]:
            if d not in trace.univs:
                trace.univs[d] = (d.name + '0', )
            return trace.univs[d]

        def arbitrary_interp_r(r: RelationDecl) -> RelationInterp:
            doms = [get_univ(syntax.get_decl_from_sort(s)) for s in r.arity]
            return dict.fromkeys(product(*doms), False)

        def ensure_defined_r(r: RelationDecl) -> None:
            arb_interp: Optional[RelationInterp] = None
            for m in (trace.rel_interps
                      if r.mutable else [trace.immut_rel_interps]):
                if r not in m:
                    if arb_interp is None:
                        arb_interp = arbitrary_interp_r(r)
                    m[r] = arb_interp

        def arbitrary_interp_c(c: ConstantDecl) -> Element:
            if isinstance(c.sort, syntax._BoolSort):
                return 'false'
            elif isinstance(c.sort, syntax._IntSort):
                return '0'
            assert isinstance(c.sort, syntax.UninterpretedSort)
            sort = c.sort
            return get_univ(syntax.get_decl_from_sort(sort))[0]

        def ensure_defined_c(c: ConstantDecl) -> None:
            arb_interp = arbitrary_interp_c(c)
            for m in (trace.const_interps
                      if c.mutable else [trace.immut_const_interps]):
                if c not in m:
                    m[c] = arb_interp

        def arbitrary_interp_f(f: FunctionDecl) -> FunctionInterp:
            doms = [get_univ(syntax.get_decl_from_sort(s)) for s in f.arity]
            image = get_univ(syntax.get_decl_from_sort(f.sort))[0]
            return dict.fromkeys(product(*doms), image)

        def ensure_defined_f(f: FunctionDecl) -> None:
            arb_interp: Optional[FunctionInterp] = None
            for m in (trace.func_interps
                      if f.mutable else [trace.immut_func_interps]):
                if f not in m:
                    if arb_interp is None:
                        arb_interp = arbitrary_interp_f(f)
                    m[f] = arb_interp

        for decl in prog.relations_constants_and_functions():
            if isinstance(decl, RelationDecl):
                ensure_defined_r(decl)
            elif isinstance(decl, ConstantDecl):
                ensure_defined_c(decl)
            elif isinstance(decl, FunctionDecl):
                ensure_defined_f(decl)
            else:
                assert False, decl

        return trace
Exemple #6
0
def answer_key(m: ModelRef, L) -> int:
    res = 0
    for l in L:
        res *= 10
        res += m.evaluate(l).as_long()
    return res
Exemple #7
0
 def evaluate(self, m: z3.ModelRef):
     timeslot = m.eval(self.time()).as_long()
     room = m.eval(self.room()).as_long()
     lab = None if not self.labs else m.eval(self.lab()).as_long()
     return {'name': str(self), 'time': timeslot, 'room': room, 'lab': lab, 'faculty': self.faculty}