Ejemplo n.º 1
0
 def show_used_relations(self, clauses, both=False):
     self.current_concept_graph.clear_edges()
     rels = self.current_concept_graph.g.relations
     used = set(
         il.normalize_symbol(s)
         for s in lu.used_constants(clauses.to_formula()))
     for rel in rels:
         fmla = rel.formula
         if any(c in used and not c.name.startswith('@')
                for c in lu.used_constants(fmla)):
             self.current_concept_graph.show_relation(rel,
                                                      '+',
                                                      update=False)
             if both and not il.is_enumerated(fmla):
                 self.current_concept_graph.show_relation(rel,
                                                          '-',
                                                          update=False)
     need_update_relations = False
     for app in ilu.apps_clauses(clauses):
         if len(app.args) == 3 and il.is_numeral(app.args[0]):
             fmla = app.rep(app.args[0], il.Variable('X', app.args[1].sort),
                            il.Variable('Y', app.args[2].sort))
             concept = self.current_concept_graph.g.formula_to_concept(fmla)
             self.current_concept_graph.g.new_relation(concept)
             need_update_relations = True
             self.current_concept_graph.show_relation(concept,
                                                      '+',
                                                      update=False)
             if both:
                 self.current_concept_graph.show_relation(concept,
                                                          '-',
                                                          update=False)
     if need_update_relations:
         self.current_concept_graph.update_relations()
     self.current_concept_graph.update()
Ejemplo n.º 2
0
 def show_used_relations(self,clauses,both=False):
     rels = self.current_concept_graph.g.relations
     used = lu.used_constants(clauses.to_formula()) 
     for rel in rels:
         if any(c in used and not c.name.startswith('@')
                for c in lu.used_constants(rel.formula)):
             self.current_concept_graph.show_relation(rel,'+',update=False)
             if both:
                 self.current_concept_graph.show_relation(rel,'-',update=False)
     self.current_concept_graph.update()
Ejemplo n.º 3
0
 def show_used_relations(self, clauses, both=False):
     rels = self.current_concept_graph.g.relations
     used = lu.used_constants(clauses.to_formula())
     for rel in rels:
         if any(c in used and not c.name.startswith('@')
                for c in lu.used_constants(rel.formula)):
             self.current_concept_graph.show_relation(rel,
                                                      '+',
                                                      update=False)
             if both:
                 self.current_concept_graph.show_relation(rel,
                                                          '-',
                                                          update=False)
     self.current_concept_graph.update()
Ejemplo n.º 4
0
def sort_infer(term):
    res = concretize_sorts(term)
    for x in chain(lu.used_variables(res),lu.used_constants(res)):
        if lg.contains_topsort(x.sort) or lg.is_polymorphic(x.sort):
            raise IvyError(None,"cannot infer sort of {}".format(x))
#    print "sort_infer: res = {!r}".format(res)
    return res
Ejemplo n.º 5
0
def check_concretely_sorted(term,no_error=False,unsorted_var_names=()):
    for x in chain(lu.used_variables(term),lu.used_constants(term)):
        if lg.contains_topsort(x.sort) or lg.is_polymorphic(x.sort):
            if x.name not in unsorted_var_names:
                if no_error:
                    raise lg.SortError
                raise IvyError(None,"cannot infer sort of {} in {}".format(x,repr(term)))
Ejemplo n.º 6
0
def sort_infer(term):
    res = concretize_sorts(term)
    for x in chain(lu.used_variables(res),lu.used_constants(res)):
        if lg.contains_topsort(x.sort) or lg.is_polymorphic(x.sort):
            raise IvyError(None,"cannot infer sort of {} in {}".format(x,term))
#    print "sort_infer: res = {!r}".format(res)
    return res
Ejemplo n.º 7
0
    def standardize_action(self, f, nexvars, name):
        nexSet = set()
        for n in nexvars:
            nexSet.add(n)
            self.updated.add(n)

        cons = lgu.used_constants(f)
        subs = dict()
        evars = []
        for c in cons:
            if c in self.nex:
                if c not in nexSet:
                    subs[c] = self.nex2pre[c]
