Trivial Prolog in Java

01: package ca.draisey.free.tprolog;
02:
03:
04:
05:
06:
07: // the most common operations without UI specific details
08: abstract class ListableDatabase extends SuccessionDatabase {
09:         void listQuery( final Sentence query, final java.io.PrintWriter pout, final ListableSuccession succession )
10:         {
11:                 final Term goal = query.dequantifyTerm();
12:                 final Variables goals = query.instantiateVariables();
13:                 try {
14:                         queryDatabase( goal, goals, succession.new SuccessionSuccessor() {
15:                                 // note -- this is slightly clever -- we are passing the
16:                                 // non-static parameters 'pout' ,'goal' and 'goals' globally throughout
17:                                 // the entire trace of this call without explicitly passing any parameters
18:                                 void succeed()
19:                                 {
20:                                         pout.println( "***SUCCEED***" );
21:                                         query.listVariables( goals, pout, succession );
22:                                         pout.flush();
23:                                         succession.next(); //throws MonitorException
24:                                 }
25:                         } );
26:                         pout.println( "***FAIL***" );
27:                         pout.flush();
28:                 }
29:                 catch( MonitorException x ) {
30:                         pout.println( "***ABORT***" );
31:                         pout.flush();
32:                 }
33:                 catch( StackOverflowError x ) {
34:                         pout.println( "***OVERFLOW***" );
35:                         pout.flush();
36:                 }
37:                 catch( OutOfMemoryError x ) {
38:                         pout.println( "***OUT*OF*MEMORY***" );
39:                         pout.flush();
40:                 }
41:         }
42:
43:         // -- the required hook for a blocking input - wait for enter key type function --
44:         abstract class ListableSuccession extends DatabaseSuccession {
45:                 // blocking wait-for-next
46:                 abstract void next();
47:                 // tell those waiting that the Prolog core has returned its final solution
48:                 //      -- my implementation never knows this so commented out --
49:                 // abstract void last();
50:         }
51:
52:         // simple listings of the database
53:         //      -- depend on "matching( String )" for accessing the rule Sentences --
54:         void listDatabase( final java.io.PrintWriter pout )
55:         {
56:                 for( String key : dictionaryKeySet() ) {
57:                         listDatabase( pout, key );
58:                 }
59:         }       
60:         void listDatabase( final java.io.PrintWriter pout, final String key )
61:         {
62:                 final java.util.Iterator< Sentence > i = matching( key );
63:                 while( i.hasNext() ) {
64:                         pout.println( ":" + i.next().toString() + ";" );
65:                 }
66:         }
67:
68:     // access the KeySet of the dictionary HashMap which is deferred so we can instantiate
69:     // a correctly typed version of the generic HashMap in the actual implementation class
70:     protected abstract java.util.Set< String > dictionaryKeySet();
71: }
72:
73: // fin