Trivial Prolog in Java

01: package ca.draisey.free.tprolog;
02:
03:
04:
05:
06:
07: // -- the classic "if A then Z" contruction written right-to-left perl-style "Z if A" --
08: // chained binary HornClause terms generate the general horn clause "Z if A and B and C and ..."
09: // That is: 
10: //      (psuedosyntax)          Z if ( A and B and C )  is equiv to     ( ( Z if A ) if B ) if C
11: //      (Edinburgh syntax)      Z :- A, B, C.           is equiv to     ( ( Z :- A ) :- B ) :- C.
12: //      (Marseilles syntax)     Z -> A B C;             is equiv to     ( ( Z -> A ) -> B ) -> C;       .
13: final class HornClause extends Clause {
14:         HornClause( final Clause c, final Term a )
15:         {
16:                 consequent = c; antecedent = a;
17:         }
18:
19:         // for pretty output
20:         final void listing( final int f, final Variables these, final java.io.PrintWriter p, final Monitor m )
21:         {
22:                 m.monitor();
23:                 //System.out.print("h");
24:                 if( ( f & -2 ) == 0 ) {
25:                         p.print( "HornClause( " );
26:                         consequent.listing( f, these, p, m );
27:                         p.print( ", " );
28:                         antecedent.listing( f, these, p, m );
29:                         p.print( " )" );
30:                 }
31:                 else if( ( f & 8 ) != 0 ) {
32:                         consequent.listing( f, these, p, m );
33:                         p.print( "  " );
34:                         antecedent.listing( f, these, p, m );
35:                 }
36:                 else {
37:                         consequent.listing( f, these, p, m );
38:                         p.print( ". " );
39:                         antecedent.listing( f, these, p, m );
40:                         p.print( "," );
41:                 }
42:         }
43:
44:         // a helper function for indexing the database -- pass this to the consequent
45:         final String getkey() {
46:                 return consequent.getkey();
47:         }
48:
49:         // -- we reason backward from effect to cause --
50:         // If the consequent of the rule would imply our goal we conditionally accept it
51:         // and reason backwards from its antecedent as our new goal (a subgoal).  Provided we
52:         // structure our database so that ground terms occur before conditional terms, we have
53:         // a reasonable expectation of avoiding an infinite regress.  (Turing proved that we
54:         // cannot, in general, predict whether any given algorithm terminates or not)
55:         final void queryClause( final Term goal, final Variables these, final Variables goals, final Successor success )
56:         {
57:                 //System.out.print("H");
58:                 consequent.queryClause( goal, these, goals, success.succession().new SuccessionSuccessor() {
59:                         void succeed()
60:                         {
61:                                 succession().queryDatabase( antecedent, these, success );
62:                         }
63:                 } );
64:         }
65:
66:         // the HornClause node structure
67:         private final Clause consequent;
68:         private final Term antecedent;
69: }
70:
71: // fin