Pyke introduction to logical programming (10): Positive reasoning for rules"

Source: Internet
Author: User
Forward Inference

After the rule repository is activated, forward inference rules are automatically enabled.

After the rule repository is activated, the sequence of forward rule execution is subject to the order in the. krb rule repository file.

Basic information of Forward Reasoning

To perform positive reasoning, Pyke checks which rule's if clause matches known facts (if clause can be matched multiple times successfully, see "backtracking "). After the rule is successfully matched, enable it to add the facts in its than clause to the list of known facts.

After the new fact matches the if clause of other positive rules, it can be enabled. This can happen in all kinds of deep Reasoning Processes. Pyke links the then clause of the first rule with the if clause of the next rule.

Note

The process of positive reasoning continues until there are no rules available for use.

Review

  • Pyke uses forward inference to check whether it matches known facts from the IF clause of the first rule.
  • If the rule matches, enter the then clause to enable the rule.
  • The enabled rule may be associated with the if clause of other rules.

Pyke's reasoning process at this time is to go from the IF clause of the rule to the then clause, and then from the IF clause of the next rule to the then clause. This method is called forward reasoning.

Use ForeachAnd AsssertReplace IfAnd Then

The IF clause of a rule has the fact statement mode, which may match several facts. Therefore, the rule may be enabled multiple times.

The fact statement of the then clause also has a pattern. When a rule is enabled, the mode variable in the then clause can be constrained to different values to assert different facts.

To avoid conceptual conflicts, Pyke usesForeachAndAssertTo replace if and then. In the first list of fact statements in the IF clause, the fact statements are integrated one by one. When the rule is enabled, the fact in the second list is stated in the asserted then clause.

Note

UseForeachAndAssertIt indicates that this is a positive inference rule.

Example

In this example, a parent-child relationship is used to reveal the parent ancestor of a person. For the sake of Concise examples, the relationship between mother and daughter is omitted. These facts are stored in the Knowledge item son_of (son, father) of the parent database family ).

1  son_of(michael, bruce)2  son_of(bruce, thomas)3  son_of(thomas, frederik)4  son_of(frederik, hiram)

Follow these steps to pass on the parent-child relationship:

father_son($father, $son, $prefix)

That is:

$ Son: Son name (such as Michael)
$ Father: Father's name (such as Bruce)
$ Prefix: The identifier before "father" and "son" indicates the first generation of parent-child relationship (for example()Direct parent-child relationship father_son,(Grand),(Grandfather great, great grandfather grand)And so on ).

Three positive inference rules are used here, and each rule is used separately:

  • Step 1: direct parent-child relationship

    • Step 1: demonstrate that the value is passed from one fact in the rule to another by applying pattern matching.
  • Step 2: parent-child relationship of grandfathers
    • Step 2: display the Backtracking between multiple preconditions of a forward inference rule. Understanding it helps you understand tracing.
  • Step 3: parent-child relationship between grandfathers
    • Step 2: display the recursion of positive inference rules.

Next, let's see how to run the example.

Step 1: Rule direct_father_son

First, you need to establish a direct parent-child relationship, that is, the value of the pattern variable $ prefix in the fact father_son is null tuples ():

1  direct_father_son2      foreach3          family.son_of($son, $father)4      assert5          family.father_son($father, $son, ())
Usage of mode Variables

It demonstrates the mode variable and how to pass the fact value in the rule to another fact.

The 2nd rows of the rule areForeachClause, where there are only 3rd separate fact statements. This fact statement matches all four son_of facts. Therefore, the rule can be successfully matched four times, but the schema variables $ son and $ father have different constraints. ThereforeAssertWhen the sub-statement is running, there are four different facts that cause assertions. The value of the pattern variables $ son and $ father is passed from row 3rd to row 5th each time the fact is asserted.

When the rule is enabled, 3rd rows match:

1  son_of(michael, bruce)

Run to row 3 and make the following assertions:

5  father_son(bruce, michael, ())

The rule applies. The second match of row 3rd is as follows:

2  son_of(bruce, thomas)

It runs to 5th rows again, and the second asserted:

6  father_son(thomas, bruce, ())

The rule applies to the other two son_of facts twice and asserted the father_son relationship twice. Therefore, this rule produces four new facts:

5  father_son(bruce, michael, ())6  father_son(thomas, bruce, ())7  father_son(frederik, thomas, ())8  father_son(hiram, frederik, ())
Step 2: Rule grand_father_son

Now we need to add the parent-child relationship of our grandfathers. Add new rules:

 6  grand_father_son 7      foreach 8          family.father_son($father, $grand_son, ()) 9          family.father_son($grand_father, $father, ())10      assert11          family.father_son($grand_father, $grand_son, (grand))
Backtracking

Rule grand_father_son, accordingForeachThe combination of fact father_son in the clause (8th million rows), applicable to running. At the same time, based on the combination, assert a father_son fact (11th rows, attention value (Grand )).

This rule can better illustrate backtracking and help you understand it. Next, let's take a look at the Backtracking operation of this rule.

ForeachThe clause contains two facts (8th rows and 9th rows), which are expected to match the fact father_son with the null tuples () of the third parameter.

8  family1.father_son($father, $grand_son, ())9  family1.father_son($grand_father, $father, ())

The fact that the matched family1 is as follows (5th to 8th ):

5  father_son(bruce, david, ())6  father_son(thomas, bruce, ())7  father_son(frederik, thomas, ())8  father_son(hiram, frederik, ())

