-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implicit quantification #5
Comments
It seems unambiguous to me that the An interesting use case might be the following: @forAll :x .
:A :p3 :o .
:B :p :o .
{?x :p3 :o} => {:a :b :x } .
{{?x :p :o} => {?x :p2 :o2}} => {:a :b :x} . I think it should result in |
OK, so for you the parent is the next higher formula in braces? EYE sees the top formula as parent. I will give some examples later why I think that Cwm's interpretation is problematic, but I want one example at the time and I do not get yours yet. I do not get how you would come to your I also disagree that your example should result in |
Well, to me, without firm definition, "parent" means immediate ancestor, so the parent of a formula is the formula within which it's contained. I think the reasoning for this is that if you consider something like Regarding the lexical ordering of In these cases, the same variable name is used in different The question of if The argument for having separate variables denoted using the same syntax being disjoint is made stronger when you consider importing rules from multiple different files, where variables such as My example likely has issues, but could be reframed to create a test case to determine how implementations handle the same variable name, both when used in different scopes or in different order within the same scope, are handled. Perhaps trying something different: {:a :b ?x} => {:a :c ?x} .
{:d :e ?x} => {:d :f ?x} .
:a :b 10 .
:d :e 11 . My implementation produces: :a :b 10; :c 10 .
:d :e 11; :f 11 . |
On Wed, Jan 23, 2019 at 6:56 PM Gregg Kellogg ***@***.***> wrote:
Well, to me, without firm definition, "parent" means immediate ancestor,
so the parent of a formula is the formula within which it's contained.
I think the reasoning for this is that if you consider something like {?x
:p3 :o} => {:a :b ?x } as an operator the allow for the scope of the
variable to include the operator. My implementation turns this into the
S-Expression (logImplies (formula (triple ?x :p3 :o)) (formula (triple :a
:b ?x)). This allows the variable ?x used in both formula to be the same
variable. Promoting it to the root would not support this specific use case.
Regarding the lexical ordering of @***@***.*** clauses in the same
scope, I drew my conclusions from SWAP examples such as the following:
- metab.n3 <https://www.w3.org/2000/10/swap/test/EricNeumann/metab.n3>
- getcom-relations.n3
<https://www.w3.org/2000/10/swap/test/gedcom/gedcom-relations.n3>
In these cases, the same variable name is used in different @forall
clauses in the same scope; it may be that they would quantify the same
values, but it's not clearly the intention of the specs (such as they are).
The question of if @forall :x and ?x denote the same variable name may be
an implementation concern. We should probably say if the set of all
explicit universal variables and implicit universal variables are disjoint
or not.
The argument for having separate variables denoted using the same syntax
being disjoint is made stronger when you consider importing rules from
multiple different files, where variables such as ?x could easily bind to
different solutions, unless this is more properly specified.
My example likely has issues, but could be reframed to create a test case
to determine how implementations handle the same variable name, both when
used in different scopes or in different order within the same scope, are
handled.
Perhaps trying something different:
{:a :b ?x} => {:a :c ?x} .
{:d :e ?x} => {:d :f ?x} .
:a :b 10 .
:d :e 11 .
My implementation produces:
:a :b 10; :c 10 .
:d :e 11; :f 11 .
Nice and same for EYE:
$ echo -e "PREFIX : <http://example.org/try#>\n\n{:a :b ?x} => {:a :c ?x}
.\n{:d :e ?x} => {:d :f ?x} .\n:a :b 10 .\n:d :e 11 ." | eye --nope --n3 -
--pass
produces
PREFIX : <http://example.org/try#>
:a :b 10 .
:d :e 11 .
:a :c 10 .
:d :f 11 .
As for your other example
$ eye --nope --n3 https://www.w3.org/2000/10/swap/test/EricNeumann/metab.n3
--pass
produces
PREFIX bg: <http://www.bg.org/bio#>
PREFIX daml: <http://www.daml.org/2001/03/daml+oil#>
PREFIX rules: <http://infomesh.net/2001/05/rdflint/rules#>
PREFIX log: <http://www.w3.org/2000/10/swap/log#>
PREFIX v: <http://infomesh.net/2001/05/rdflint/vars#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <https://www.w3.org/2000/10/swap/test/EricNeumann/metab.n3#>
bg:catalyzes a daml:ObjectProperty.
bg:Protein a daml:Class.
bg:modification a daml:Property.
bg:Enzyme a daml:Class.
bg:BioChemical a daml:Class.
bg:Compound a daml:Class.
bg:Reaction a daml:Class.
bg:reactsIn a daml:ObjectProperty.
bg:isProducedBy a daml:ObjectProperty.
bg:consumes a daml:ObjectProperty.
bg:produces a daml:ObjectProperty.
bg:metabolizes a daml:ObjectProperty.
bg:synthesizes a daml:ObjectProperty.
bg:Substrate a daml:Class.
bg:Product a daml:Class.
bg:isUpStream a daml:TransitiveProperty.
bg:isDownStream a daml:TransitiveProperty.
:glucose6P a bg:Compound.
:fructose6P a bg:Compound.
:Glu2Fru a bg:Reaction.
:GluIsomerase a bg:Enzyme.
:fructose1P a bg:Compound.
:Fru62Fru1 a bg:Reaction.
:FruPIsomerase a bg:Enzyme.
bg:catalyzes daml:minCardinality "1".
bg:catalyzes daml:range bg:Reaction.
bg:modification daml:range rdfs:Literal.
bg:reactsIn daml:range bg:Reaction.
bg:isProducedBy daml:range bg:Reaction.
bg:consumes daml:range bg:Substrate.
bg:produces daml:range bg:Product.
bg:isUpStream daml:range bg:BioChemical.
bg:isDownStream daml:range bg:BioChemical.
bg:Protein daml:hasProperty bg:modification.
bg:Enzyme daml:hasProperty bg:catalyzes.
bg:BioChemical daml:hasProperty bg:isUpStream.
bg:BioChemical daml:hasProperty bg:isDownStream.
bg:Reaction daml:hasProperty bg:consumes.
bg:Reaction daml:hasProperty bg:produces.
bg:Substrate daml:hasProperty bg:reactsIn.
bg:Product daml:hasProperty bg:isProducedBy.
bg:Protein daml:subClassOf bg:BioChemical.
bg:Enzyme daml:subClassOf bg:Protein.
bg:Compound daml:subClassOf bg:BioChemical.
bg:Substrate daml:subClassOf bg:BioChemical.
bg:Product daml:subClassOf bg:BioChemical.
bg:consumes daml:inverseOf bg:reactsIn.
bg:produces daml:inverseOf bg:isProducedBy.
bg:isDownStream daml:inverseOf bg:isUpStream.
:glucose6P bg:reactsIn :Glu2Fru.
:fructose6P bg:reactsIn :Fru62Fru1.
:Glu2Fru bg:produces :fructose6P.
:Fru62Fru1 bg:produces :fructose1P.
:GluIsomerase bg:catalyzes :Glu2Fru.
:FruPIsomerase bg:catalyzes :Fru62Fru1.
:GluIsomerase bg:synthesizes :fructose6P.
:FruPIsomerase bg:synthesizes :fructose1P.
Kind regards,
Jos
… —
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#5 (comment)>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/AALzpPFlWmoA4dz-mbog4JDokfvhEWPxks5vGKI1gaJpZM4Z-Zz9>
.
|
Thank you for your clarification. Your last example case is much clearer and I would expect the same answer your reasoner gives. For the two SWAP files you mention: I see why you came to the conclusion that the lexical order matters, but from a logical point of view it does not really matter whether or not you repeat the universal quantifiers of the variables.
should lead to the same results as:
What do you do if you have:
Cwm gave me:
Which does not really help since I do not know how :x is quantified. I also have another question: what do you get if you have the following input:
I tested with Cwm and EYE and saw that EYE derives |
@doerthe said:
I get the following data produced: :s :b :c; :p :o . So, I do not produce
I don't handle blank node scoping properly yet. But, it seems to me that Alternatively, the |
I do not get why it is unbound, could you explain? Isn't it bound by the existential quantifier in front of the triple. I would have expected based on what you told me so far that you'd produce:
Without blank nodes we can still have a similar example, so what do you do for:
Based on your answer above I would expect that you'd expect a reasoner to derive EYE understands the rule as: ∀x:∀x_2: p(x, b(x_2,c)) → p(s,o) This allows the reasoner to unify the antecedent of the rule with the triple and come to the result With Cwms's interpretation this cannot be derived, the reasoner understands the rule as: ∀x:: p(x, (∀x_2: b(x_2,c))) → p(s,o) Since in the triple Cwm would derive
|
@doerthe said:
:s :p :o.
@forAll :x. {:x :p :o}=>{:x :b :c}.
@forSome :x. {:s :p :o}=>{:a :b :x}. The first implication binds the universal quantifier The second implication redefines
It's not the blank nodes that I don't support, but the formula as part of the dataset. i have since updated my code to treat blank nodes as unique to each formula.
Here we get to what is meant by variable scope. My understanding, is that variable scope relates to their visibility within formulae, not the dataset. My implementation currently only reasons over data in the default graph, but I think it would be consistent to say that the pattern The inner most formula has solutions, which allow the outermost formula to bind to the blank node for the named graph having that solution. The outermost formula therefore also has a solution, so the consequent The other thing I've noticed about variables is if they bind in one formula, those bindings are not in effect in another formula at the same level. I discovered this when working on unify5: @keywords is, a .
fred siblings ( [ parents (Zeus Juno), (Alice Bob), (Jane Joe) ] Aphrodite ).
{ fred siblings ( [] ?x ) } => { ?x a ShouldBeAphrodite }.
{ fred siblings ( ?y ?x ) } => { ?y a BnodeExtractedError }.
{ fred siblings ( [ parents ([] ?y) ] ?x ) } => { ?x a ShouldBeAphrodite2. ?y a ShouldBeJunoBobJoe }. In the second formula, CWM produces the following result:
|
I see here again the problem that you understand rules like if-else statements in imperative programming if you say:
Here, we deal with logical rules, so what we actually say by a rule is that if the antecedent is true, so is the consequence. Note furthermore, that
Cwm derives:
The important part here is that we get:
According to the w3c team submission this is the same as:
Note that we deal with two different things here, the scope and the position of the quantifier. If you understand a SPARQL query as a rule, you would still only get the bindings as you describe them if the position of the quantifier is outside of the whole formula. So, the rule
will lead to But for cwm, the formula:
as the formula is quantified on what cwm sees as "the parent". So, to stay in your graph example, the rule would only "fire" if in your subgraph we would either have the triple
Please note, the you deal with logical rules here. There is no reason why, if a triple fulfils the antecedent of one rule which therefore "fires" the antecedent of another rule would also be fulfiled by simply using the same binding we had for the first rule. Since I find the siblings rather confusing (more to refer to, not the example as such), I give you an easier example. Following the rule Jos had in the other issue, consider the two rules:
These means: "If an instance is made of stone, it is a :StoneObject and if it is made of cheese, it can be eaten." The rules above can both be instantiated by binding
Both of these rules are true: If the moon is made out of stone, it is a stone object and if the moon is made of cheese, it can be eaten. Now we have some knowledge, namely:
We can thus conclude:
For the antecedent of the second rule we have no evidence, we therefore do not know whether or not the moon is made of cheese (cheese and stone could still be the same), we cannot derive anything from our triple using the second rule. To conclude: there are two steps, the binding and the application of the rule. You can bind the universal variables in your example with any instance of the universe, but that does not mean that you can apply the rule. You can only apply the rule, if you find evidence for the antecedent, ie you either have the concrete triples present in your bound version of the rule stated in your database or you can derive these triples by using other rules. |
I actually don't get that output from CWM using
Great, thanks for helping my understanding. It makes sense for existential quantifiers that the consequent simply emits the quantifier as part of the output. However, if :s :p :o.
@forAll :x. {:x :p :o}=>{:x :b :c}.
@forSome :y. {:s :p :y}=>{:a :b :y}. would then generate :s :p :o, :b :c .
:a :b :o .
I have to think about this, and how to interpret it in light of the description of
What is the "knowledge-base" against which
This makes sense to me know, in light of your clarification on the level at which a variable is introduced. Thanks for the great detailed explanations. |
This is indeed strange. I just used the input I listed together with --think and got the output I also posted. Maybe we have different versions of Cwm? I have v 1.197 2007/12/13 15:38:39 syosi.
Please note that there is a difference between The binding you describe can only happen for a rule containing a variable which is quantified with "For all x in the universe the rule
is valid. This rule can be applied if we encounter the triple In the case of a variable used together with "There is some (note not all, only some) We cannot apply the rule
In the example, the In general I think it is also problematic to see the logical implication just as a simple relationship since I think a logical operator is more than that (something like that was also briefly mentioned before in the mailing list). I would also like to separate the semantic view (what does it mean) from the operational view (what does the reasoner do?) here and first concentrate on the logical meaning of an implication. But that just as a side remark. |
It seems like we've gotten a bit off track here, talking e.g., about existing implementation behaviors and interpretations of different logic operators. Although these side discussions have certainly been useful, it may become a bit daunting for others to get a good view of where we stand on this issue. If you feel that we missed anything please feel free to comment. To summarize, I believe that we've arrived at the following (some copied from previous posts, others from personal discussions): The shorthand syntax “?x” implies that x is universally quantified not in the formula but in its parent formula. Firstly, is this a good thing; and secondly, what exactly should this "parent" be?
@doerthe: To give a concrete example, consider the rule:
Cwm interprets that as:
EYE interprets it as:
@Gregg: it seems unambiguous to me that the EDIT it seems that scoping at the outermost level would be most appropriate:
Quantification in the parent formula instead of the formula itself, has consequences for the semantics of the formula. For instance, take the simplified example:
Quantification inside the same formula:
Quantification in a parent formula:
In the first formula, x is scoped only to the rule premise, meaning that only when all x in the universe adhere to the condition will the consequent also be valid (i.e., the consequent holds if the condition is met by all instances). The second formula states that, for all x in the universe, in case the condition holds for any x, the consequent will also be valid for that x. In light of this, it does seem to make sense to me to quantify on the parent formula for logical implications. Further, I greatly appreciate that a "simpler" syntax is available for dealing with universal quantification (i.e., "?x"). It should be straightforward to encode many practical use cases using this notation; this allows developers to start coding with this simpler syntax and later move on to explicit quantifiers (when or if needed) and all the complexity that brings. @doerthe gives a good case for when this could go wrong however: the reason why quantification on the parent formula is so problematic is that you can change the meaning of a formula by simply adding another one somewhere else in you N3 document. I do not expect that people are careful with the variables they use. So, for cwm,
means
but: by only adding one new rule somewhere in the document which contains the same universal variable on a higher level this changes.
means
This makes scoping very unstable. EDIT How to cope with a variable being introduced at a higher level in a formula, and then that variable being differently quantified "lower down" in that formula? I.e., how to cope with variable name clashes? Would these be different variables with the same name in different scopes (as I think was suggested by @gkellogg but I could be wrong) EDIT bnode identifiers: RDF vs N3
There were other discussions as well, e.g., on differences between operational and semantic views (scoping of variable bindings) (starting from here) and the application of quantifiers (see here). |
I think my statement was misinterpreted. In my view, the meaning of
I'm not sure that it does, I think this could be interpreted that there are two variables with the same name introduced in different scopes. However, it may become more practical to scope the universal variables at the outermost level, as EYE apparently does, and this would clear up this kind of confusion. If we ever want to separate the reasoning from N3, and define it more broadly over an extension to RDF 1.1 datasets, we might introduce universal and existential variables as resources, similar to IRIs and Bland Nodes. Defining a scoping rule for variables to formulae/graphs would be out of keeping with the typical triple/quad representation used in many implementations. My own implementation of N3 reasoning (such as it is) does just this, and parses the N3 into an extended dataset. The scope of equivalently named variables and blank nodes can be handled within the parser. I internally produce unique names for variables and blank node labels to enforce the rules defined for N3. |
For implicit quantification (i.e., To your point, putting the quantification on the direct parent formula will likely lead to confusion when one starts nesting formulae in the condition .. Although this may introduce variable name clashes (as @doerthe says), they also seems like a more general problem that is not limited to implicit quantification (?) How do we deal with a variable being introduced at a higher level in a formula, and then that variable being differently quantified "lower down" in that formula (i.e., in a nested clause)?
For sure, a parser could certainly apply the N3 variable scoping rules and consequently generate unique names to differentiate them. It would be interesting to know what policy your parser applies to generate these unique names for variables. |
In my case, I create an identifier applied to every bnode/variable along with a sequence, which increments with each distinct bnode/variable. It could just as well be a UUID, but this does help debugging somewhat. A spec, clearly, should not specify at this level of detail. One challenging thing for general RDF Dataset use is that RDF Concepts says that Blank node identifiers are locally scoped to the store, and not to the graph within which they are contained, as N3 dictates. Pat Hayes recently suggested a more explicit scoping mechanism (also in w3c/EasierRDF#19), which would define some syntactic structure for constraining the scope of bnode labels. Pat proposed the following:
In any case, these are syntactic constructs and don't affect the underlying data model, but such syntactic constructs would need an expression in the different RDF serializations (e.g., JSON-LD), not just the Turtle/N3 family. |
I also think that it is simply more practical to assume the universal quantification on top level. For the other cases we can still use explicit quantification if we really need this expressiveness (I am actually not sure here). An the notation Pat Hayes introduced also goes into that direction. @gkellogg Just to be sure, can you create a small example for the below:
I think you refer to named graphs and the fact that in
the two
these two I think that we should follow N3's solution here simply to be able to refer to a local blank node in a graph. Even without explicit quantification, skolemisation could bring us to rdf's interpretation, but there is no way from rdf to N3 here. |
👍
I wasn't suggesting changing N3's scoping rules, but it is a consideration when considering reasoning from other serializations. Of course, this can be solved at the syntax level by just not reusing blank node identifiers that should be distinct. |
When I started working with N3 I thought so too, but please remember that we do not simply talk about different variables here but also about different positions of quantifiers. If we come back to my example from above, the following graph
means in "pseudo" first order logic:
while the existential quantifier for TriG is outside the graph. If I try to write it down somehow first-order logic like, I could say:
It really makes a difference where the existential quantifier is located. |
Not sure how to reconcile that, but if we want to put forth a solution that works generally for RDF datasets, we'll need to figure this out. Otherwise, remain stuck in an N3 backwater with no way forward to reconcile with RDF. |
Same here as with #6 - I believe @doerthe and @josd talked to the designers of N3, and got some insight into what exactly constitutes the "parent" formula in the original N3, and why. Here, I think we were closer to a concrete decision - i.e., the parent formula being the outermost level. Perhaps they could explain it here :-) . |
You are right, we asked TBL why he choose the concept o the parent the way he did. His reason was that he wanted to treat cited graphs as formulas you read from another file. If you directly have something like |
Just to clarify, in TBL’s view the parent formula would have been the lexical “parent” (i.e., containing) formula? Since citing any (external) formula would then be neatly scoped on its (new) parent formula? Not understanding the reason fully here. Maybe scenarios like your second example were not considered?
Regardless, I think using the top (outer) scope makes a lot of sense to me. As said, I think we were pretty close to a consensus here.
|
I believe we agreed some time ago on outermost-level scope. |
When we used the reasoners Cwm and EYE, we discovered, that they differed in their way of handling implicit universal quantification. To give a concrete example, consider the rule:
Cwm interprets that as:
EYE interprets it as:
The reason for that the W3C team submission is not really clear here, it says that universals are quantified "on the parent formula" (see https://www.w3.org/TeamSubmission/n3/#Quantifica), but it does not say what exactly this "parent" is.
How do the other reasoners handle this case?
The text was updated successfully, but these errors were encountered: