Help with very simple example

389 views
Skip to first unread message

Baltasar García Perez-Schofield

unread,
Nov 22, 2013, 6:57:05 AM11/22/13
to py...@googlegroups.com
Hi, there,

I'm new to Pyke, and I'm unable to make it work for a tiny example.

This is my code in the family.py file:

==
from pyke import knowledge_engine

engine = knowledge_engine.engine( __file__ )
engine.assert_( "family", "sonOf", ( "Hector", "Baltasar" ) );
engine.assert_( "family", "sonOf", ( "Hector", "Rosa" ) );
engine.assert_( "family", "sonOf", ( "Baltasar", "Jose" ) );
engine.assert_( "family", "sonOf", ( "Baltasar", "Juana" ) );
engine.assert_( "family", "sonOf", ( "Rosa", "Maria" ) );
engine.assert_( "family", "sonOf", ( "Rosa", "Robustiano" ) );

engine.get_kb( "family" ).dump_specific_facts();

engine.activate( "bc_family" );
engine.prove_1_goal( "family.grandSonOf( Hector, Jose )" )
==

bc_family.krb is:
==
grandSonOf
use grandSonOf( $son, $grandfather )
when
sonOf( $son, $father )
sonOf( $father, $grandfather  )
==

However, the exception cannot_prove is raised. What am I doing wrong?
Thanks in advance,

-- Baltasar

Bruce Frederiksen

unread,
Nov 22, 2013, 7:23:54 AM11/22/13
to py...@googlegroups.com
Two things:

1.  Your knowledge base name in the call to prove_1_goal should be bc_family rather than family:

engine.prove_1_goal( "bc_family.grandSonOf( Hector, Jose )" )

2. The sonOf facts in your grandSonOf rule are in the family knowledge base, so need a family prefix:

grandSonOf
use grandSonOf( $son, $grandfather )
when
family.sonOf( $son, $father )
family.sonOf( $father, $grandfather  )

-Bruce


--
You received this message because you are subscribed to the Google Groups "PyKE" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyke+uns...@googlegroups.com.
To post to this group, send email to py...@googlegroups.com.
Visit this group at http://groups.google.com/group/pyke.
For more options, visit https://groups.google.com/groups/opt_out.

Baltasar García Perez-Schofield

unread,
Nov 24, 2013, 12:11:48 PM11/24/13
to py...@googlegroups.com
Hi, Bruce

Two things:
1.  Your knowledge base name in the call to prove_1_goal should be bc_family rather than family:
2. The sonOf facts in your grandSonOf rule are in the family knowledge base, so need a family prefix:


Thank you, now it works.
However, I'm having trouble accessing the results. I mean, I made it work by using "with":
==
with engine.prove_goal( "bc_family.grandSonOf( $x, $y )" ) as gen:
    for vars, plan in gen:
        engine.assert_( "family", "grandSonOf", ( vars[ "x" ], vars[ "y" ] ) );

engine.get_kb( "family" ).dump_specific_facts();
==
Without "with", i.e.:
==
gen2 = engine.prove_goal( "bc_family.grandSonOf( $x, $y )" )
for vars, plan in gen2:
        engine.assert_( "family", "grandSonOf", ( vars[ "x" ], vars[ "y" ] ) );
==

I always get the error "producer is not iterable"... I guess "producer" is the class of object returned, but... why can I only access it using with?

Bruce Frederiksen

unread,
Nov 24, 2013, 3:34:59 PM11/24/13
to py...@googlegroups.com
The internals of Pyke use generators to produce the matches to a goal.  The pattern variables use a shallow binding mechanism that requires the generator to undo the bindings when it is done.

The problem is that it is not always up to the generator to determine when it is "done".  Sometimes the caller decides it doesn't need the rest of the matching goals.  On jython and ironpython, the only way that the generator clean-up code can be guaranteed to run when it needs to is by use of the with statement.

If Python had a variant of the for loop that would guarantee to call the generator's close method when the loop terminates, the with statements wouldn't be needed.

So, yes, you need to use both a with and for statement...

-Bruce


Baltasar García Perez-Schofield

unread,
Nov 25, 2013, 4:49:15 AM11/25/13
to py...@googlegroups.com
Many thanks for your answer, Bruce.

Taking into account that is necessary a from __future__ import with_statement, maybe it's time to port Pyke to Python3. I think it would be easy to get to a single source, compatible with Python2 and Python3.

Reply all
Reply to author
Forward
0 new messages