From the top of the family1 prerequisite list, Pyke searches for matching for the first prerequisite (Row 1. In fact 5, $ father is bound to Bruce.

8  family.father_son($father, $grand_son, ())    => fact 5, SUCCESS9  family.father_son($grand_father, $father, ())

After the match is successful, Pyke goes to the next premise of the 9th rows. Because $ father is bound to Bruce, this time it is successfully matched with fact 6.

8  family.father_son($father, $grand_son, ())    => fact 59  family.father_son($grand_father, $father, ()) => fact 6, SUCCESS

Although the match is successful, Pyke has reached the end of the prerequisite list, so it starts to enable the rule's assertions:

9  father_son(thomas, michael, (grand))

This is a forward inference rule. Pyke tries its best to obtain all the answers to the question. Therefore, it continues to run as if it failed (meaning that it does not like the current answer ).

Note

Later, we will see that Pyke does not run automatically based on reverse inference rules.

Pyke failed to return to the second precondition, and looked for other father_son facts with Bruce as the first parameter.

8  family1.father_son($father, $grand_son, ())    => fact 59  family1.father_son($grand_father, $father, ()) => FAILS

Failure leads to rollback. Pyke withdraws to the first premise and looks for other father_son facts beyond fact 5. The result matches Fact 6, and $ father is restricted to Thomas:

8  family1.father_son($father, $grand_son, ())    => fact 6, SUCCESS9  family1.father_son($grand_father, $father, ())

Success leads to progress. Pyke goes to the second premise and matches with fact 7:

8  family1.father_son($father, $grand_son, ())    => fact 69  family1.father_son($grand_father, $father, ()) => fact 7, SUCCESS

Although the match is successful, Pyke has reached the end of the prerequisite list, so it starts to enable the rule's assertions:

10 father_son(frederik, bruce, (grand))

Next, Pyke retreated to the second premise and continued to look for matching facts after the fact 7. This failed.

8  family1.father_son($father, $grand_son, ())    => fact 69  family1.father_son($grand_father, $father, ()) => FAILS

Failure leads to rollback. Pyke returns to the first premise and looks for other father_son facts after fact 6. Because Fact 7 is the last matching successful, skip it and try Fact 8 at the end. As a result, it matches Fact 8 successfully and sets $ father to Hiram. The result matches Fact 6 and $ father to Thomas:

8  family1.father_son($father, $grand_son, ())    => fact 8, SUCCESS9  family1.father_son($grand_father, $father, ())

Success leads to progress. Pyke goes to the second premise and looks for the father_son for Hiram fact that matches Hiram. Result:

8  family1.father_son($father, $grand_son, ())    => fact 89  family1.father_son($grand_father, $father, ()) => FAILS

Failure leads to backend. Pyke returns to the first premise and finds other matching facts after fact 8. The result is not found. Failed:

8  family1.father_son($father, $grand_son, ())    => FAILS9  family1.father_son($grand_father, $father, ())

If the task fails, the task is rolled back, but the Pyke has been removed to the end of the prerequisite list. The rule fails to be applied and Pyke completes the task.

Important

Note,ForeachThe fact at the end of the clause, which can be successfully matched multiple times, is enabled multiple times.AssertClause.

However,ForeachThe fact that the clause starts with can only fail to match once. If the matching fails, the entire rule fails to apply.

Therefore, if the rule grand_father_son is applied, three more facts are returned:

9  father_son(thomas, david, (grand))10 father_son(frederik, bruce, (grand))11 father_son(hiram, thomas, (grand))    (this is the one we skipped)
Step 3: Rule great_grand_father_son

Finally, we increased the parent-child relationship between our grandfathers. The rule is:

12  great_grand_father_son13      foreach14          family1.father_son($father, $gg_son, ())15          family1.father_son($gg_father, $father, ($prefix1, *$rest_prefixes))16      assert17          family1.father_son($gg_father, $gg_son,                                (great, $prefix1, *$rest_prefixes))
Note

Note: How to specify the pattern variable $ prefixes in Row 3 as ($ prefix1, * $ rest_prefixes. The result is that it does not match null tuples. However, if $ rest_prefixes is constrained to null tuples (), it can also match (Grand ).

This rule is unique and applicable recursively. It asserted that new facts can be used for the same (matching 15th rows of facts) Rules to generate parent-child relationships that trace back to the original generation.

Recursive rules

When this rule is applied, the following facts are usually asserted:

12 father_son(frederik, david, (great, grand))13 father_son(hiram, bruce, (great, grand))

However, because these facts can be used for the same rule of 15th rows, Pyke will run the rule again to check new facts.

Try to match the first new fact: father_son (Frederik, David, (great, grand), but it fails because David is not a father.

Try to match the second new fact: father_son (Hiram, Bruce, (great, grand) and get a new fact:

14 father_son(hiram, david, (great, great, grand))

Use this rule again to try out the new facts, but David failed because he was not the father.

Pyke now completes the application of this rule. It is enabled three times, and the facts of assertions are as follows:

12 father_son(frederik, david, (great, grand))13 father_son(hiram, bruce, (great, grand))14 father_son(hiram, david, (great, great, grand))
Running example

These rules can be run as follows:

>>> from pyke import knowledge_engine>>> engine = knowledge_engine.engine(__file__)>>> engine.activate('fc_related')     # This is where the rules are run!>>> engine.get_kb('family1').dump_specific_facts()father_son('bruce', 'david', ())father_son('thomas', 'bruce', ())father_son('frederik', 'thomas', ())father_son('hiram', 'frederik', ())father_son('thomas', 'david', ('grand',))father_son('frederik', 'bruce', ('grand',))father_son('hiram', 'thomas', ('grand',))father_son('frederik', 'david', ('great', 'grand'))father_son('hiram', 'bruce', ('great', 'grand'))father_son('hiram', 'david', ('great', 'great', 'grand'))

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.