Example #1
0
def get_initial_concept_domain(sig):
    """
    sig is an ivy_logic.Sig object
    """
    concepts = OrderedDict()

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

    # add sort concepts
    for s in sorted(sig.sorts.values()):
        X = Var('X', s)
        concepts[s.name] = Concept([X], Eq(X,X))
        concepts['nodes'].append(s.name)

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

    # add concepts from relations
    for c in sorted(sig.symbols.values()):
        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())
Example #2
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())
Example #3
0
    def generate(self):
        """
        generate variable with new name

        Returns
        -------
        generated_var : .logic.Var
            generated variable
        """
        generated_var = Var(self.base_name + str(self.counter))
        self.counter += 1
        return generated_var
Example #4
0
 def _materialize_node(self, concept_name):
     """
     Materialize a node, returns the witness constant
     """
     concept = self.domain.concepts[concept_name]
     assert concept.arity == 1
     sort = concept.variables[0].sort
     assert sort != TopSort()
     witnesses = self._get_witnesses(concept_name)
     if len(witnesses) > 0:
         c = witnesses[0]
     else:
         c = Const(self._fresh_const_name(), sort)
         # TODO: maybe we shouldn't split here, and create the concepts explicitly
         X = Var('X', c.sort)
         name = '={}'.format(c.name)
         self.domain.concepts[name] = Concept(name, [X], Eq(X, c))
         self.domain.split(concept_name, name)
     self.suppose(concept(c))
     return c
Example #5
0
                _implies_cache[key] = False
                result.append(False)
            elif res == z3.unsat:
                _implies_cache[key] = True
                result.append(True)
            else:
                # no caching of unknown results
                print "z3 returned: {}".format(res)
                assert False
                result.append(None)
    return result


if __name__ == '__main__':
    S = UninterpretedSort('S')
    X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z'])
    BinRel = FunctionSort(S, S, Boolean)
    leq = Const('leq', BinRel)
    transitive1 = ForAll((X, Y, Z),
                         Implies(And(leq(X, Y), leq(Y, Z)), leq(X, Z)))
    transitive2 = ForAll((X, Y, Z),
                         Or(Not(leq(X, Y)), Not(leq(Y, Z)), leq(X, Z)))
    transitive3 = Not(
        Exists((X, Y, Z), And(leq(X, Y), leq(Y, Z), Not(leq(X, Z)))))
    antisymmetric = ForAll((X, Y),
                           Implies(And(leq(X, Y), leq(Y, X), true), Eq(Y, X)))

    print z3_implies(transitive1, transitive2)
    print z3_implies(transitive2, transitive3)
    print z3_implies(transitive3, transitive1)
    print z3_implies(transitive3, antisymmetric)
Example #6
0
 def get_clauses(self):
     clause1 = Clause(Atom(self.preds[0], [Var('X'), Var('Y')]), [])
     self.clauses = [clause1]
Example #7
0
    elif ((type(t) is ForAll and type(t.body) is And)
          or (type(t) is Exists and type(t.body) is Or)):
        return normalize_quantifiers(
            type(t.body)(*(type(t)(t.variables, x) for x in t.body)))

    elif type(t) in (ForAll, Exists):
        return type(t)(free_variables(t.body) & frozenset(t.variables),
                       normalize_quantifiers(t.body))

    else:
        assert False, type(t)


def is_tautology_equality(t):
    """Returns True if t is Eq(x,x) for some x"""
    return type(t) is Eq and t.t1 == t.t2


if __name__ == '__main__':
    from logic import *
    s1 = UninterpretedSort('s1')
    s2 = UninterpretedSort('s2')
    X1 = Var('X', s1)
    X2 = Var('X', s2)
    f = ForAll([X1], Eq(X2, X2))
    assert free_variables(f) == {X2}
    assert free_variables(f, by_name=True) == set()
    assert free_variables(f.body) == {X2}
    assert free_variables(f.body, by_name=True) == {'X'}
Example #8
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())
Example #9
0
def get_standard_combiners():
    T = TopSort()
    UnaryRelation = FunctionSort(T, Boolean)
    BinaryRelation = FunctionSort(T, T, Boolean)
    X, Y, Z = (Var(n, T) for n in ['X', 'Y', 'Z'])
    U = Var('U', UnaryRelation)
    U1 = Var('U1', UnaryRelation)
    U2 = Var('U2', UnaryRelation)
    B = Var('B', BinaryRelation)
    B1 = Var('B1', BinaryRelation)
    B2 = Var('B2', BinaryRelation)
    result = OrderedDict()

    result['none'] = ConceptCombiner([U], Not(Exists([X], U(X))))
    result['at_least_one'] = ConceptCombiner([U], Exists([X], U(X)))
    result['at_most_one'] = ConceptCombiner([U], ForAll([X,Y], Implies(And(U(X), U(Y)), Eq(X,Y))))

    result['node_necessarily'] = ConceptCombiner(
        [U1, U2],
        ForAll([X], Implies(U1(X), U2(X))),
    )
    result['node_necessarily_not'] = ConceptCombiner(
        [U1, U2],
        ForAll([X], Implies(U1(X), Not(U2(X)))),
    )


    result['mutually_exclusive'] = ConceptCombiner(
        [U1, U2],
        ForAll([X, Y], Not(And(U1(X), U2(Y))))
    )

    result['all_to_all'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X,Y], Implies(And(U1(X), U2(Y)), B(X,Y)))
    )
    result['none_to_none'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X,Y], Implies(And(U1(X), U2(Y)), Not(B(X,Y))))
    )
    result['total'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X], Implies(U1(X), Exists([Y], And(U2(Y), B(X,Y)))))
    )
    result['functional'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X, Y, Z], Implies(And(U1(X), U2(Y), U2(Z), B(X,Y), B(X,Z)), Eq(Y,Z)))
    )
    result['surjective'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([Y], Implies(U2(Y), Exists([X], And(U1(X), B(X,Y)))))
    )
    result['injective'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X, Y, Z], Implies(And(U1(X), U1(Y), U2(Z), B(X,Z), B(Y,Z)), Eq(X,Y)))
    )

    result['node_info'] = ['none', 'at_least_one', 'at_most_one']
    if False:
        # this just slows us down, and it's not clear it's needed
        # later this should be made customizable by the user
        result['edge_info'] = ['all_to_all', 'none_to_none', 'total',
                               'functional', 'surjective', 'injective']
    else:
        result['edge_info'] = ['all_to_all', 'none_to_none']

    result['node_label'] = ['node_necessarily', 'node_necessarily_not']

    return result
Example #10
0
    if sorts is not None:
        for (s, tt), sort in zip(pairs, sorts):
            unify(s, sort)

    return [tt() for s, tt in pairs]


if __name__ == '__main__':
    S = UninterpretedSort('S')
    T = TopSort()
    UnaryRelationS = FunctionSort(S, Boolean)
    BinaryRelationS = FunctionSort(S, S, Boolean)
    UnaryRelationT = FunctionSort(T, Boolean)
    BinaryRelationT = FunctionSort(T, T, Boolean)

    XS, YS = (Var(n, S) for n in ['X', 'Y'])
    XT, YT = (Var(n, T) for n in ['X', 'Y'])

    xs, ys = (Const(n, S) for n in ['x', 'y'])
    xt, yt = (Const(n, T) for n in ['x', 'y'])

    rs = Const('r', BinaryRelationS)
    ps = Const('p', UnaryRelationS)
    rt = Const('r', BinaryRelationT)
    pt = Const('p', UnaryRelationT)
    tt = Const('tt', T)
    TT = Var('TT', T)

    f1 = And(ps(XS), ps(xs))
    cf1 = concretize_sorts(f1)
    print repr(f1)
if __name__ == '__main__':
    from collections import ConceptDict
    from logic import (Var, Const, Apply, Eq, Not, And, Or, Implies, ForAll,
                       Exists)
    from logic import UninterpretedSort, FunctionSort, first_order_sort, Boolean
    from logic_util import free_variables, substitute, substitute_apply
    from concept import Concept, ConceptCombiner, ConceptDomain

    def test(st):
        print st, "=", eval(st)

    S = UninterpretedSort('S')
    UnaryRelation = FunctionSort(S, Boolean)
    BinaryRelation = FunctionSort(S, S, Boolean)

    X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z'])
    U = Var('U', UnaryRelation)
    U1 = Var('U1', UnaryRelation)
    U2 = Var('U2', UnaryRelation)
    B = Var('B', BinaryRelation)
    B1 = Var('B1', BinaryRelation)
    B2 = Var('B2', BinaryRelation)

    nstar = Const('nstar', BinaryRelation)
    x = Const('x', S)
    y = Const('y', S)

    c11 = Concept('xy', [X], And(Eq(x, X), Eq(y, X)))
    c10 = Concept('x', [X], And(Eq(x, X), Not(Eq(y, X))))
    c01 = Concept('y', [X], And(Not(Eq(x, X)), Eq(y, X)))
    c00 = Concept('other', [X], And(Not(Eq(x, X)), Not(Eq(y, X))))