def to_constraint(self): if isinstance(self.args[1],Some): if self.args[1].if_value() != None: return And(Implies(self.args[1].args[1], lg.Exists([self.args[1].args[0]], And(self.args[1].args[1],Equals(self.args[0],self.args[1].if_value())))), Or(lg.Exists([self.args[1].args[0]],self.args[1].args[1]), Equals(self.args[0],self.args[1].else_value()))) return lg.ForAll([self.args[1].args[0]], Implies(self.args[1].args[1], lu.substitute(self.args[1].args[1],{self.args[1].args[0]:self.args[0]}))) if is_individual(self.args[0]): return Equals(*self.args) return Iff(*self.args)
def exclusivity(sort,variants): # partial funciton def pto(s): return Symbol('*>',RelationSort([sort,s])) excs = [partial_function(pto(s)) for s in variants] for s in enumerate(variants): x,y,z = [Variable(n,s) for n,s in [('X',sort),('Y',sort),('Z',s)]] excs.append(Implies(And(pto(s)(x,z),pto(s)(y,z)),Equals(x,y))) for i1,s1 in enumerate(variants): for s2 in variants[:i1]: x,y,z = [Variable(n,s) for n,s in [('X',sort),('Y',s1),('Z',s2)]] excs.append(Not(And(pto(s1)(x,y),pto(s2)(x,z)))) return And(*excs)
def extensionality(destrs): if not destrs: return Or() c = [] sort = destrs[0].sort.dom[0] x, y = Variable("X", sort), Variable("Y", sort) for d in destrs: vs = variables(d.sort.dom[1:]) eqn = Equals(d(*([x] + vs)), d(*([y] + vs))) if vs: eqn = lg.ForAll(vs, eqn) c.append(eqn) res = Implies(And(*c), Equals(x, y)) return res
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) print print z3_implies(true, Iff(transitive1, transitive2)) print
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
def partial_function(rel): lsort, rsort = rel.sort.dom x, y, z = [ Variable(n, s) for n, s in [('X', lsort), ('Y', rsort), ('Z', rsort)] ] return ForAll([x, y, z], Implies(And(rel(x, y), rel(x, z)), Equals(y, z)))
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)))) cnstar = Concept('nstar', [X, Y], nstar(X, Y)) cnplus = Concept('nplus', [X, Y], And(nstar(X, Y), Not(Eq(X, Y)))) notexists = ConceptCombiner([U], Not(Exists([X], U(X)))) exists = ConceptCombiner([U], Exists([X], U(X))) singleton = ConceptCombiner([U], ForAll([X, Y], Implies(And(U(X), U(Y)), Eq(X, Y)))) all_to_all = ConceptCombiner([U1, U2, B], ForAll([X, Y], Implies(And(U1(X), U2(Y)), B(X, Y)))) cd = ConceptDomain( OrderedDict([ ('xy', c11), ('other', c00), ('x', c10), ('y', c01), ('nstar', cnstar), ('nplus', cnplus), ]), OrderedDict([ ('notexists', notexists),