Beispiel #1
0
def option_printer(state: State, s: SortDecl, elt: str, args: List[str]) -> str:
    assert len(args) == 2
    is_none_name, value_name = args
    is_none = get_relation(is_none_name)
    value = get_function(value_name)

    option_sort = UninterpretedSort(None, s.name)

    assert not is_none.mutable and not value.mutable and \
        is_none.arity == [option_sort] and value.arity == [option_sort]

    elt_sort = syntax.get_decl_from_sort(value.sort)

    none: Optional[str] = None
    for tup, b in state.rel_interp[is_none]:
        if b:
            assert none is None and len(tup) == 1
            none = tup[0]

    assert none is not None

    if elt == none:
        return 'None'
    else:
        the_value: Optional[str] = None
        for tup, res in state.func_interp[value]:
            assert len(tup) == 1
            if tup[0] == elt:
                assert the_value is None
                the_value = res
        assert the_value is not None

        return 'Some(%s)' % (logic.print_element(state, elt_sort, the_value))
Beispiel #2
0
def option_printer(struct: FirstOrderStructure, s: SortDecl, elt: str,
                   args: List[str]) -> str:
    assert len(args) == 2
    is_none_name, value_name = args
    is_none = get_relation(is_none_name)
    value = get_function(value_name)

    option_sort = UninterpretedSort(s.name)

    assert not is_none.mutable and not value.mutable and \
        is_none.arity == (option_sort,) and value.arity == (option_sort,)

    elt_sort = syntax.get_decl_from_sort(value.sort)

    none: Optional[str] = None
    for tup, b in struct.rel_interps[is_none].items():
        if b:
            assert none is None and len(tup) == 1
            none = tup[0]

    assert none is not None

    if elt == none:
        return 'None'
    else:
        the_value: Optional[str] = None
        for tup, res in struct.func_interps[value].items():
            assert len(tup) == 1
            if tup[0] == elt:
                assert the_value is None
                the_value = res
        assert the_value is not None

        return 'Some(%s)' % (print_element(struct, elt_sort, the_value))
Beispiel #3
0
def ordered_by_printer(struct: FirstOrderStructure, sortdecl: SortDecl,
                       elt: str, args: List[str]) -> str:
    assert len(args) == 1
    order_name = args[0]
    order = get_relation(order_name)
    us = UninterpretedSort(sortdecl.name)
    assert order.arity == (us, us) and not order.mutable
    old_error_count = utils.error_count
    solve = solver.Solver()
    thm_expr_strs = [
        (f'{order_name}(X, X)', 'reflexive'),
        (f'{order_name}(X, Y) & {order_name}(Y, X) -> X = Y', 'antisymmetric'),
        (f'{order_name}(X, Y) & {order_name}(Y, Z) -> {order_name}(X, Z)',
         'transitive'),
        (f'{order_name}(X, Y) & {order_name}(X, Y) -> {order_name}(Y, Z) | {order_name}(Z, Y)',
         'semi-linear'),
    ]
    for e_str, prop_name in thm_expr_strs:
        e = logic.parse_and_typecheck_expr(e_str, close_free_vars=True)
        th = syntax.TheoremDecl(name=None, expr=e, num_states=0)
        if (m := logic.check_theorem(th, solve, verbose=False)) is not None:
            utils.error_count += 1
            utils.logger.always_print(
                f'warning: relation {order_name} is not {prop_name}')
            utils.logger.always_print(f'info: try adding "axiom {e_str}"')
            utils.logger.always_print('info: see counterexample below')
            sortdecl.annotations = ()
            utils.logger.always_print(str(m))
Beispiel #4
0
def ordered_by_printer(state: State, s: SortDecl, elt: str, args: List[str]) -> str:
    assert len(args) == 1
    order_name = args[0]
    order = get_relation(order_name)
    us = UninterpretedSort(None, s.name)
    assert order.arity == [us, us] and not order.mutable

    return '%s%s' % (s.name, get_ordinal(state, order, elt))
Beispiel #5
0
def ordered_by_printer(struct: FirstOrderStructure, s: SortDecl, elt: str,
                       args: List[str]) -> str:
    assert len(args) == 1
    order_name = args[0]
    order = get_relation(order_name)
    us = UninterpretedSort(s.name)
    assert order.arity == (us, us) and not order.mutable
    ordinal = get_ordinal(struct.rel_interps[order], elt)
    return f'{s.name}{ordinal}'
Beispiel #6
0
def set_printer(state: State, s: SortDecl, elt: str, args: List[str]) -> str:
    assert len(args) == 1
    member_name = args[0]
    member = get_relation(member_name)

    assert len(member.arity) == 2 and not member.mutable
    set_sort = UninterpretedSort(None, s.name)
    assert member.arity[1] == set_sort
    item_sort = member.arity[0]
    item_sort_decl = syntax.get_decl_from_sort(item_sort)

    items: Set[str] = set()
    for tup, b in state.rel_interp[member]:
        assert len(tup) == 2
        item, set_id = tup
        if b and set_id == elt:
            items.add(item)

    return '{%s}' % (','.join(sorted(logic.print_element(state, item_sort_decl, x) for x in items)),)
Beispiel #7
0
def set_printer(struct: FirstOrderStructure, s: SortDecl, elt: str,
                args: List[str]) -> str:
    assert len(args) == 1
    member_name = args[0]
    member = get_relation(member_name)

    assert len(member.arity) == 2 and not member.mutable
    set_sort = UninterpretedSort(s.name)
    assert member.arity[1] == set_sort
    item_sort = member.arity[0]
    item_sort_decl = syntax.get_decl_from_sort(item_sort)

    items: Set[str] = set()
    for tup, b in struct.rel_interps[member].items():
        assert len(tup) == 2
        item, set_id = tup
        if b and set_id == elt:
            items.add(item)

    return '{' + ','.join(
        sorted(print_element(struct, item_sort_decl, x) for x in items)) + '}'
Beispiel #8
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