def as_onestate_formula(self, index: Optional[int] = None) -> Expr:
        # TODO: move to class State, this shouldn't be here
        assert self.num_states == 1 or index is not None, \
            'to generate a onestate formula from a multi-state model, ' + \
            'you must specify which state you want'
        assert index is None or (0 <= index and index < self.num_states)

        if index is None:
            index = 0

        if index not in self.onestate_formula_cache:
            prog = syntax.the_program

            mut_rel_interps = self.rel_interps[index]
            mut_const_interps = self.const_interps[index]
            mut_func_interps = self.func_interps[index]

            vs: List[syntax.SortedVar] = []
            ineqs: Dict[SortDecl, List[Expr]] = {}
            rels: Dict[RelationDecl, List[Expr]] = {}
            consts: Dict[ConstantDecl, Expr] = {}
            funcs: Dict[FunctionDecl, List[Expr]] = {}
            for sort in self.univs:
                vs.extend(syntax.SortedVar(v, syntax.UninterpretedSort(sort.name))
                          for v in self.univs[sort])
                u = [syntax.Id(v) for v in self.univs[sort]]
                ineqs[sort] = [syntax.Neq(a, b) for a, b in combinations(u, 2)]
            for R, l in chain(mut_rel_interps.items(), self.immut_rel_interps.items()):
                rels[R] = []
                for tup, ans in l.items():
                    e: Expr = (
                        syntax.AppExpr(R.name, tuple(syntax.Id(col) for col in tup))
                        if tup else syntax.Id(R.name)
                    )
                    rels[R].append(e if ans else syntax.Not(e))
            for C, c in chain(mut_const_interps.items(), self.immut_const_interps.items()):
                consts[C] = syntax.Eq(syntax.Id(C.name), syntax.Id(c))
            for F, fl in chain(mut_func_interps.items(), self.immut_func_interps.items()):
                funcs[F] = [
                    syntax.Eq(syntax.AppExpr(F.name, tuple(syntax.Id(col) for col in tup)),
                              syntax.Id(res))
                    for tup, res in fl.items()
                ]

            # get a fresh variable, avoiding names of universe elements in vs
            fresh = prog.scope.fresh('x', [v.name for v in vs])

            e = syntax.Exists(tuple(vs), syntax.And(
                *chain(*ineqs.values(), *rels.values(), consts.values(), *funcs.values(), (
                    syntax.Forall((syntax.SortedVar(fresh,
                                                    syntax.UninterpretedSort(sort.name)),),
                                  syntax.Or(*(syntax.Eq(syntax.Id(fresh), syntax.Id(v))
                                              for v in self.univs[sort])))
                    for sort in self.univs
                ))))
            assert prog.scope is not None
            with prog.scope.n_states(1):
                typechecker.typecheck_expr(prog.scope, e, None)
            self.onestate_formula_cache[index] = e
        return self.onestate_formula_cache[index]
    def _read_first_order_structure(
            struct: FirstOrderStructure
    ) -> Tuple[List[syntax.SortedVar],  # vs
               Dict[SortDecl, List[Expr]],  # ineqs
               Dict[RelationDecl, List[Expr]],  # rels
               Dict[ConstantDecl, Expr],  # consts
               Dict[FunctionDecl, List[Expr]],  # funcs
               ]:
        vars_by_sort: Dict[SortDecl, List[syntax.SortedVar]] = {}
        ineqs: Dict[SortDecl, List[Expr]] = {}
        rels: Dict[RelationDecl, List[Expr]] = {}
        consts: Dict[ConstantDecl, Expr] = {}
        funcs: Dict[FunctionDecl, List[Expr]] = {}
        for sort in struct.univs:
            vars_by_sort[sort] = [
                syntax.SortedVar(v, syntax.UninterpretedSort(sort.name))
                for v in struct.univs[sort]
            ]
            u = [syntax.Id(s) for s in struct.univs[sort]]
            ineqs[sort] = [
                syntax.Neq(a, b) for a, b in itertools.combinations(u, 2)
            ]

        for R, l in struct.rel_interps.items():
            rels[R] = []
            for tup, ans in l.items():
                e: Expr
                if tup:
                    args: List[Expr] = []
                    for (col, col_sort) in zip(tup, R.arity):
                        assert isinstance(col_sort, syntax.UninterpretedSort)
                        assert col_sort.decl is not None
                        args.append(syntax.Id(col))
                    e = syntax.AppExpr(R.name, tuple(args))
                else:
                    e = syntax.Id(R.name)
                e = e if ans else syntax.Not(e)
                rels[R].append(e)
        for C, c in struct.const_interps.items():
            e = syntax.Eq(syntax.Id(C.name), syntax.Id(c))
            consts[C] = e
        for F, fl in struct.func_interps.items():
            funcs[F] = []
            for tup, res in fl.items():
                e = syntax.AppExpr(F.name,
                                   tuple(syntax.Id(col) for col in tup))
                e = syntax.Eq(e, syntax.Id(res))
                funcs[F].append(e)

        vs = list(itertools.chain(*(vs for vs in vars_by_sort.values())))

        return vs, ineqs, rels, consts, funcs
Beispiel #3
0
def p_expr_app(p: Any) -> None:
    'expr : id LPAREN args RPAREN'
    p[0] = syntax.AppExpr(p[1], p[1].value, p[3])
Beispiel #4
0
 def as_expr(self, els_trans: Callable[[str],str]) -> Expr:
     e = syntax.AppExpr(None, self._func.name, [syntax.Id(None, els_trans(e)) for e in self._params_els])
     return syntax.Eq(e, syntax.Id(None, els_trans(self._res_elm)))
Beispiel #5
0
def p_expr_app(p: Any) -> None:
    'expr : id LPAREN args RPAREN'
    callee_tok = p[1]
    args: List[syntax.Expr] = p[3]
    p[0] = syntax.AppExpr(callee_tok.value, args, span=loc_join(callee_tok, p.slice[4]))
Beispiel #6
0
def p_expr_app(p: Any) -> None:
    'expr : id primes LPAREN args RPAREN'
    callee_tok = p[1]
    primes = p[2]
    args: Tuple[syntax.Expr, ...] = p[4]
    p[0] = syntax.AppExpr(callee_tok.value, args, primes, span=loc_join(callee_tok, p.slice[5]))