#             elif False and (c not in self.pre):
            elif c not in self.pre:
                if (not c.sort.dom) and (c.sort != lg.Boolean):
                    vname = "Vtmp" + c.name
                    #                     vname = vname.replace(":", "")
                    qv = lg.Var(vname, c.sort)
                    subs[c] = qv
                    evars.append(qv)
        action = f
        if len(subs) != 0:
            #            for k, v in subs.iteritems():
            #                print("\treplacing %s -> %s in %s" % (k, v, name))
            action = lgu.substitute(f, subs)
        if len(evars) != 0:
            action = lg.Exists(evars, action)
        return action
Ejemplo n.º 8
0
    def _get_witnesses(self, concept_name):
        # TODO: maybe this function should be in ConceptDomain? or Concept?
        """
        Return a list of constant that are witnesses for the given unary
        constant, or [] if none are found

        A witness is a constant c s.t. concept(x) implies x=c. Note
        that this does not necessarily mean that concept(c) holds.
        """
        concept = self.domain.concepts[concept_name]
        assert concept.arity == 1
        sort = concept.variables[0].sort
        assert sort != TopSort()

        constants = used_constants(concept.formula)
        x = Const(self._fresh_const_name(constants), sort)
        f = concept(x)

        def is_witness(c):
            try:
                return z3_implies(f, Eq(x, c))
            except SortError:
                return False

        return [c for c in constants if is_witness(c)]
Ejemplo n.º 9
0
    def _get_witnesses(self, concept_name):
        # TODO: maybe this function should be in ConceptDomain? or Concept?
        """
        Return a list of constant that are witnesses for the given unary
        constant, or [] if none are found

        A witness is a constant c s.t. concept(x) implies x=c. Note
        that this does not necessarily mean that concept(c) holds.
        """
        concept = self.domain.concepts[concept_name]
        assert concept.arity == 1
        sort = concept.variables[0].sort
        assert sort != TopSort()

        if sort.name == 'unit':
            return [Const('0',sort)]

        constants = used_constants(concept.formula)
        x = Const(self._fresh_const_name(constants), sort)
        f = concept(x)
        def is_witness(c):
            try:
                return z3_implies(f, Eq(x, c))
            except SortError:
                return False

        return [c for c in constants if is_witness(c)]
Ejemplo n.º 10
0
 def add_new_constants(self, f):
     cons = lgu.used_constants(f)
     for c in cons:
         if c not in self.allvars:
             self.add_constant(c, False)
             self.vars.add(c)
             self.allvars.add(c)
Ejemplo n.º 11
0
 def _fresh_const_name(self, extra=frozenset()):
     contents = ([self._to_formula()] + [
         c.formula for n, c in self.domain.concepts.iteritems()
         if isinstance(c, Concept)
     ])
     used = frozenset(c.name for c in (used_constants(*contents) | extra))
     return next(name for name in constant_name_generator()
                 if name not in used)
Ejemplo n.º 12
0
 def _fresh_const_name(self, extra=frozenset()):
     contents = ([self._to_formula()] +
                 [c.formula for n,c in self.domain.concepts.iteritems() if isinstance(c,Concept)])
     used = frozenset(c.name for c in (
         used_constants(*contents) | extra
     ))
     return next(name for name in constant_name_generator()
                 if name not in used)
Ejemplo n.º 13
0
def get_diagram_concept_domain(sig, diagram):
    """
    sig is an ivy_logic.Sig object
    diagram is a formula
    """
    concepts = OrderedDict()

    concepts['nodes'] = []
    concepts['node_labels'] = []
    concepts['edges'] = []

    # add equality concept
    X = Var('X', TopSort())
    Y = Var('Y', TopSort())
    concepts['='] = Concept([X, Y], Eq(X, Y))

    # add concepts from relations and constants in the signature and
    # in the diagram
    if sig is not None:
        sig_symbols = frozenset(sig.symbols.values())
    else:
        sig_symbols = frozenset()
    for c in sorted(sig_symbols | used_constants(diagram)):
        assert type(c) is Const

        if first_order_sort(c.sort):
            # first order constant, add unary equality concept
            X = Var('X', c.sort)
            name = '{}:{}'.format(c.name, c.sort)
            concepts[name] = Concept([X], Eq(X,c))
            concepts['nodes'].append(name)

        elif type(c.sort) is FunctionSort and c.sort.arity == 1:
            # add unary concept and label
            X = Var('X', c.sort.domain[0])
            name = '{}'.format(c.name)
            concepts[name] = Concept([X], c(X))

        elif type(c.sort) is FunctionSort and c.sort.arity == 2:
            # add binary concept and edge
            X = Var('X', c.sort.domain[0])
            Y = Var('Y', c.sort.domain[1])
            name = '{}'.format(c.name)
            concepts[name] = Concept([X, Y], c(X, Y))

        elif type(c.sort) is FunctionSort and c.sort.arity == 3:
            # add ternary concept
            X = Var('X', c.sort.domain[0])
            Y = Var('Y', c.sort.domain[1])
            Z = Var('Z', c.sort.domain[2])
            name = '{}'.format(c.name)
            concepts[name] = Concept([X, Y, Z], c(X, Y, Z))

        else:
            # skip other symbols
            pass

    return ConceptDomain(concepts, get_standard_combiners(), get_standard_combinations())
Ejemplo n.º 14
0
def check_concretely_sorted(term, no_error=False, unsorted_var_names=()):
    for x in chain(lu.used_variables(term), lu.used_constants(term)):
        if lg.contains_topsort(x.sort) or lg.is_polymorphic(x.sort):
            if x.name not in unsorted_var_names:
                if no_error:
                    raise lg.SortError
                raise IvyError(
                    None,
                    "cannot infer sort of {} in {}".format(x, repr(term)))
Ejemplo n.º 15
0
 def show_used_relations(self,clauses,both=False):
     self.current_concept_graph.clear_edges()
     rels = self.current_concept_graph.g.relations
     used = set(il.normalize_symbol(s) for s in lu.used_constants(clauses.to_formula()))
     for rel in rels:
         if any(c in used and not c.name.startswith('@')
                for c in lu.used_constants(rel.formula)):
             self.current_concept_graph.show_relation(rel,'+',update=False)
             if both:
                 self.current_concept_graph.show_relation(rel,'-',update=False)
     need_update_relations = False
     for app in ilu.apps_clauses(clauses):
         if len(app.args) == 3 and il.is_numeral(app.args[0]):
             fmla = app.rep(app.args[0],il.Variable('X',app.args[1].sort),il.Variable('Y',app.args[2].sort))
             concept = self.current_concept_graph.g.formula_to_concept(fmla)
             self.current_concept_graph.g.new_relation(concept)
             need_update_relations = True
             self.current_concept_graph.show_relation(concept,'+',update=False)
             if both:
                 self.current_concept_graph.show_relation(concept,'-',update=False)
     if need_update_relations:
         self.current_concept_graph.update_relations()
     self.current_concept_graph.update()
Ejemplo n.º 16
0
def is_in_logic(term,logic,unstrat = False):
    global reason_text
    assert logic in logics
    if logic == "epr":
        # ok = (is_prenex_universal(term)
        #       if lu.free_variables(term) else is_ea(term))
        # if not ok:
        #     reason_text = "of quantifier alternation"
        #     return False
        try:
            check_essentially_uninterpreted(term)
        except NotEssentiallyUninterpreted:
            reason_text = "a variable occurs under an interpreted function symbol"
            return False
        cs = lu.used_constants(term)
        for s in cs:
            if s.name in sig.interp:
                reason_text = "'{}' is iterpreted".format(s)
                return False
        if unstrat:
            reason_text = "functions are not stratified"
            return False

            if not is_segregated(term):
                reason_text = "formula is unsegregated"
                return False
        return True
    elif logic == "qf":
        reason_text = "a formula contains a quantifier"
        return is_qf(term)
    elif logic == "fo":
        cs = lu.used_constants(term)
        for s in cs:
            if s.name in sig.interp:
                reason_text = "'{}' is iterpreted".format(s)
                return False
        return True
Ejemplo n.º 17
0
def is_in_logic(term, logic, unstrat=False):
    global reason_text
    assert logic in logics
    if logic == "epr":
        # ok = (is_prenex_universal(term)
        #       if lu.free_variables(term) else is_ea(term))
        # if not ok:
        #     reason_text = "of quantifier alternation"
        #     return False
        try:
            check_essentially_uninterpreted(term)
        except NotEssentiallyUninterpreted:
            reason_text = "a variable occurs under an interpreted function symbol"
            return False
        cs = lu.used_constants(term)
        for s in cs:
            if s.name in sig.interp:
                reason_text = "'{}' is iterpreted".format(s)
                return False
        if unstrat:
            reason_text = "functions are not stratified"
            return False

            if not is_segregated(term):
                reason_text = "formula is unsegregated"
                return False
        return True
    elif logic == "qf":
        reason_text = "a formula contains a quantifier"
        return is_qf(term)
    elif logic == "fo":
        cs = lu.used_constants(term)
        for s in cs:
            if s.name in sig.interp:
                reason_text = "'{}' is iterpreted".format(s)
                return False
        return True
Ejemplo n.º 18
0
    def minimize_conjecture(self, button=None, bound=None):
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses, used_symbols_clauses, negate
        from ivy_solver import unsat_core
        from logic_util import free_variables, substitute

        if self.bmc_conjecture(bound=bound):
            # found a BMC counter-example
            return

        with self.ui_parent.run_context():
            step_action = im.module.actions['ext']

            n_steps = self.current_bound

            ag = self.parent.new_ag()
            with ag.context as ac:
                post = ac.new_state(ag.init_cond)
            if 'initialize' in im.module.actions:
                init_action = im.module.actions['initialize']
                post = ag.execute(init_action, None, None, 'initialize')
            for n in range(n_steps):
                post = ag.execute(step_action, None, None, 'ext')
            axioms = im.module.background_theory()
            post_clauses = and_clauses(post.clauses, axioms)

            used_names = (
                frozenset(x.name for x in il.sig.symbols.values()) |
                frozenset(x.name for x in used_symbols_clauses(post_clauses))
            )
            facts = self.get_active_facts()
            assert not any(
                c.is_skolem() and c.name in used_names for c in lu.used_constants(*facts)
            )
            core = unsat_core(Clauses(facts), post_clauses)
            if core is None:
                core = Clauses([]) ## can happen if we are proving true
#            assert core is not None, "bmc_conjecture returned False but unsat core is None"
            core_formulas = frozenset(core.fmlas)
            self.set_facts([fact for fact in facts if fact in core_formulas])
            self.highlight_selected_facts()
            self.ui_parent.text_dialog("BMC found the following possible conjecture:",
                                       str(self.get_selected_conjecture()))
Ejemplo n.º 19
0
    def minimize_conjecture(self, button=None, bound=None):
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses, used_symbols_clauses, negate
        from ivy_solver import unsat_core
        from logic_util import free_variables, substitute

        if self.bmc_conjecture(bound=bound):
            # found a BMC counter-example
            return

        with self.ui_parent.run_context():
            step_action = im.module.actions['ext']

            n_steps = self.current_bound

            ag = self.parent.new_ag()
            with ag.context as ac:
                post = ac.new_state(ag.init_cond)
            if 'initialize' in im.module.actions:
                init_action = im.module.actions['initialize']
                post = ag.execute(init_action, None, None, 'initialize')
            for n in range(n_steps):
                post = ag.execute(step_action, None, None, 'ext')
            axioms = im.module.background_theory()
            post_clauses = and_clauses(post.clauses, axioms)

            used_names = (frozenset(x.name for x in il.sig.symbols.values())
                          | frozenset(
                              x.name
                              for x in used_symbols_clauses(post_clauses)))
            facts = self.get_active_facts()
            assert not any(c.is_skolem() and c.name in used_names
                           for c in lu.used_constants(*facts))
            core = unsat_core(Clauses(facts), post_clauses)
            if core is None:
                core = Clauses([])  ## can happen if we are proving true
