Lessons/Succeed, fail and backtrack - part 3

Here we will consider more ways to use the knowledge in our little "knowledge base" (i.e. from ).

This clause will call father with two free variables, i.e. both arguements are output arguments. Therefore it will succeed for the first clause and have created a backtrack point to the second clause. And so forth.

Notice that the actual backtracking takes place from run to father.

foreach  do  end foreach is a construction that execute  and if it succeeds then it executes  after <Q></vp> has executed it will backtrack into <P></vp> if that is possible and if <P></vp> succeeds again then <Q></vp> is also run again, this continues until <P></vp> finally fails, at which point the excecution will continue after end foreach</vp>.

fail</vp> is a built-in predicate that always fails, it can be used to achieve a siilar behavior as the one foreach</vp> achieves:

After we have found a Person</vp> and its Father</vp> and written it we call fail</vp>. And since fail</vp> fails we will backtrack:


 * Into father</vp> if there is a backtrack point there.
 * And otherwise to the second runGoal</vp> clause.

So besides the syntactic difference in using foreach</vp> and fail</vp> there is also the difference that after having found all fathers, the <vp>foreach</vp> construction will succeed and execution will therefore continue after <vp>end foreach</vp> in the same clause; <vp>fail</vp> on the other hand fails, so in after having found all fathers fail will fail, and we will therefore the entire clause containing <vp>fail</vp> will itself fail, and execution will therefore continue in the next clause.

Summary:


 * We can use the "knowledge base" with different combinations of bound and free arguments.
 * <vp>foreach</vp> can be used to exhaust backtracking of a certain "generator" and perform some action of each "generated thing".
 * when the backtracking in a <vp>foreach</vp> construction is finally exhausted, the entire <vp>foreach</vp> construction succeeds.
 * <vp>fail</vp> is a built-in predicate that fails when called.

<vp>if <C> then <P> else <Q> end if</vp> is a construction that will first execute <vp><C></vp> if that succeeds it will execute <vp><P></vp> if it fails it will execute <vp><Q></vp> instead. Backtrack points in <vp><C></vp> (if any) will be discarded, so there will be no backtracking in to <vp><C></vp>. So <vp><C></vp> is used to choose between <vp><P></vp> and <vp><Q></vp>. If (lets us say) <vp><P></vp> is chosen then the entire <vp>if</vp> construction functions as if <vp><P></vp> was called. So if <vp><P></vp> fails then the entire <vp>if</vp> construction fails, and it <vp><P></vp> succeds then the entire <vp>if</vp> construction succeeds. Finally, if <vp><P></vp> created backtrack points then backtracking will return into <vp><P></vp>.

If you don't want anything to happen in the then-part you can use the built-in <vp>succeed</vp> predicate, which simply succeeds, or you can write nothing at all:

if <C> then succeed else <Q> end if if <C> then else <Q> end if

If you don't want anything to take place in the <vp>else</vp> part you can also leave out the word <vp>else</vp>, so these three things have the same meaning:

if <C> then <P> else succeed end if if <C> then <P> else end if if <C> then <P> end if

Summary


 * <vp>succeed</vp> is a build-in predicate that succeeds
 * <vp>if <C> then <P> else <Q> end if</vp> runs <vp>C</vp> to choose between <vp><P></vp> and <vp><Q></vp>.