I am trying out some forward chaining rules on some simple family relations, and it looks to me like NOTANY does not work the way one would think it would work. I assumed that the following clause only succeeds if none of the embedded premises are true:
notany
premise1
premise2
premise3
However, this does not seem to be the case. It appears that notany works fine to negate a single premise but cannot handle multiple premises properly. For example, the following is my knowledgebase and rulebase. Even though the KB asserts dead(jon), the rulebase still asserts cousins_of_living_uncles(marc, will) which is wrong.
Ok this really looks like a bug. The notany premise really behaves instead like a "notall". In other words, at least in forward chainging, notall will only succeed if ALL of the embedded premises fail. One would think from the ord "notall" that it would only take one embedded premise for the whole thing to fail, but in fact it takes ALL the embedded premises to fail! You can see this in my example by setting both dead(jon) and dead(william_david). That is the only way to make dummy.cousins_of_living_uncles not get asserted.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Since a solution requires proving both premises simultaneously, failing
to prove either premise would suffice for the notany to succeed. By
"simultaneously", Pyke will backtrack from the second premise back to the
first to look for all combinations of solutions before it declares the pair
un-provable. Thus, not any of the possible combinations succeed.
As you've already pointed out; if you want to check that both premises fail
independently of each other (i.e., neither succeeds by itself), you should
use two independent notany clauses. Then the two notany clauses would be
AND-ed: (notany dummy.dead($father1)) AND (notany dummy.dead($father2)).
Here is an example where notany requires the use of multiple premises. I
want to produce sons that have no brothers:
Ok this really looks like a bug. The notany premise really behaves instead
like a "notall". In other words, at least in forward chainging, notall will
only succeed if ALL of the embedded premises fail. One would think from the
ord "notall" that it would only take one embedded premise for the whole
thing to fail, but in fact it takes ALL the embedded premises to fail! You
can see this in my example by setting both dead(jon) and
dead(william_david). That is the only way to make
dummy.cousins_of_living_uncles not get asserted.
Well, ok, maybe I understand it now. The word 'notany' really refers to 'not any variable binding will make the following premise (or premises) true'. Any set of embedded premises in a notany clause will be AND-ed together to determine the overall truth or falsehood of the embedded set. So having an embedded set of premises for notany really means 'no variable bindings will make this embedded set all true.' So, to see if any premise (ie one or more) from a given set of premises is true, and fail if that is the case, one really needs to specify notany for each premise in the set one at a time.
Did I get this right? That seems to be the way it actually works in my tests.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well, ok, maybe I understand it now. The word 'notany' really refers to
'not any variable binding will make the following premise (or premises)
true'. Any set of embedded premises in a notany clause will be AND-ed
together to determine the overall truth or falsehood of the embedded set.
So having an embedded set of premises for notany really means 'no variable
bindings will make this embedded set all true.' So, to see if any premise
(ie one or more) from a given set of premises is true, and fail if that is
the case, one really needs to specify notany for each premise in the set
one at a time.
Did I get this right? That seems to be the way it actually works in my
tests.
That is right. My prior email and your here crossed paths...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am trying out some forward chaining rules on some simple family relations, and it looks to me like NOTANY does not work the way one would think it would work. I assumed that the following clause only succeeds if none of the embedded premises are true:
However, this does not seem to be the case. It appears that notany works fine to negate a single premise but cannot handle multiple premises properly. For example, the following is my knowledgebase and rulebase. Even though the KB asserts dead(jon), the rulebase still asserts cousins_of_living_uncles(marc, will) which is wrong.
What am I doing wrong? Or is this a bug?
NOTE: If instead of
I use
then it seems to work for this example. But it seems to me to be highly misleading that notany only works properly with one embedded premise!
What am I missing here?
Ok this really looks like a bug. The notany premise really behaves instead like a "notall". In other words, at least in forward chainging, notall will only succeed if ALL of the embedded premises fail. One would think from the ord "notall" that it would only take one embedded premise for the whole thing to fail, but in fact it takes ALL the embedded premises to fail! You can see this in my example by setting both dead(jon) and dead(william_david). That is the only way to make dummy.cousins_of_living_uncles not get asserted.
No, it is working as advertised
http://pyke.sourceforge.net/pyke_syntax/krb_syntax/compound_premise.html#notany-premise.
It only succeeds if there is not any solution to the nested premises (which
would be AND-ed, as lists of premises always are). Thus there is not any
solution to:
dummy.dead($father1) AND dummy.dead($father2)
Since a solution requires proving both premises simultaneously, failing
to prove either premise would suffice for the notany to succeed. By
"simultaneously", Pyke will backtrack from the second premise back to the
first to look for all combinations of solutions before it declares the pair
un-provable. Thus, not any of the possible combinations succeed.
As you've already pointed out; if you want to check that both premises fail
independently of each other (i.e., neither succeeds by itself), you should
use two independent notany clauses. Then the two notany clauses would be
AND-ed: (notany dummy.dead($father1)) AND (notany dummy.dead($father2)).
Here is an example where notany requires the use of multiple premises. I
want to produce sons that have no brothers:
only_son
foreach
dummy.son_of($son, $father)
notany
dummy.son_of($brother, $father)
check $son != $brother
assert
dummy.only_son($son, $father)
Hope this helps!
-Bruce
On Wed, Dec 24, 2014 at 7:20 PM, westofpluto westofpluto@users.sf.net
wrote:
Well, ok, maybe I understand it now. The word 'notany' really refers to 'not any variable binding will make the following premise (or premises) true'. Any set of embedded premises in a notany clause will be AND-ed together to determine the overall truth or falsehood of the embedded set. So having an embedded set of premises for notany really means 'no variable bindings will make this embedded set all true.' So, to see if any premise (ie one or more) from a given set of premises is true, and fail if that is the case, one really needs to specify notany for each premise in the set one at a time.
Did I get this right? That seems to be the way it actually works in my tests.
On Wed, Dec 24, 2014 at 7:37 PM, westofpluto westofpluto@users.sf.net
wrote: