// -*- Mode: LISP; Syntax: Common-lisp; Package: DTP; Base: 10 -*- // ---------------------------------------------------------------------------- // // File Fork.Lisp // System Don's Theorem Prover // // Written by Don Geddis (Geddis@CS.Stanford.Edu) "(in-package dtp)"; // ---------------------------------------------------------------------------- // // Public // ---------------------------------------------------------------------------- define method update-blocking (conjunction, answer) if (answer == #"blocked") // Block the conjunction if (parent-subgoal) parent-subgoal.inferences := remove(parent-subgoal.inferences, conjunction); add-to-end-if-new(conjunction, parent-subgoal.blocked-conjunctions); else proof-query-conjunctions(*proof*) := remove(proof-query-conjunctions(*proof*), conjunction); add-to-end-if-new(conjunction, proof-blocked-conjunctions(*proof*)); end if; elseif (parent-subgoal) if (~ cl-find(conjunction, parent-subgoal.inferences)) push!(conjunction, parent-subgoal.inferences); parent-subgoal.blocked-conjunctions := remove(parent-subgoal.blocked-conjunctions, conjunction); end if; else if (~ cl-find(conjunction, proof-query-conjunctions(*proof*))) push!(conjunction, proof-query-conjunctions(*proof*)); proof-blocked-conjunctions(*proof*) := remove(proof-blocked-conjunctions(*proof*), conjunction); end if; end if; end method update-blocking; // ---------------------------------------------------------------------------- define method fork-conjunction (conj) let forked = #f; forked := copy-conjunction(conj); fork-specialize!(forked, conj); let parent = forked.parent-subgoal; if (parent) add-to-end(forked, parent.blocked-conjunctions); else add-to-end(forked, proof-blocked-conjunctions(*proof*)); end if; end method fork-conjunction; // ---------------------------------------------------------------------------- define method unblock-agenda () // All remaining subgoals blocked, so proof effort is in cycle let blocked-conj = #f; blocked-conj := best-blocked-conjunction(); fork-conjunction(blocked-conj); blocked-conj.backtrack-pointer := blocked-conj.stack-pointer; propagate(not-an-answer: active-conjunct(blocked-conj)); end method unblock-agenda; // ---------------------------------------------------------------------------- define method forkable-conjunctions? () // True IFF the subgoal agenda or query has a forkable conjunction cl-find-if(forkable?, proof-blocked-conjunctions(*proof*)) | cl-find-if(method (sg) cl-find-if(forkable?, sg.blocked-conjunctions); end method, proof-subgoal-agenda(*proof*)); end method forkable-conjunctions?; // ---------------------------------------------------------------------------- // // Private // ---------------------------------------------------------------------------- define method best-blocked-conjunction () // Return a blocked conjunction whose unblocking might make progress let conjs = #f; conjs := reduce1(concatenate, map(method (sg) sg.blocked-conjunctions; end method, reverse(proof-subgoal-agenda(*proof*)))); conjs := concatenate(proof-blocked-conjunctions(*proof*), conjs); cl-find-if(forkable?, conjs); end method best-blocked-conjunction; // ---------------------------------------------------------------------------- define method forkable? (conjunction) // True IFF the conjunction could make progress by forking // I.e.: If the current blocked conjunction got an answer, and then got no // more answers (and so backtracked) after that, would there still be more // in the conjunction space to search? if (instance?(conjunction, )) conjunction.stack-pointer > conjunction.top-conjunct; else conjunction.stack-pointer > 0; end if; end method forkable?; // ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- nil(#f, nil(), "Return a copy of the conjunction (with some slot values copied)", nil(nil(), nil(#f, nil(#())), nil(nil(#f, #()), nil(nil, nil(#f, #()))), nil(nil(#f, #()), nil(nil(#f, #()))), nil(nil(#(#(), #(), #(), #(), #(), #(), #())), nil(nil(#f, #f), nil(#f, #f))), #f)); // ---------------------------------------------------------------------------- define method fork-specialize! (instance, original) for (conjunct in instance.list) conjunct.parent-conjunction := instance; end for; instance.top-conjunct := original.stack-pointer; let ac = #f; let subgoal = #f; ac := active-conjunct(instance); subgoal := ac.subgoal; let new-value-157314 = ac; let g157313 = add!(new-value-157314, subgoal.conjuncts-to-propagate-to); set-slot-value(subgoal, #"conjuncts-to-propagate-to", g157313); end method fork-specialize!; // ---------------------------------------------------------------------------- "eof";