#            assert core is not None, "bmc_conjecture returned False but unsat core is None"
            core_formulas = frozenset(core.fmlas)
            self.set_facts([fact for fact in facts if fact in core_formulas])
            self.highlight_selected_facts()
            self.ui_parent.text_dialog(
                "BMC found the following possible conjecture:",
                str(self.get_selected_conjecture()))
Ejemplo n.º 20
0
    def get_selected_conjecture(self):
        """
        Return a positive universal conjecture based on the selected facts.

        The result is a Clauses object
        """
        from logic_util import used_constants, free_variables, substitute
        from ivy_logic_utils import negate, Clauses, simplify_clauses

        facts = self.get_active_facts()
        assert len(free_variables(
            *
            facts)) == 0, "conjecture would contain existential quantifiers..."
        sig_symbols = frozenset(il.sig.symbols.values())
        facts_consts = used_constants(*facts)
        subs = {}
        rn = iu.VariableGenerator()
        for c in sorted(facts_consts, key=lambda c: c.name):
            if c.is_numeral() and il.is_uninterpreted_sort(c.sort):
                #                prefix = str(c.sort)[:2].upper() + c.name
                subs[c] = lg.Var(rn(c.sort.name), c.sort)

        literals = [negate(substitute(f, subs)) for f in facts]
        result = Clauses([lg.Or(*literals)])
        result = simplify_clauses(result)

        # now rename again to get a pretty clause, since some
        # variables have been eliminated by simplify_clauses
        # assert len(result.fmlas) == 1
        # clause = result.fmlas[0]
        # subs = {}
        # count = defaultdict(int)
        # for c in free_variables(clause):
        #     prefix = str(c.sort)[0].upper()
        #     count[prefix] += 1
        #     subs[c] = lg.Var(prefix + str(count[prefix]), c.sort)
        # result = Clauses([substitute(clause, subs)])

        # change to negation of conjunction rather than disjunction
        assert len(result.fmlas) == 1
        if type(result.fmlas[0]) is lg.Or:
            result = Clauses(
                [lg.Not(lg.And(*(negate(lit) for lit in result.fmlas[0])))])

        return result
Ejemplo n.º 21
0
def concretize_terms(terms, sorts=None):
    """ Concretize the sorts in a list of terms. Free variables must have
    the same sort in all terms. The list 'sorts' gives a sort upper bound for
    each term (use TopS to leave the sort unspecified). """

    # give sort names to all the free variables and constants:

    names = free_variables(*terms,
                           by_name=True).union(x.name
                                               for x in used_constants(*terms))
    env = dict((name, SortVar()) for name in names)

    pairs = [infer_sorts(term, env) for term in terms]

    if sorts is not None:
        for (s, tt), sort in zip(pairs, sorts):
            unify(s, sort)

    return [tt() for s, tt in pairs]
Ejemplo n.º 22
0
def concretize_terms(terms,sorts=None):
    """ Concretize the sorts in a list of terms. Free variables must have
    the same sort in all terms. The list 'sorts' gives a sort upper bound for
    each term (use TopS to leave the sort unspecified). """

    # give sort names to all the free variables and constants:

    names = free_variables(*terms, by_name=True).union(
               x.name for x in used_constants(*terms)
            )
    env = dict((name, SortVar()) for name in names)

    pairs = [infer_sorts(term,env) for term in terms]

    if sorts is not None:
        for (s,tt),sort in zip(pairs,sorts):
            unify(s,sort)

    return [tt() for s,tt in pairs]
Ejemplo n.º 23
0
    def standardize_action(self, f, nexvars, name):
        nexSet = set()
        for n in nexvars:
            nexSet.add(n)
            self.updated.add(n)

        cons = lgu.used_constants(f)
        subs = dict()
        for c in cons:
            if c in self.nex:
                if c not in nexSet:
                    subs[c] = self.nex2pre[c]

        if len(subs) == 0:
            return f
        else:
            #             for k, v in subs.iteritems():
            #                 print("\treplacing %s -> %s in %s" % (k, v, name))
            return lgu.substitute(f, subs)
Ejemplo n.º 24
0
    def get_selected_conjecture(self):
        """
        Return a positive universal conjecture based on the selected facts.

        The result is a Clauses object
        """
        from logic_util import used_constants, free_variables, substitute
        from ivy_logic_utils import negate, Clauses, simplify_clauses

        facts = self.get_active_facts()
        assert len(free_variables(*facts)) == 0, "conjecture would contain existential quantifiers..."
        sig_symbols = frozenset(il.sig.symbols.values())
        facts_consts = used_constants(*facts)
        subs = {}
        rn = iu.UniqueRenamer()
        for c in sorted(facts_consts, key=lambda c: c.name):
            if c.is_numeral() and il.is_uninterpreted_sort(c.sort):
                prefix = str(c.sort)[:2].upper() + str(c)
                subs[c] = lg.Var(rn(prefix), c.sort)

        literals = [negate(substitute(f, subs)) for f in facts]
        result = Clauses([lg.Or(*literals)])
        result = simplify_clauses(result)

        # now rename again to get a pretty clause, since some
        # variables have been eliminated by simplify_clauses
        # assert len(result.fmlas) == 1
        # clause = result.fmlas[0]
        # subs = {}
        # count = defaultdict(int)
        # for c in free_variables(clause):
        #     prefix = str(c.sort)[0].upper()
        #     count[prefix] += 1
        #     subs[c] = lg.Var(prefix + str(count[prefix]), c.sort)
        # result = Clauses([substitute(clause, subs)])

        # change to negation of conjunction rather than disjunction
        assert len(result.fmlas) == 1
        if type(result.fmlas[0]) is lg.Or:
            result = Clauses([lg.Not(lg.And(*(negate(lit) for lit in result.fmlas[0])))])

        return result
Ejemplo n.º 25
0
 def add_new_constants(self, f, origin=''):
     cons = lgu.used_constants(f)
     for c in cons:
         if c not in self.allvars and c.name not in {'<=', '>=', '>'}:
             #                print >>sys.stderr, c, c.sort, origin
             if origin in {'prop', 'axiom'}:
                 sym = c
                 psym = sym.prefix('__')
                 nsym = sym
                 self.pre.add(psym)
                 self.nex.add(nsym)
                 self.pre2nex[psym] = nsym
                 self.nex2pre[nsym] = psym
                 self.allvars.add(psym)
                 self.allvars.add(nsym)
                 self.add_constant(sym, True)
             else:
                 self.add_constant(c, False)
                 self.vars.add(c)
                 self.allvars.add(c)
Ejemplo n.º 26
0
def is_in_logic(term,logic,unstrat = False):
    global reason_text
    assert logic in logics
    if logic == "epr":
        # ok = (is_prenex_universal(term)
        #       if lu.free_variables(term) else is_ea(term))
        # if not ok:
        #     reason_text = "of quantifier alternation"
        #     return False
        cs = lu.used_constants(term)
        for s in cs:
            if s.name in sig.interp:
                reason_text = "'{}' is iterpreted".format(s)
                return False
        if unstrat:
            if not is_segregated(term):
                reason_text = "formula is unsegregated"
                return False
        return True
    elif logic == "qf":
        return is_qf(term)
