====== CLIPS & Prolog ====== ===== Download ===== Please download the following files containing simple knowledge bases about a family: * CLIPS file: {{ :pl:dydaktyka:dss:rules:family_en.clp.zip |}} * Prolog file: {{ :pl:dydaktyka:dss:rules:family_en.pl |}} * Manual for CLIPS: {{:pl:dydaktyka:rules:lab:labs:bpg.pdf|Basic Programming Guide}}, [[http://clipsrules.sourceforge.net/OnlineDocs.html|version online]] ===== Knowledge Bases ===== Both files have corresponding content: * The same facts. * The same relationships defined on the facts. In addition, files contain a single rule defining the **child** relation. ===== 1. Loading The Facts ===== After downloading the files, they have to be loaded into corresponding Knowledge Bases (KB): * CLIPS: (load family_en.clp) If everything was loaded correctly, you should a feedback similar to: Defining deffacts: initial-facts Defining defrule: child +j TRUE The ** TRUE ** is the most important part of this feedback. If ** FALSE ** appears, it means that loading failed. * Prolog: [family]. The succesful loading should display something similar to: % family compiled 0.01 sec, 9,232 bytes true. Notice the ** true ** again. ===== 2. Display the KB ===== To view the contents of the KB, enter: * CLIPS: (reset) (facts) * How many facts are in the KB? * Prolog: listing. ===== 3. Inference ===== CLIPS uses the forward-chaining. The inference is implemented as a loop, that checks what rules can be executed based on the current state of the KB. Then the found rules are executed and the cycle repeats. The loop ends when it fails to find a rule to execute. The input of the forward-chaining algorithm is ** the set of facts ** in the knowledge base. * To check what rules are ready to be run, type (agenda) * What rules are ready to run? * What facts trigger these rules? * How to explain the result? * To run the inference process, type (run) * What is the output? * How many facts are in the database? * What facts were added? * Have you expected the result? In Prolog we use backward-chaining and the process is inverted. The input of this algorithm is **target** --- fact that we want to infer. We may say that this a goal-oriented approach. Let's ask: * What women are included in the knowledge base: woman(X). With the '';'' key, we can continue to list all the possible answers of the inference. If you want to interrupt, press "enter". * What pairs of type (mom, child) are included in the KB: mother(Mom, Child). * What children does Dariusz have? father(dariusz, Child). * What are the names of all the fathers: father(Father, _). * What sons does Dariusz have: father(dariusz, Son), man(Son). ===== 4. How to use Rules ===== Both files contain a rule defines who/what is a ** child**. * How to interpret these rules? * Do they use the same notion of a **child**? CLIPS failed to start this rule (previous point). In Prolog, we can query using this rule: child(X, Y). * Run the above query and ... * describe what happened? * Has the situation been analogous to that in CLIPS? * Does the rule in CLIPS failed because of the same reason? ===== 5. Creating Rules ===== In order to run the **child** rule, we have to define: * In CLIPS: a rule that adds a parent to the knowledge base (changing the knowledge base will trigger the next inference cycle): (defrule parent (or (mother ?x ?y) (father ?x ?y)) => (assert (parent ?x ?y)) ) * In Prolog: a rule defining a relationship (child, parent): parent(X, Y) :- father(X, Y). parent(X, Y) :- mother(X, Y). It is worth noting that in the case of Prolog, we define two rules. One can assume that there is a conjuction (**OR**) between these two rules. * Repeat steps: * CLIPS: 1. and 3. (start with executing ''(clear)'' to clear the fact base) * Prolog: 1 and 4. * How many facts are there in the CLIPS database? * What are the active rules in CLIPS? * Why is the **child** rule inactive? ==== 5.1. Adding Knowledge to the KB ==== === 5.1.1. Son and daughter === We can try now to supplement the current KB with new rules, that define other relationships: * Both tools can answer who is the child of which parent. How to extend the rules base of both tools with the help of the **child** concept so that they can tell who is the son and who is the daughter? * Define the appropriate rules. * Start the inference to check if the defined rule is correct. * You can also try to simply display the facts in CLIPS. === 5.1.2. Marriage === * The knowledge base can also be supplemented by a rule defining **marriage**. With existing facts and rules, you can define that two people are married if: * are different sex, * have a common child. * This rule will cause the inference to omit the childless couples. In order to define the proper notion of **marriage**, KB would have to be supplemented with additional facts (what facts?) === 5.1.3. Other === Knowing that the concepts **brother** is defined as follow: * CLIPS: (defrule brother (siblings ?x ?y) (man ?x) => (assert (brother ?x ?y)) ) * Prolog: brother(X, Y) :- siblings(X, Y), man(X). Define the following rules: * siblings(X,Y) --- two different people with a common parent; * tip: ** (test (neq ?x ?y)) ** checks inequality of variables. * question: why do you have to use ** test ** keyword? * sister(X,Y) * grandfather(X,Y) * grandmother(X,Y) * grandparent(X,Y) --- tip: use ** OR ** * cousins(X,Y) --- two different people with a common grandparent. You can check this rule in Prolog with a query: cousins(X,Y), parent(R,X), parent(R, Y), it should return **false** * remember: siblings are not cousins! * aunt(X,Y) and uncle(X,Y) in terms of sister, brother and parent. * half-orphan(X) --- a person with only one parent. TIP: celina is the only half-orphan in the KB * widow(X) (and widower(X)) --- assume that all the single-parents are single because of the spouse's death. TIP: tobiasz is the only widower in the KB, there are no widows. In CLIPS you may check results of the following rule: (defrule widower ... => (assert (widower ?x)) (printout t ?x " is widower" crlf) ). Do you get the expected result? ===== 6. Tracking the execution of the program ===== Since CLIPS doesn't correctly find the widowers, it is necessary to track the execution of the program: === 6.1. Tracking the facts ===== Allows you to track operations on facts: add, delete, change of the value. - In the first step, we will start observing the **widower** rule to see what triggers it: (watch rules widower) - We reset the fact base: (reset) - Restart the inference: (run) - Now we see the triggers and indexes of facts from which we started. - Now check which fact triggered the inference: (facts) ===== 6.2. Rule tracking ===== Allows tracking of rules: firing, activation. - Because we did learn nothing interesting tracing the fact, we will follow the **widow** rule and all the rules it depends on: **parent**, **marriage**: (unwatch all) (watch rules marriage widow parent) - Now we reset the fact base: (reset) - Restart the inference: (run) - What is the reason behind the malfunction of the **widower** rule? - How can we fix it? === 6.3. Tracking in Prolog ===== Prolog allows you to follow the program. To do so, you set the so-called. trace point. Trace points: * ''trace/0'' - sets the trace point on all predicates, eg: ?- trace, woman(K), parent(K, _). * **trace/1** - sets the trace point at the indicated predicate, * **trace/2** - modifies trace point of the specific events (call, redo, exit, fail), eg: * remove the trace point from the specified predicate //something/1// trace(something/1, -all) * set a trace point tracking only calls to the specified predicates //something// of arbitrary arity. trace(something, call +) * Predicate ''debugging/0'' lists all the set trace points. * The ''debug/0'' predicate activates debug mode. * Predicate ''nodebug/0'' disactivates debug mode. Check following code: ?- trace(parent). [debug] ?- trace(mother). [debug] ?- trace(father) [debug] ?- parent(dariusz, tomasz). [debug] ?- nodebug.