annotate service/reasoning/escapeoutputstatements.py @ 1402:5373c5cc03c4

device configs Ignore-this: 6e052d5533da601f72c6e7017b232e8c darcs-hash:b179d80e8a1c78f71d851b78f2e54ab781d9d1e7
author drewp <drewp@bigasterisk.com>
date Tue, 23 Jul 2019 10:16:14 -0700
parents cb7fa2f30df9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1089
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
1 """
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
2 Why?
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
3
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
4 Consider these rules:
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
5 { :button1 :state :press . :lights :brightness 0 } => { :lights :brightness 1 }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
6 { :button1 :state :press . :lights :brightness 1 } => { :lights :brightness 0 }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
7 { :room1 :sees :motion } => { :house :sees :motion }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
8 { :room2 :sees :motion } => { :house :sees :motion }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
9 { :house :sees :motion } => { :outsideLights :brightness 1 }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
10
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
11 Suppose we ran with these inputs:
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
12 :lights :brightness 0 .
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
13 :button1 :state :press .
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
14 Those will trigger the first *two* rules, since we run rules forward
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
15 until no more statements are produced.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
16
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
17 The problem here is that (:lights :brightness ?x) is both an input
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
18 statement and an output statement, but it's the kind of output that is
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
19 not meant to cascade into more rules. A more precise way to read the
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
20 first rule is "if button1 is pressed and lights WERE at brightness 0,
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
21 then the lights SHOULD BE at brightness 1".
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
22
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
23 Can we just stop running the rules when we get the first :brightness
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
24 output and not run the second rule? Not in general. Consider the third
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
25 rule, which generates (:house :sees :motion). That output triple is
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
26 meant as an input to the last rule. There's no clear difference
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
27 between (:lights :brightness 1) and (:house :sees :motion) in this
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
28 graph. Only with external knowledge do I know that (:lights
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
29 :brightness 1) shouldn't cascade.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
30
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
31 Possible fixes:
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
32
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
33 1. Make the :brightness predicate more clear, like
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
34 (:lights :was_brightness 0) or (:lights :new_brightness 1). Dealing
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
35 with multiple predicates for different "tenses" seems like a pain.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
36
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
37 2. Put input statements in a subgraph and match them specifically in there:
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
38 {
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
39 :button1 :state :press . GRAPH :input { :lights :brightness 0 }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
40 } => {
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
41 :lights :brightness 1
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
42 }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
43
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
44 (:button1 :state :press) is allowed to match anywhere, but (:lights
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
45 :brightness 0) must be found in the :input graph. How do you say
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
46 this in N3? My example is half SPARQL. Also, how do you make rule
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
47 authors remember to do this? The old mistake is still possible.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
48
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
49 3. (current choice) RDF-reify output statements so they don't cascade,
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
50 then recover them after the rule run is done.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
51
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
52 {
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
53 :button1 :state :press . :lights :brightness 0
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
54 } => {
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
55 :output :statement [ :subj :lights; :pred :brightness; :obj 1 ]
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
56 }
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
57
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
58 This works since the output statement definitely won't trigger more
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
59 rules that match on :lights :brightness. It's easy to recover the true
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
60 output statement after the rules run. Like #2 above, it's still easy
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
61 to forget to reify the output statement. We can automate the
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
62 reification, though: given patterns like (?s :brightness ?o), we can
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
63 rewrite the appropriate statements in implied graphs to their reified
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
64 versions. escapeOutputStatements does this.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
65
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
66 4. Reify input statements. Just like #3, but alter the input
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
67 statements instead of outputs.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
68
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
69 This seems more expensive than #3 since there are lots of input
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
70 statements that are given to the rules engine, including many that are
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
71 never used in any rules, but they'd all have to get reified into 4x as
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
72 many statements. And, even within the patterns that do appear in the
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
73 rules, a given triple probably appears in more input graphs than
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
74 output graphs.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
75 """
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
76 import unittest
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
77 from rdflib.parser import StringInputSource
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
78 from rdflib import Graph, URIRef, Namespace, BNode
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
79 from rdflib.compare import isomorphic
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
80
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
81 NS = Namespace('http://projects.bigasterisk.com/room/')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
82
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
83 def escapeOutputStatements(graph, outputPatterns):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
84 """
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
85 Rewrite
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
86 {} => { :s :p :o } .
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
87 to
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
88 {} => { :output :statement [ :subj :s; :pred :p; :obj :o ] } .
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
89
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
90 if outputPatterns contains an element matching (:s, :p, :o) with
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
91 None as wildcards.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
92
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
93 Operates in-place on graph.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
94 """
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
95 for s, p, o in graph:
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
96 if isinstance(o, Graph):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
97 o = escapeOutputStatements(o, outputPatterns)
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
98 variants = {(s, p, o),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
99 (s, p, None),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
100 (s, None, o),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
101 (s, None, None),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
102 (None, p, o),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
103 (None, p, None),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
104 (None, None, o),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
105 (None, None, None)}
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
106
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
107 if not variants.isdisjoint(outputPatterns):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
108 graph.remove((s, p, o))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
109 stmt = BNode()
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
110 graph.add((stmt, NS['subj'], s))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
111 graph.add((stmt, NS['pred'], p))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
112 graph.add((stmt, NS['obj'], o))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
113 graph.add((NS['output'], NS['statement'], stmt))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
114
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
115
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
116 def unquoteOutputStatements(graph):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
117 """
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
118 graph can contain structures like
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
119
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
120 :output :statement [:subj ?s; :pred ?p; :obj ?o]
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
121
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
122 which simply mean the statements (?s ?p ?o) are meant to be in
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
123 the output, but they had to be quoted since they look like
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
124 input statements and we didn't want extra input rules to fire.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
125
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
126 This function returns the graph of (?s ?p ?o) statements found
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
127 on :output.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
128
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
129 Todo: use the standard schema for the escaping, or eliminate
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
130 it in favor of n3 graph literals.
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
131 """
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
132 out = Graph()
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
133 for qs in graph.objects(NS['output'], NS['statement']):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
134 out.add((graph.value(qs, NS['subj']),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
135 graph.value(qs, NS['pred']),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
136 graph.value(qs, NS['obj'])))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
137 return out
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
138
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
139
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
140 ################################################################
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
141 # tests
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
142
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
143 def fromN3(n3):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
144 g = Graph(identifier=URIRef('http://example.org/graph'))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
145 g.parse(StringInputSource(('@prefix : %s .\n' % URIRef(NS).n3()) + n3),
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
146 format='n3')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
147 return g
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
148
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
149 def impliedGraph(g):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
150 if len(g) != 1: raise NotImplementedError
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
151 stmt = list(g)[0]
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
152 return stmt[2]
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
153
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
154 class TestEscapeOutputStatements(unittest.TestCase):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
155 def testPassThrough(self):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
156 g = fromN3(''' { :a :b :c } => { :d :e :f } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
157 escapeOutputStatements(g, [])
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
158 self.assertEqual(fromN3(''' { :a :b :c } => { :d :e :f } . '''), g)
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
159
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
160 def testMatchCompletePattern(self):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
161 g = fromN3(''' { :a :b :c } => { :d :e :f } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
162 escapeOutputStatements(g, [(NS['d'], NS['e'], NS['f'])])
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
163 expected = fromN3('''
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
164 { :a :b :c } =>
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
165 { :output :statement [ :subj :d; :pred :e; :obj :f ] } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
166 self.assert_(isomorphic(impliedGraph(expected), impliedGraph(g)))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
167
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
168 def testMatchWildcardPatternOnObject(self):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
169 g = fromN3(''' { :a :b :c } => { :d :e :f } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
170 escapeOutputStatements(g, [(NS['d'], NS['e'], None)])
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
171 expected = fromN3('''
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
172 { :a :b :c } =>
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
173 { :output :statement [ :subj :d; :pred :e; :obj :f ] } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
174 self.assert_(isomorphic(impliedGraph(expected), impliedGraph(g)))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
175
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
176 def testWildcardAndNonMatchingStatements(self):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
177 g = fromN3(''' { :a :b :c } => { :d :e :f . :g :e :f . } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
178 escapeOutputStatements(g, [(NS['d'], NS['e'], NS['f'])])
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
179 expected = fromN3('''
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
180 { :a :b :c } =>
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
181 { :output :statement [ :subj :d; :pred :e; :obj :f ] .
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
182 :g :e :f } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
183 self.assert_(isomorphic(impliedGraph(expected), impliedGraph(g)))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
184
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
185 def testTwoMatchingStatements(self):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
186 g = fromN3(''' { :a :b :c } => { :d :e :f . :g :e :f } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
187 escapeOutputStatements(g, [(None, NS['e'], None)])
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
188 expected = fromN3('''
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
189 { :a :b :c } =>
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
190 { :output :statement [ :subj :d; :pred :e; :obj :f ],
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
191 [ :subj :g; :pred :e; :obj :f ] } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
192 self.assert_(isomorphic(impliedGraph(expected), impliedGraph(g)))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
193
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
194 def testDontReplaceSourceStatements(self):
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
195 g = fromN3(''' { :a :b :c } => { :a :b :c } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
196 escapeOutputStatements(g, [(NS['a'], NS['b'], NS['c'])])
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
197 expected = fromN3('''
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
198 { :a :b :c } =>
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
199 { :output :statement [ :subj :a; :pred :b; :obj :c ] } . ''')
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
200 self.assert_(isomorphic(impliedGraph(expected), impliedGraph(g)))
cb7fa2f30df9 rules become simple-looking again; fix the ambiguity in memory after loading them.
drewp <drewp@bigasterisk.com>
parents:
diff changeset
201