From 00dd225b81678a0c26c28d2940eba1e41ce91c41 Mon Sep 17 00:00:00 2001 From: Jim Balhoff Date: Fri, 22 Oct 2021 11:14:31 -0400 Subject: [PATCH 1/3] Check for cycles in basic.owl using souffle. --- src/ontology/uberon.Makefile | 6 ++++++ src/scripts/cycles.dl | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/scripts/cycles.dl diff --git a/src/ontology/uberon.Makefile b/src/ontology/uberon.Makefile index 9ad050b316..205e94ae9c 100644 --- a/src/ontology/uberon.Makefile +++ b/src/ontology/uberon.Makefile @@ -976,6 +976,12 @@ $(REPORTDIR)/basic-allcycles: basic.owl test: $(REPORTDIR)/basic-allcycles +tmp/basic.facts: basic.owl + riot -q --output=n-triples $< | sed 's/ /\t/' | sed 's/ /\t/' | sed 's/ \.$$//' >$@ + +tmp/basic-cycles.tsv: tmp/basic.facts + souffle -F tmp -D tmp ../scripts/cycles.dl && mv tmp/cycle.csv $@ + #%-synclash: %.obo # blip-findall -u query_obo -i $< "same_label_as(X,Y,A,B,C),X@ $@ # TODO @matentzn - like mondo, make sure that there are no label/exact syn clashes, use ROBOT diff --git a/src/scripts/cycles.dl b/src/scripts/cycles.dl new file mode 100644 index 0000000000..9f2085a837 --- /dev/null +++ b/src/scripts/cycles.dl @@ -0,0 +1,25 @@ +#define RDF_TYPE "" +#define RDFS_SUBCLASS_OF "" +#define OWL_RESTRICTION "" +#define OWL_ON_PROPERTY "" +#define OWL_SOME_VALUES_FROM "" + +.decl basic(s: symbol, p: symbol, o: symbol) +.decl relation(s: symbol, p: symbol, o: symbol) +.decl reachable(s: symbol, o: symbol) +.decl cycle(s: symbol) + +relation(s, p, o) :- + basic(s, RDFS_SUBCLASS_OF, restr), + basic(restr, OWL_ON_PROPERTY, p), + basic(restr, OWL_SOME_VALUES_FROM, o), + basic(restr, RDF_TYPE, OWL_RESTRICTION), + match("<.+>", o). + +reachable(s, o) :- relation(s, _, o). +reachable(s, o) :- relation(s, _, c), reachable(c, o). + +cycle(s) :- reachable(s, s). + +.input basic +.output cycle From 5145cafd3be95c5cd4bb203c54944688598467ea Mon Sep 17 00:00:00 2001 From: Jim Balhoff Date: Fri, 22 Oct 2021 12:06:42 -0400 Subject: [PATCH 2/3] Add is_a relations. --- src/scripts/cycles.dl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/scripts/cycles.dl b/src/scripts/cycles.dl index 9f2085a837..475e8b0858 100644 --- a/src/scripts/cycles.dl +++ b/src/scripts/cycles.dl @@ -14,8 +14,11 @@ relation(s, p, o) :- basic(restr, OWL_ON_PROPERTY, p), basic(restr, OWL_SOME_VALUES_FROM, o), basic(restr, RDF_TYPE, OWL_RESTRICTION), + match("<.+>", s), match("<.+>", o). +relation(s, RDFS_SUBCLASS_OF, o) :- basic(s, RDFS_SUBCLASS_OF, o), match("<.+>", s), match("<.+>", o). + reachable(s, o) :- relation(s, _, o). reachable(s, o) :- relation(s, _, c), reachable(c, o). From 41d6d80a2b640a52ca2abeb950c48664d4e0283d Mon Sep 17 00:00:00 2001 From: Jim Balhoff Date: Thu, 9 Dec 2021 10:26:21 -0500 Subject: [PATCH 3/3] Improve cycle detector to report paths. --- src/scripts/cycles.dl | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/scripts/cycles.dl b/src/scripts/cycles.dl index 475e8b0858..f1a6a1cfc3 100644 --- a/src/scripts/cycles.dl +++ b/src/scripts/cycles.dl @@ -4,10 +4,22 @@ #define OWL_ON_PROPERTY "" #define OWL_SOME_VALUES_FROM "" +.type List = [ + head : PathSegment, + tail : List +] + +.type PathSegment = [ + property: symbol, + filler: symbol +] + .decl basic(s: symbol, p: symbol, o: symbol) .decl relation(s: symbol, p: symbol, o: symbol) -.decl reachable(s: symbol, o: symbol) -.decl cycle(s: symbol) +.decl reachable_via_path(s: symbol, o: symbol, reverse_path: List) +.decl cycle_path(s: symbol, reverse_path: List) +.decl cycle_path_text_builder(s: symbol, text_path: symbol, remaining: List) +.decl cycle(text_path: symbol) relation(s, p, o) :- basic(s, RDFS_SUBCLASS_OF, restr), @@ -19,10 +31,16 @@ relation(s, p, o) :- relation(s, RDFS_SUBCLASS_OF, o) :- basic(s, RDFS_SUBCLASS_OF, o), match("<.+>", s), match("<.+>", o). -reachable(s, o) :- relation(s, _, o). -reachable(s, o) :- relation(s, _, c), reachable(c, o). +reachable_via_path(s, o, [[p, o], nil]) :- relation(s, p, o). +reachable_via_path(s, o, [[p, o], path]) :- reachable_via_path(s, c, path), relation(c, p, o), s != c, s != o. + +cycle_path(s, path) :- reachable_via_path(s, s, path). +cycle_path(s, [[p, s], path]) :- reachable_via_path(s, c, path), relation(c, p, s), s != c. + +cycle_path_text_builder(s, cat(" --[", p, "]--> ", o), remaining) :- cycle_path(s, [[p, o], remaining]). +cycle_path_text_builder(s, cat(" --[", p, "]--> ", o, current), remaining) :- cycle_path_text_builder(s, current, [[p, o], remaining]). -cycle(s) :- reachable(s, s). +cycle(cat(s, current)) :- cycle_path_text_builder(s, current, nil). .input basic .output cycle