Help on forward chaining

Help
2009-05-13
2013-05-17
  • bruno GALLART

    bruno GALLART - 2009-05-13

    Hi,

    First, Pyke is very interesting and I test it. I find to have created one base for the questions it is very well and usefull.
    I am not very good in english, it is for what I send this message to find help.
    I did this krb's file like this: 

    grandson_of
        foreach
            family.son_of($child,$father)
        family.son_of($father,$grandfather)
        assert
            family.grandson_of($child,$grandfather)

    grandson
        use grandson_of($child,$grandfather)
        when
            family.son_of($child,$father)
        family.son_of($father,$grandfather)

    and my program is :
    my_engine.assert_('family','son_of',('remy','francis'))
    my_engine.assert_('family','son_of',('bruno','francis'))
    my_engine.assert_('family','son_of',('lucie','bruno'))
    my_engine.assert_('family','son_of',('victor','bruno'))

    my_engine.activate('example')
    my_engine.get_kb('family').dump_specific_facts()

    Question 1:
    When I active the base I have all the facts (initials and deduced) and I shoulld like have only the facts deduced like
    grandson_of('lucie', 'francis')
    grandson_of('victor', 'francis')
    Is it possible ?

    Question 2:
    When I want to look after the victor's grandfather or lucie I find the good  reponse : ('francis',) with this program
    with my_engine.prove_n('example','grandson_of',('victor',),1) as gen:
        for vars, no_plan in gen:
            print "reponse :",vars

    But if I want know who are the francis's grandsons, here I am lost because if I do this :
    with my_engine.prove_n('example','grandson_of',('francis',),1) as gen:
        for vars, no_plan in gen:
            print "reponse :",vars
    it is not good. I think I must change the structure of my backward rule but I don't know how ?
    Somebody can give me some help ?

    Thanks a lot,
    Bruno

     
    • bruno GALLART

      bruno GALLART - 2009-05-14

      Hi,

      For the second question, to find grandson_of(X,'francis')
      I found one answer with the creation of new rule like this :
      grandfather
          use grandfather_of($grandfather,$child)
          when
              family.son_of($child,$father)
          family.son_of($father,$grandfather)
         
      And now when I ask Pyke like this:
      with my_engine.prove_n('example','grandfather_of',('francis',),1) as gen:
          for vars, no_plan in gen:
              truc=vars
              print " Francis is ",vars[0], "'s grandfather"

      I have a good answer :
      Francis is  lucie 's grandfather
      Francis is  victor 's grandfather

      New question: Have I the obligation to create a specific rule to do this or there is an another way, directly from this rule ?
      use grandson_of($child,$grandfather)
      when
      family.son_of($child,$father)
      family.son_of($father,$grandfather)

      with my_engine.prove_n('example','grandson_of',($X,'francis'),1) as gen  ??

      Thanks,
      Bruno

       
    • Bruce Frederiksen

      Hi Bruno,

      Question 1:

      I would use different fact bases to separate your facts.  For example, place your initial facts in the 'family' fact base, and your deduced facts in 'extended_family'.  Just use 'extended_family' rather than 'family' in the "assert" clauses of your forward chaining rules.  But be careful to also change the names for deduced facts in the "foreach" and "when" clauses that use them too!

      Question 2:

      Both the engine.prove_1 and engine.prove_n are simplified front-end functions for the more general engine.prove function, explained here:

      http://pyke.sourceforge.net/using_pyke.html#other-functions

      This requires that you convert all goal arguments to patterns, which are explained here:

      http://pyke.sourceforge.net/using_pyke.html#creating-your-own-patterns

      The code to run your example would be (I'll use dots to keep the indenting ....):

      # You need these to create the patterns and context object.
      from pyke import pattern, contexts

      # You can place anything that doesn't contain pattern variables in a pattern_literal to turn it into a pattern.
      # This includes tuples (as a note to other readers -- your example doesn't use or need tuples).
      # But if the tuple has pattern variables in it, you need to use a pattern.pattern_tuple instead!
      child = pattern.pattern_literal('victor')

      # Create a pattern variable for the grandfather.  I doesn't matter what we name the variable.
      # I could have called it 'grandfather', but I thought 'gf' might be less confusing since I'm also
      # assigning it to a 'grandfather' python variable.
      # The contexts.variable is also a type of pattern (that binds the variable).
      grandfather = contexts.variable('gf')

      # We need a context to hold our variable bindings:
      pattern_context = contexts.simple_context()

      # And now we can call engine.prove!
      with my_engine.prove('example', 'grandson_of', pattern_context, (child, grandfather)) as gen:
      ....# NOTE: there is only _one_ generated value here.  The variable bindings are in pattern_context!
      ....for no_plan in gen:
      ........print "response :", pattern_context.lookup_data('gf')

      With engine.prove, you can ask any question.  It's just more work!  The engine.prove_1 and engine.prove_n functions just call engine.prove for you to make it easier when your pattern variables are the last N goal arguments.

      -bruce

       
    • bruno GALLART

      bruno GALLART - 2009-05-18

      Hi, Bruce,

      First, congratulations for your program PYKE. It is very interesting.

      Question 1:
      I did the manipulation. It is exactly what I want. Thanks.

      Question 2:
      I have tested the pattern. I tested it with
      grandfa= pattern.pattern_literal('francis')
      contexte = contexts.variable('variable')
      pattern_context = contexts.simple_context()
      with my_engine.prove('example', 'grandson_of', pattern_context, (contexte, grandfa)) as gen: 
          for no_plan in gen:
                  print "response :", pattern_context.lookup_data('variable')

      to look after all the francis's grand_son and ... I have understood !!! Great ! This way is like Prolog.
      For some people (that I am !), one exemple  is better than 100 lines of explanation. I am going to read very precisely your documentation because PYKE is very rich and I see that I don't understand all its subtilities.

      See you soon or read you soon !
      Regards,
      Bruno

       

Log in to post a comment.