Ejemplo n.º 27
0
def get_structure_concept_domain(state, sig=None):
    """
    state is an ivy_interp.State with a .universe
    sig is an ivy_logic.Sig object
    """
    concepts = OrderedDict()

    concepts['nodes'] = []
    concepts['node_labels'] = []

    # add equality concept
    X = Var('X', TopSort())
    Y = Var('Y', TopSort())
    concepts['='] = Concept([X, Y], Eq(X, Y))

    # add nodes for universe elements
    elements = [uc for s in state.universe for uc in state.universe[s]]
    for uc in sorted(elements):
        # add unary equality concept
        X = Var('X', uc.sort)
        name = uc.name
        if str(uc.sort) not in name:
            name += ':{}'.format(uc.sort)
        concepts[name] = Concept([X], Eq(X,uc))
        concepts['nodes'].append(name)

    # # find which symbols are equal to which universe constant
    # equals = dict(
    #     (uc, [c for c in symbols
    #           if c != uc and
    #           c.sort == s and
    #           z3_implies(state_formula, Eq(c, uc))])
    #     for s in state.universe
    #     for uc in state.universe[s]
    # )

    # add concepts for relations and constants
    state_formula = state.clauses.to_formula()
    symbols = used_constants(state_formula)
    if sig is not None:
        symbols = symbols | frozenset(sig.symbols.values())
    symbols = symbols - frozenset(elements)
    symbols = sorted(symbols)
    for c in symbols:
        assert type(c) is Const

        if first_order_sort(c.sort):
            # first order constant, add unary equality concept
            X = Var('X', c.sort)
            name = '={}'.format(c.name)
            concepts[name] = Concept([X], Eq(X,c))

        elif type(c.sort) is FunctionSort and c.sort.arity == 1:
            # add unary concept and label
            X = Var('X', c.sort.domain[0])
            name = '{}'.format(c.name)
            concepts[name] = Concept([X], c(X))

        elif type(c.sort) is FunctionSort and c.sort.arity == 2:
            # add binary concept and edge
            X = Var('X', c.sort.domain[0])
            Y = Var('Y', c.sort.domain[1])
            name = '{}'.format(c.name)
            concepts[name] = Concept([X, Y], c(X, Y))

        elif type(c.sort) is FunctionSort and c.sort.arity == 3:
            # add ternary concept
            X = Var('X', c.sort.domain[0])
            Y = Var('Y', c.sort.domain[1])
            Z = Var('Z', c.sort.domain[2])
            name = '{}'.format(c.name)
            concepts[name] = Concept([X, Y, Z], c(X, Y, Z))

        else:
            # skip other symbols
            pass

    return ConceptDomain(concepts, get_standard_combiners(), get_standard_combinations())
Ejemplo n.º 28
0
 def _fresh_const_name(self, extra=frozenset()):
     used = frozenset(c.name for c in (
         used_constants(self._to_formula()) | extra
     ))
     return next(name for name in constant_name_generator()
                 if name not in used)
Ejemplo n.º 29
0
def infer_sorts(t, env=None):
    """
    Infer the sort of term t in environment env.

    env maps symbol names to sort variables.

    The result is a pair: (s, tt) where s is a sort or sort variable
    with the sort of t in env, and tt is a closure that, when called,
    will concretize t according to inferred sort information at its
    call time.

    If env is not None, it must contain all the free variables and
    constants used in t.
    """

    if env is None:
        names = free_variables(t, by_name=True).union(
            x.name for x in used_constants(t)
        )
        env = dict((name, SortVar()) for name in names)

    if type(t) in (Var, Const):
        if is_polymorphic(t):  # each instance can have different sort
            s = insert_sortvars(t.sort,{})
        else:
            s = env[t.name]
            unify(s, t.sort)
        return s, lambda: type(t)(t.name, convert_from_sortvars(s))

    elif type(t) is Apply:
        func_s, func_t = infer_sorts(t.func, env)
        xys = [infer_sorts(tt, env) for tt in t.terms]
        terms_s = [x for x, y in xys]
        terms_t = [y for x, y in xys]
        sorts = terms_s + [SortVar()]
        unify(func_s, FunctionSort(*sorts))
        return sorts[-1], lambda: Apply(func_t(), *(
            x() for x in terms_t
        ))

    elif type(t) is Eq:
        s1, t1 = infer_sorts(t.t1, env)
        s2, t2 = infer_sorts(t.t2, env)
        unify(s1, s2)
        return Boolean, lambda: Eq(t1(), t2())

    elif type(t) is Ite:
        s_cond, t_cond = infer_sorts(t.cond, env)
        s_then, t_then = infer_sorts(t.t_then, env)
        s_else, t_else = infer_sorts(t.t_else, env)
        unify(s_cond, Boolean)
        unify(s_then, s_else)
        return s_then, lambda: Ite(t_cond(), t_then(), t_else())

    elif type(t) in (Not, And, Or, Implies, Iff):
        xys = [infer_sorts(tt, env) for tt in t]
        terms_s = [x for x, y in xys]
        terms_t = [y for x, y in xys]
        for s in terms_s:
            unify(s, Boolean)
        return Boolean, lambda: type(t)(*[
            x() for x in terms_t
        ])

    elif type(t) in (ForAll, Exists):
        # create a copy of the environment and shadow that quantified
        # variables
        env = env.copy()
        env.update((v.name, SortVar()) for v in t.variables)
        vars_t = [infer_sorts(v, env)[1] for v in t.variables]
        body_s, body_t = infer_sorts(t.body, env)
        unify(body_s, Boolean)
        return Boolean, lambda: type(t)(
            [x() for x in vars_t],
            body_t(),
        )

    elif hasattr(t,'clone'):
        xys = [infer_sorts(tt, env) for tt in t.args]
        terms_t = [y for x, y in xys]
        return TopSort(), lambda: t.clone([
            x() for x in terms_t
        ])
        
    else:
        assert False, type(t)
Ejemplo n.º 30
0
def infer_sorts(t, env=None):
    """
    Infer the sort of term t in environment env.

    env maps symbol names to sort variables.

    The result is a pair: (s, tt) where s is a sort or sort variable
    with the sort of t in env, and tt is a closure that, when called,
    will concretize t according to inferred sort information at its
    call time.

    If env is not None, it must contain all the free variables and
    constants used in t.
    """

    if env is None:
        names = free_variables(t,
                               by_name=True).union(x.name
                                                   for x in used_constants(t))
        env = dict((name, SortVar()) for name in names)

    if type(t) in (Var, Const):
        if is_polymorphic(t):  # each instance can have different sort
            s = insert_sortvars(t.sort, {})
        else:
            s = env[t.name]
            unify(s, t.sort)
        return s, lambda: type(t)(t.name, convert_from_sortvars(s))

    elif type(t) is Apply:
        func_s, func_t = infer_sorts(t.func, env)
        xys = [infer_sorts(tt, env) for tt in t.terms]
        terms_s = [x for x, y in xys]
        terms_t = [y for x, y in xys]
        sorts = terms_s + [SortVar()]
        unify(func_s, FunctionSort(*sorts))
        return sorts[-1], lambda: Apply(func_t(), *(x() for x in terms_t))

    elif type(t) is Eq:
        s1, t1 = infer_sorts(t.t1, env)
        s2, t2 = infer_sorts(t.t2, env)
        unify(s1, s2)
        return Boolean, lambda: Eq(t1(), t2())

    elif type(t) is Ite:
        s_cond, t_cond = infer_sorts(t.cond, env)
        s_then, t_then = infer_sorts(t.t_then, env)
        s_else, t_else = infer_sorts(t.t_else, env)
        unify(s_cond, Boolean)
        unify(s_then, s_else)
        return s_then, lambda: Ite(t_cond(), t_then(), t_else())

    elif type(t) in (Not, And, Or, Implies, Iff):
        xys = [infer_sorts(tt, env) for tt in t]
        terms_s = [x for x, y in xys]
        terms_t = [y for x, y in xys]
        for s in terms_s:
            unify(s, Boolean)
        return Boolean, lambda: type(t)(*[x() for x in terms_t])

    elif type(t) in (ForAll, Exists):
        # create a copy of the environment and shadow that quantified
        # variables
        env = env.copy()
        env.update((v.name, SortVar()) for v in t.variables)
        vars_t = [infer_sorts(v, env)[1] for v in t.variables]
        body_s, body_t = infer_sorts(t.body, env)
        unify(body_s, Boolean)
        return Boolean, lambda: type(t)(
            [x() for x in vars_t],
            body_t(),
        )

    elif hasattr(t, 'clone'):
        xys = [infer_sorts(tt, env) for tt in t.args]
        terms_t = [y for x, y in xys]
        return TopSort(), lambda: t.clone([x() for x in terms_t])

    else:
        assert False, type(t)