I was trying to write a simple transitive relation, and had a bit of a difficult time (and as I can see in previous issues I am not the first). Maybe it would be a good idea to include some extra functionality in- or outside the Relation class which allows one to easily define reflexive, symmetric and/or transitive relations? These are very common properties for relations found in mathematics, so it might be nice to support these out-of-the-box.
I've written a little helper as a start, but it still has the possibility for infinite loops when there is a cycle in the graph. However I'm not sure how to fix that neatly.
def extend_relation(rel, reflexive=True, symmetric=True, transitive=True):
def goal(a, b):
c = var()
return conde(
[eq(a, b)] if reflexive else [fail],
[rel(a, b)],
[rel(b, a)] if symmetric else [fail],
[neq(a, c),
neq(c, b),
rel(a, c),
Zzz(goal, c, b)] if transitive else [fail]
)
return goal
I was trying to write a simple transitive relation, and had a bit of a difficult time (and as I can see in previous issues I am not the first). Maybe it would be a good idea to include some extra functionality in- or outside the Relation class which allows one to easily define reflexive, symmetric and/or transitive relations? These are very common properties for relations found in mathematics, so it might be nice to support these out-of-the-box.
I've written a little helper as a start, but it still has the possibility for infinite loops when there is a cycle in the graph. However I'm not sure how to fix that neatly.