Reverse Inference
The enabling of reverse inference rules occurs when your program asks about Pyke. For example, require Pyke to prove a specific target. Pyke certification activities only use the activated rule repository.
Overview of "reverse inference"
For reverse reasoning, Pyke needs to find out the rule that the then clause part matches the target (that is, the question the program asks Pyke. After finding a matched rule, Pyke tries to prove that all the sub-targets of the Rule If clause are true through recursion. Some of the sub-objectives are the fact of seeking for matching, while others are other reverse reasoning rules. If all these sub-targets prove true, this rule applies successfully and the initial ultimate goal proves true. Otherwise, this rule fails to apply. Pyke tries to find other rules, that is, the rules whose then clause matches the target. This process will be repeated.
Pyke will eventually form a "evidence chain", starting from the IF clause of the first rule and ending with the then clause of the next rule.
Review
- The proof activity of Pyke begins to look for a rule, and its then clause matches the target.
- Pyke then proves that the if clause of the rule is true.
- That is, the if clause of the rule and the then clause of the other rule can be connected.
Pyke's proof activity method starts from the then clause of the rule and ends with the if clause. It is opposite to the reasoning method we usually use. Therefore, it is called "reverse reasoning ".
More specifically, when Pyke requires writing your reverse inference rules, it first writes the then clause because it is processed at runtime.
Use
UseAnd
WhenReplace
ThenAnd if
However, the then-if rule is awkward and Pyke will use it.UseReplaceThen, UseWhenReplaceIf.
Note
Pyke only allows one fact statement in the Use Clause, which is different from the assert clause of Forward Reasoning (allowing multiple facts.
Example
Consider the following example:
1 direct_father_son 2 use father_son($father, $son, ()) 3 when 4 family2.son_of($son, $father) 5 grand_father_son 6 use father_son($grand_father, $grand_son, (grand)) 7 when 8 father_son($father, $grand_son, ()) 9 father_son($grand_father, $father, ())10 great_grand_father_son11 use father_son($gg_father, $gg_son, (great, $prefix1, *$rest_prefixes))12 when13 father_son($father, $gg_son, ())14 father_son($gg_father, $father, ($prefix1, *$rest_prefixes))15 brothers16 use brothers($brother1, $brother2)17 when18 father_son($father, $brother1, ())19 father_son($father, $brother2, ())20 check $brother1 != $brother221 uncle_nephew22 use uncle_nephew($uncle, $nephew, $prefix)23 when24 brothers($uncle, $father)25 father_son($father, $nephew, $prefix1)26 $prefix = ('great',) * len($prefix1)27 cousins28 use cousins($cousin1, $cousin2, $distance, $removed)29 when30 uncle_nephew($uncle, $cousin1, $prefix1)31 father_son($uncle, $cousin2, $prefix2)32 $distance = min(len($prefixes1), len($prefixes2)) + 133 $removed = abs(len($prefixes1) - len($prefixes2))
Note
The conclusions drawn from these rules are exactly the same as those obtained using positive reasoning. It only adds some kinship rules, namely brothers, uncle_nephew, and cousins (brothers, uncles, and cousins)
You can draw a function call flow chart generated by applicable rules similar to forward inference:
Rule call example
These rules are called only when Pyke verifies the requirements of a target.
The simplest way to request evidence is to use functions.Some_engine.prove_inclugoalOrSome_engine.prove_goal. FunctionProve_inclugoalAfter the first evidence is returned, the operation is stopped (or unexpected: Pyke. knowledge_engine.cannotprove ). FunctionProve_goalThe "manager" of all the evidence generated during the verification process is returned ". There may be too much evidence to generate.
The two functions return the pattern variables in the order determined by the "Scheme flowchart.
Backtracking of reverse inference rules
In the following example, the verification process starts with a set of facts.Family2Matching:
1 son_of(tim, thomas)2 son_of(fred, thomas)3 son_of(bruce, thomas)4 son_of(david, bruce)
We want to knowFredAsk who the nephew is.Uncle_nephew (Fred, $ nephew, $ prefix).
The numbers in parentheses in the program code are the steps to verify the success. The row number in the routine, indicating the location when the verification fails.
(1) 22 use uncle_nephew(fred, $nephew, $prefix) 24 brothers(fred, $father)(2) 16 use brothers(fred, $brother2) 18 father_son($father, fred, ())(3) 2 use father_son($father, fred, ()) 4 family2.son_of(fred, $father) matches fact 2: son_of(fred, thomas) 19 father_son(thomas, $brother2, ())(4) 2 use father_son(thomas, $son, ()) 4 family2.son_of($son, thomas) matches fact 1: son_of(tim, thomas) 20 check fred != tim 25 father_son(tim, $nephew, $prefix1)(5.1) 2 use father_son(tim, $son, ()) 4 family2.son_of($son, tim) => FAILS(5.2) 6 use father_son(tim, $grand_son, (grand)) 8 father_son(tim, $grand_son, ()) 2 use father_son(tim, $son, ()) 4 family2.son_of($son, tim) => FAILS(5.3) 11 use father_son(tim, $gg_son, (great, $prefix1, *$rest_prefixes)) 13 father_son(tim, $gg_son, ()) 2 use father_son(tim, $son, ()) 4 family2.son_of($son, tim) => FAILS
The call sequence of each rule. The number is in parentheses. In step 5, three different rules (5th, 5.1, and 5.2) were tried, but both failed.
We can regard these rules as functions. The process of applying the rules for verification can be drawn into a flowchart, indicating that the rules are successful in a black circle, and that the Rules fail in a red circle:
We need to look back!
In this case, the verification process of Pyke cannot be continued and must be traced back. The backtracing method is to backward from the list of running rules and combine them all into a list. For example, after Step 1 fails, Pyke returns to step 2, trying to find another way to reach the next step.
If other methods are found, Pyke starts to verify the next step; otherwise, Pyke goes back to the previous step.
Pyke returned to Step 1 and constrained the pattern variable $ son to Fred. In applicable rulesBrothersThe matching fails:
20 check $brother1 != $brother2
Pyke had to return Step 1 again. The next method is to constrain the pattern variable $ son into Bruce. The rule brothers applies successfully this time. When father_son is called, Fred's nephew David is returned.
But there is no other way to proceed.
Summary of "backtracking"
We can see:
- Backtracking Algorithm: "success and defeat ". Backtracking not only appears in the when clause of a single rule, but also exists in the entire process of verifying the target.
- This execution model is not available within traditional programming ages like python. This method of running programs is not applicable to traditional programming languages like python.
- In the operation process, the ability to seek other methods at any time is the reason why the reverse reasoning system is powerful.
Running example
>>> from pyke import knowledge_engine>>> engine = knowledge_engine.engine(__file__)>>> engine.activate('bc_related')
Because it is not a forward inference rule, even if the rule repository is activated, there is no rule to run.
We want to ask, "Who is Fred's nephew ?". Into Pyke fact statement:
Bc_related.uncle_nephew (Fred, $ V1, $ V2).
Note
We use the rule repository name bc_related, not the repository name Family2. This is because the expected answer is bc_related.
The rule repository is 'bc _ related', the fact statement is 'Uncle _ nephew ', and the parameter is 'fred' and two mode variables:
>>> from __future__ import with_statement>>> with engine.prove_goal('bc_related.uncle_nephew(fred, $nephew, $distance)') as gen:... for vars, no_plan in gen:... print vars['nephew'], vars['distance']david ()