/*

=begin latex

\input{header.tex}
\hello{Abduction 101}{Tim Menzies

~\\
{\tt tim@menzies.us }

{\large\today}

=end latex

=head1 System

=head2 Background knowledge*/

 happy/t        :- rich/t,healthy/t.
 happy/t        :- tranquility /hi.
 tranquility/hi :- conscience/clear.
 tranquility/hi :- satiated/t.
 satiated/t     :- diet/fatty.
 healthy/t      :- diet/light. /*

=head2 Current facts. */

 rich/t.

 %tim/f.
 %satiated/f.
 /*

=head2 High level goal */

 todo/t        :- happy/t. /*

=head2 Example output

Here's one run. 

 ?- goes.
 % assumptions
 0* (diet/light)
 1* (rich/t)
 2* (happy/t)
 2* (healthy/t)
 2* (todo/t)

 % assumptions
 0* (conscience/clear)
 2* (happy/t)
 2* (todo/t)
 2* (tranquility/hi)

 % assumptions
 0* (diet/fatty)
 2* (happy/t)
 2* (satiated/t)
 2* (todo/t)
 2* (tranquility/hi)

Here's anohter run. Hmmm... different order. Why?

 ?- goes.
 % assumptions
 0* (diet/light)
 1* (rich/t)
 2* (happy/t)
 2* (healthy/t)
 2* (todo/t)

 % assumptions
 0* (diet/fatty)
 2* (happy/t)
 2* (satiated/t)
 2* (todo/t)
 2* (tranquility/hi)

 % assumptions
 0* (conscience/clear)
 2* (happy/t)
 2* (todo/t)
 2* (tranquility/hi)

=head1 Implementation

=head2 Working memory management */

 reset  :-
 	dynamic(assuption/3),
 	retractall(assumption(_,_,_)).

 report :- write('% assumptions\n'), report1, fail.
 report :- nl.

 report1 :-
 	setof(Z*(X/Y),assumption(X,Y,Z),All),
 	member(One,All),
 	write(One),
 	nl. /*


=head2 Standard stuff */

 goes :- go, fail.
 goes.

 goes(X) :- go(X),fail.
 goes(_).

 go    :- reset, run,    report.
 go(X) :- reset, run(X), report.

 run    :- maybe(todo/t).
 run(X) :- maybe(X). /*

=head2 Assumption management */

 assume(X/Y,_)   :- assumption(X,Z,_),!,Y=Z.
 assume(X/Y,How) :- bassert(assumption(X,Y,How)).

 bassert(X) :- assert(X).
 bassert(X) :- retract(X),fail. /*

=head2 Assumption generation */

 maybe(X) :- once(maybe0(X,Y)), maybe1(Y).

 maybe0((X,Y),      (X,Y)).
 maybe0(X/Y,        fact(X/Y))      :- clause(X /_,true).
 maybe0(X/Y,        rule(X/Y))      :- clause(X/_,_).
 maybe0(X/Y,        abducible(X/Y)).

 maybe1((X,Y))        :- maybe(X),maybe(Y).
 maybe1(abducible(X)) :- assume(X,0).
 maybe1(fact(X))      :- assume(X,1), one(X).
 maybe1(rule(X))      :- assume(X,2), one(clause(X,Y)), maybe(Y). /*

=head2 Random ordering

Return solutions to goal C<X>, in some random order. */

 one(X) :-
 	setof(N/X,(X,
 	           N is random(10000)),
 	      All),
 	member(_/X,All).
