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))
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))
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))
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))
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}'
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)),)
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)) + '}'
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