Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

facts from instances?

Help
2011-09-04
2012-11-23
  • Maxim Bakaev
    Maxim Bakaev
    2011-09-04

    Dear colleagues, would you please kindly share your advice on the following.

    I have quite an extensive structure of classes (ontology built in Protege-Frames editor and exported with CLIPSTab) and some instances. I'm making a system with CLIPS, which loads respective files.
    As it seems to me that rules (defrule…) don't work well with classes and instances, I decided to use facts (deftemplate…) instead.
    So now, basically, I have to manually write deftemplates that replicate defclasses, then create respective facts. My questions are:
    1) Is there a built-in way to create deftemplates from defclasses and facts from instances?
    2) Any other hints how to organize interaction between classes/instances and templates/facts? Is there a better way than the one I chose?

     
  • Gary Riley
    Gary Riley
    2011-09-04

    You can access all of the classes, slots, instances, etc. from within deffunctions, so just load the classes and instances and write a function that will convert from one form to the other. For example:

    CLIPS> (defclass A (is-a USER) (slot x) (slot y) (multislot z))
    CLIPS> 
    (deffunction class-to-template (?class ?output)
      (printout ?output "(deftemplate " ?class)
      (progn$ (?slot (class-slots ?class))
         (if (member$ SGL (slot-facets ?class ?slot))
            then (printout ?output crlf "   (slot " ?slot ")")
            else (printout ?output crlf "   (multislot " ?slot ")")))
      (printout ?output ")" crlf))
    CLIPS> (class-to-template A t)
    (deftemplate A
       (slot x)
       (slot y)
       (multislot z))
    CLIPS>
    

    There are a number of things you can do with instances that you can't do with facts, so switching from instances to facts based on functionality doesn't make a lot of sense.

     
  • Maxim Bakaev
    Maxim Bakaev
    2011-09-05

    garyriley, thank you very much for the example function (and for CLIPS, actually!).

    In terms of functionality: I couldn't quite figure out how to use instances in LHS of rules, so that was the reason I turned to facts (without rules the power of logic programming would remain largely unused).
    So could you please give some hints on how to use instances in rules - checking for some conditions on all or some instances of a class and using matched values in RHS?

     
  • Gary Riley
    Gary Riley
    2011-09-06

    Fact and instance patterns are very similar. Section 5.4.1.7 of the Basic Programming Guide describes the details specific to object patterns. If you look at the files dilemma1.clp and dilemma3.clp from http://clipsrules.svn.sourceforge.net/viewvc/clipsrules/examples/, you can compare the same program coded using facts and instances to see the differences. Here are two example rules:

    (defrule move-alone-facts
       ?node <- (status (search-depth ?num) 
                        (farmer-location ?fs))
       (opposite-of ?fs ?ns)
       =>
       (duplicate ?node (search-depth =(+ 1 ?num))
                        (parent ?node)
                        (farmer-location ?ns)
                       (last-move alone)))
    
    (defrule move-alone-instances 
       ?node <- (object (is-a status)
                        (search-depth ?num)  
                        (farmer-location ?fs))
       (object (is-a opposite-of) (value ?fs) (opposite-value ?ns))
       =>
       (duplicate-instance ?node (search-depth (+ 1 ?num))
                                 (parent ?node)
                                 (farmer-location ?ns)
                                 (last-move alone)))
    
     
  • pyc
    pyc
    2012-03-10

    This is not a reply but a somewhat related question, to Gary.
    Is there a capability in COOL to write a recursive message handler?
    I tried to call an internal-instance handler from within an instance handler.
    The internal-instance and the instance are of the same class.
    The instance is made according to has-a pattern, where the instance's multislot is made from internal-instance.
    Such inclusion could be to any depth, so it would be convenient to call handlers of internal-instances from the handler of the instance, for example to print all instances.
    I got "No applicable primary message-handlers found for print." when tried to call (send  print) inside print handler for the class.
    Is there something I am missing regarding recursiveness of the handlers (not possible?) ?
    Is there an alternative way to achieve similar functionality?
    Thanks,
    Pyc.

     
  • pyc
    pyc
    2012-03-11

    Gary, I made mistakes. Sorry. Recursive calling of message handlers works in COOL.

     
  • Gary Riley
    Gary Riley
    2012-03-11

    It sounds like what you did was to send to the specific instance  rather than the instance variable ?self:inner-instance.

             CLIPS (6.30 8/15/11)
    CLIPS> 
    (defclass EXAMPLE
       (is-a USER)
       (slot inner-instance (type INSTANCE)))
    CLIPS>    
    (definstances example
       ([a] of EXAMPLE (inner-instance [b]))
       ([b] of EXAMPLE (inner-instance [c]))
       ([c] of EXAMPLE))
    CLIPS>    
    (defmessage-handler EXAMPLE my-print ()
       (send ?self print)
       (if (instance-existp ?self:inner-instance)
          then
          (send [inner-instance] my-print)))
    CLIPS> (send [a] my-print)
    [a] of EXAMPLE
    (inner-instance [b])
    [MSGPASS2] No such instance inner-instance in function send.
    [PRCCODE4] Execution halted during the actions of message-handler my-print primary in class EXAMPLE
    FALSE
    CLIPS>    
    (defmessage-handler EXAMPLE my-print ()
       (send ?self print)
       (if (instance-existp ?self:inner-instance)
          then
          (send [inner-instance] my-print)))
    CLIPS>    
    (defmessage-handler EXAMPLE my-print ()
       (send ?self print)
       (if (instance-existp ?self:inner-instance)
          then
          (send ?self:inner-instance my-print)))
    CLIPS> (send [a] my-print)
    [a] of EXAMPLE
    (inner-instance [b])
    [b] of EXAMPLE
    (inner-instance [c])
    [c] of EXAMPLE
    (inner-instance [nil])
    FALSE
    CLIPS>