def transitivity(triples): clauses = [] for triple, (rels_a, rels_b) in triples.items(): a = (triple[0], triple[1]) b = (triple[1], triple[2]) o = (triple[0], triple[2]) for rel_a in rels_a: for rel_b in rels_b: if rel_a == "*": clauses.append(impl(simultaneous(*a) & relation[rel_b](*b), relation[rel_b](*o))) elif rel_b == "*" or rel_b == rel_a: clauses.append(impl(relation[rel_a](*a) & relation[rel_b](*b), relation[rel_a](*o))) return clauses
def exhaustive_occurrence(*events): "Relationships between events imply that the events themselves occur" return pairwise(lambda a, b: impl(or_(simultaneous(a, b), sequential(a, b), sequential(b, a)), a & b), events)
def occurrence(relationships): clauses = [] for pair, rels in relationships.items(): for r in rels: clauses.append( impl(relation[r](*pair), var(pair[0]) & var(pair[1]))) return clauses
def exhaustive_timeline(*events): """ A timeline is linear, and allows only a single relationship between each pair of events; a<b, b<a, or a*b """ return pairwise(lambda a, b: impl(a & b, onehot(simultaneous(a, b), sequential(a, b), sequential(b, a))), events)
def timeline(relationships): """A timeline is linear, and allows only a single relationship between each pair of events; a<b, b<a, or a*b""" clauses = [] for pair, rels in relationships.items(): clauses.append(impl(var(pair[0]) & var(pair[1]), onehot(*[relation[rel](*pair) for rel in rels]))) return clauses
def test_transitivity(): def trans(s): return transitivity(triples(relationships(s))) statements = [sequential('a', 'b'), sequential('b', 'c'), sequential('d', 'e')] assert len(trans(statements)) == 1 statements += sequential('a', 'c') assert trans(statements)[0].equiv( impl(and_(var("a<b"), var("b<c")), var("a<c")))
def inner(a, b, c): return and_(impl(fn(a, b) & fn(b, c), fn(a, c)), impl(simultaneous(a, b) & fn(b, c), fn(a, c)), impl(fn(a, b) & simultaneous(b, c), fn(a, c)))