carfield.com.hk NLBean.java 2001-12-08T16:00:00Z 2001-12-08T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">// mwa.products.NLBean.java // // Copyright 1997, Mark Watson. // package nlbean; import java.net.*; import java.io.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.text.*; import java.util.*; import java.beans.*; import java.sql.*; import java.util.Vector; public class NLBean extends Panel implements Serializable { protected NLEngine engine = null; public NLBean() { super(); reset(); } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { System.out.println(&quot;Beginning writeObject&quot;); s.defaultWriteObject(); System.out.println(&quot;Ending writeObject&quot;); } private void resetExamples() { choiceChanged = false; choice.removeAll(); choice.addItem(&quot;Examples &quot;); for (int i=(examples.length - 1); i&gt;= 0; i--) { choice.insert(examples[i], 1); } } private void resetSynonyms() { engine.clearSynonyms(); for (int i=0; i&lt;synonyms.length; i++) { addSynonym(synonyms[i]); } } // Set up USER INTERFACE: private void reset() { engine = new NLEngine(); AWTsetup(); } private void AWTsetup() { Frame help_frame = new Frame(); help = new Help(help_frame); setFont(new Font(&quot;Dialog&quot;, Font.PLAIN, 12)); setLayout(null); Label l1 = new Label(&quot;Natural Language Database Access&quot;); l1.setFont(new Font(&quot;Dialog&quot;, Font.BOLD, 28)); add(l1); l1.setBounds(2, 1, 600, 34); list1 = new java.awt.List(3, false); for (int i=0; i&lt;databaseNames.length; i++) list1.add(databaseNames[i]); list2 = new java.awt.List(3, false); list3 = new java.awt.List(3, false); add(list1); add(list2); add(list3); list1.setBounds(2, 40, 220, 90); list2.setBounds(232, 40, 170, 90); list3.setBounds(412, 40, 170, 90); list1.addMouseListener(new MouseSelect1()); list2.addMouseListener(new MouseSelect2()); list3.addMouseListener(new MouseSelect3()); Button q_button = new Button(&quot;Do query&quot;); q_button.addMouseListener(new MouseQuery()); add(q_button); q_button.setBounds(2, 140, 160, 30); Button help_button = new Button(&quot;Help&quot;); help_button.addMouseListener(new MouseHelp()); add(help_button); help_button.setBounds(172, 140, 40, 30); Label label22 = new Label(&quot;Query:&quot;); label22.setFont(new Font(&quot;Dialog&quot;, Font.BOLD, 14)); add(label22); label22.setBounds(2, 180, 60, 22); label22.setVisible(true); // inputText = new SmartTextField(&quot;list Salary where EmpName equals Mark&quot;, 64); inputText = new TextField(&quot;list Salary where EmpName equals Mark&quot;, 64); add(inputText); inputText.setBounds(80, 180, 500, 22); choice = new Choice(); choiceChanged = false; choice.addItem(&quot;Examples &quot;); for (int i=(examples.length - 1); i&gt;=0; i--) choice.insert(examples[i], 1); choice.addItemListener(new ChoiceListener()); add(choice); choice.setBounds(2, 210, 582, 25); Label label23 = new Label(&quot;Generated SQL:&quot;); label23.setFont(new Font(&quot;Dialog&quot;, Font.BOLD, 12)); add(label23); label23.setBounds(2, 240, 120, 30); sqlText = new TextArea(&quot;&quot;,1,80,TextArea.SCROLLBARS_NONE); sqlText.setEditable(false); add(sqlText); sqlText.setBounds(130, 240, 455, 40); outputText = new TextArea(&quot;NLBean(tm) natural language interface\nCopyright 1997, Mark Watson. All rights reserved.\n&quot;, 8, 74); add(outputText); outputText.setBounds(2, 285, 582, 150); Label l1x = new Label(&quot;NLBean Copyright 1997-1999 by Mark Watson. www.markwatson.com&quot;); l1x.setFont(new Font(&quot;Dialog&quot;, Font.ITALIC, 14)); add(l1x); l1x.setBounds(5, 442, 540, 16); // * * * list1_last_selection=-1; list2_last_selection=-1; list3_last_selection=-1; setBounds(20, 20, 590, 464); setupHelper(); } private void setupHelper() { if (loadSynonyms) { for (int i=0; i&lt;synonyms.length; i++) addSynonym(synonyms[i]); } if (loadDB) { for (int i=0; i&lt;databaseNames.length; i++) { engine.addDB(databaseNames[i], userNames[i], passwords[i], tableLists[i]); } } engine.initDB(); } // Suggest spelling corrections, or other words: // synchronized private String[] suggestedWords(String a_word) { // return engine.suggestedWords(a_word); // } synchronized private void putText(String s, boolean replace_flag) { if (replace_flag==false) { outputText.append(s); } else { outputText.setText(s); } } synchronized private String inText(String new_val, boolean set_flag) { if (set_flag) { inputText.setText(new_val); return &quot;&quot;; } return inputText.getText(); } synchronized private void query() { System.out.println(&quot;Entering query()&quot;); sqlText.setText(&quot;&quot;); String a_query = inText(&quot;&quot;, false); System.out.println(&quot;query(): a_query=&quot; + a_query); String sql_query=null; if (a_query.startsWith(&quot;SELECT&quot;) || a_query.startsWith(&quot;select&quot;)) { sql_query = a_query; } else { engine.parse(a_query); sql_query = engine.getSQL(); } if (sql_query==null) { System.out.println(&quot;No SQL for &quot; + a_query); return; } System.out.println(&quot;SQL query: &quot; + sql_query); sqlText.setText(sql_query); try { engine.createResultSet(sql_query, databaseNames[0], userNames[0], passwords[0]); putText(&quot;Query results:\n&quot;, false); String data = engine.getRows(sql_query, databaseNames[0], userNames[0], passwords[0]); putText(engine.toEnglish(data) + &quot;\n&quot;, false); } catch (Exception e) { e.printStackTrace(); } } private boolean usingAWT = false; private boolean loadSynonyms = true; private boolean loadDB = true; private void addSynonym(String def_string) { int pos = def_string.indexOf(&quot;=&quot;); String description = def_string.substring(0,pos); String column = def_string.substring(pos+1); if (engine!=null) { engine.addSynonym(column, description); } } // Use an inner classes for mouse event handling: class MouseQuery extends MouseAdapter implements Serializable { // The magic: access the public query method in the // containing class: synchronized public void mouseReleased(MouseEvent mevt) { query(); } } // Use an inner classes for mouse event handling: class MouseSelect1 extends MouseAdapter implements Serializable { synchronized public void mouseReleased(MouseEvent mevt) { if (list1_last_selection != list1.getSelectedIndex()) { list1_last_selection = list1.getSelectedIndex(); String s=&quot;&quot;; if (list1_last_selection &gt;= 0 &amp;&amp; list1_last_selection &lt; tableLists.length) { s = tableLists[list1_last_selection]; } System.out.println(&quot;s=&quot; + s); String temp [] = Util.parseStrings(s); list2.removeAll(); list3.removeAll(); for (int i=0; i&lt;temp.length; i++) list2.addItem(temp[i]); } } } // Use an inner classes for mouse event handling: class MouseSelect2 extends MouseAdapter implements Serializable { synchronized public void mouseReleased(MouseEvent mevt) { if (list2_last_selection != list2.getSelectedIndex()) { list2_last_selection = list2.getSelectedIndex(); list3.removeAll(); String sel1 [] = list1.getSelectedItems(); if (sel1!=null) { if (sel1.length&gt;0) { String sel2 [] = list2.getSelectedItems(); if (sel2!=null) { if (sel2.length&gt;0) { String user=&quot;&quot;; String pass=&quot;&quot;; if (list1_last_selection &gt;= 0 &amp;&amp; list1_last_selection &lt; userNames.length) { user = userNames[list1_last_selection]; } try { String cols[] = engine.getColumnNames(sel2[0], sel1[0], user, pass); if (cols!=null) { for (int j=0; j&lt;cols.length; j++) { list3.addItem(cols[j]); } } } catch (Exception e) { } } } } } } } } // Use an inner classes for mouse event handling: class MouseSelect3 extends MouseAdapter implements Serializable { synchronized public void mouseReleased(MouseEvent mevt) { if (list3_last_selection != list3.getSelectedIndex()) { System.out.println(&quot;TESTING 3rd list selection&quot;); list3_last_selection = list3.getSelectedIndex(); String [] sel1x = list1.getSelectedItems(); if (sel1x!=null) { if (sel1x.length&gt;0) { String sel2 [] = list2.getSelectedItems(); String sel3 [] = list3.getSelectedItems(); if (sel2!=null &amp;&amp; sel3!=null) { if (sel3.length&gt;0) { String user=&quot;&quot;; String pass=&quot;&quot;; if (list1_last_selection &gt;= 0 &amp;&amp; list1_last_selection &lt; userNames.length) { user = userNames[list1_last_selection]; pass = passwords[list1_last_selection]; } try { String r = engine.getRows(&quot;SELECT &quot; + sel3[0] + &quot; FROM &quot; + sel2[0], sel1x[0], user, pass); if (r==null) return; putText(r + &quot;\n&quot;, false); } catch (Exception e) { } } } } } } } } private Choice choice; transient private boolean choiceChanged = false; class ChoiceListener implements ItemListener { public void itemStateChanged(ItemEvent ie) { System.out.println(&quot;choice menu: &quot; + ie.paramString()); System.out.println(&quot;choice menu: &quot; + (String)ie.getItem()); String sel = (String)ie.getItem(); if (sel.equals(&quot;Examples&quot;)) return; inText(sel, true); if (choiceChanged==false) { choice.remove(0); choiceChanged=true; } System.out.println(&quot;choice menu: &lt;returning&gt;&quot;); } } private Help help; class MouseHelp extends MouseAdapter implements Serializable { public void mouseReleased(MouseEvent mevt) { help.setVisible(true); } } public static void main(String args[]) { Frame f = new Frame(); NLBean sc = new NLBean(); f.add(sc); f.setTitle(&quot;NLBean version 4.0&quot;); f.pack(); f.show(); f.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } private TextArea outputText; private /* Smart */ TextField inputText; private TextArea sqlText; private java.awt.List list1, list2, list3; private int list1_last_selection, list2_last_selection, list3_last_selection; // properties for specifying a few sample natural language // queries to place at the beginning of the 'Example' // 'choice' control. NOTE: this program automatically // adds additional examples that it generates from examining // the field names of the database tables. private String [] examples = { &quot;list email address where name equals Mark&quot;, &quot;list salary where employee name equals Mark&quot;, &quot;list salary where hire date is after 1993/1/5 and employee name equals Mark&quot;, &quot;list name, phone number, and email address where name equals Mark&quot;, &quot;list employee name, salary, and hire date where hire date is after January 10, 1993&quot;, &quot;list salary where hire date is after January 1, 1993 or employee name equals Carol&quot;, &quot;list product name where cost is less than $20&quot; }; // Set up for synonyms: private String [] synonyms = { &quot;employee name=EmpName&quot;, &quot;hire date=HireDate&quot;, &quot;phone number=PhoneNumber&quot;, &quot;email address=Email&quot;, &quot;product name=productname&quot;, &quot;products=productname&quot;, &quot;product=productname&quot; }; // for four properties each for up to three databases: // Demo database information private String [] databaseNames = {&quot;jdbc:idb:database/nlbean.prp&quot;}; private String [] userNames = {&quot;Admin&quot;}; private String [] passwords = {&quot;sammy&quot;}; private String [] tableLists= {&quot;NameTable;products;Employees&quot;}; // // Inner class to handle text input field: // transient protected int startWordPos=0, stopWordPos=0; class SmartTextField extends TextField implements Serializable { public SmartTextField(String s, int width) { super(s, width); helper(); } public SmartTextField(String s) { super(s); helper(); } public SmartTextField() { super(); helper(); } private void helper() { addMouseListener(new MouseText()); addKeyListener(new MyKeyAdapter()); setEditable(true); setFont(new Font(&quot;default&quot;, Font.PLAIN, 12)); words = new String[20]; for (int i=0; i&lt;20; i++) words[i]=&quot;&quot;; num_words=0; } transient private String words[] = null; transient int num_words; public String getWord(int charPos) { startWordPos=stopWordPos=-1; String s = getText(); // find start of word: int start = charPos-1; try { while (start &gt;= 0 &amp;&amp; s.charAt(start)!=' ') { start--; } start++; } catch (Exception e) {} // find the end of word: int stop=charPos; try { while (stop &lt; s.length() &amp;&amp; s.charAt(stop)!=' ') { stop++; } } catch (Exception e) {} if (start&lt;0) start=0; //if (stop&gt;s.length()-1) stop=s.length()-1; System.out.println(&quot;getWord(): start=&quot; + start + &quot;, stop=&quot; + stop); //if (stop &gt; s.length() - 2) stop = s.length() - 1; int stp = stop; if (stop&gt;my_char_pos) { stop=my_char_pos; System.out.println(&quot; stop reset to &quot; + stop); } if (start &lt; stop) { startWordPos=start; stopWordPos=stp; System.out.println(&quot;getWord() returning: |&quot; + s.substring(start, stop) + &quot;|&quot;); return s.substring(start, stop); } else return &quot;&quot;; } public void setUpperCase(int charPos) { String s = getText(); // find start of word: int start = charPos-1; try { while (start &gt;= 0 &amp;&amp; s.charAt(start)!=' ') { start--; } start++; } catch (Exception e) {} // find the end of word: int stop=charPos; try { while (stop &lt; s.length() &amp;&amp; s.charAt(stop)!=' ') { stop++; } } catch (Exception e) {} if (start&lt;0) start=0; if (stop&gt;s.length()) stop=s.length(); if (stop&gt;my_char_pos) stop=my_char_pos; if (start &lt; stop) { StringBuffer sb = new StringBuffer(s); for (int i=start; i&lt;stop; i++) { char ch = sb.charAt(i); if (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') ch += 'A' - 'a'; sb.setCharAt(i, ch); } setText(new String(sb)); setCaretPosition(stop); } } transient private int charWidth = -1; transient private FontMetrics fm = null; public void paint(Graphics g) { super.paint(g); if (fm==null) { fm = g.getFontMetrics(); } } private int getPixelWidth(String s) { if (fm==null) return 1; return fm.stringWidth(s); } transient private int my_char_pos=0; public int getCharPos(int pixel) { String s = getText(); my_char_pos=-1; if (getPixelWidth(s) &lt; pixel) return -1; // to right of text int len = s.length(); for (int i=1; i&lt;len; i++) { if (getPixelWidth(s.substring(0, i)) &gt; pixel - 12) { my_char_pos=i; return i; } } my_char_pos = len-1; return len-1; } // Handle mouse events over the input text window: class MouseText extends MouseAdapter implements Serializable { public void mousePressed(MouseEvent mevt) { int x = mevt.getX(); int charPos = getCharPos(x); if (charPos&lt;0) return; my_char_pos = 1000; // special for mouse click only! String word = getWord(charPos); System.out.println(&quot;MouseText.mousePressed(): getWord returned: &quot; + word); if (word.length() &lt; 1) return; System.out.println(&quot;x=&quot; + x + &quot;, charPos=&quot; + charPos + &quot;, word=&quot; + word); } } class MyKeyAdapter extends KeyAdapter implements Serializable { public void keyTyped(KeyEvent ke) { if (ke.getKeyChar()==KeyEvent.VK_SPACE || ke.getKeyChar()==KeyEvent.VK_COMMA || ke.getKeyChar()==KeyEvent.VK_PERIOD) { // Handle new word: //System.out.println(&quot;New word. all text:&quot; + getText()); int charPos = getCaretPosition(); my_char_pos = charPos; System.out.println(&quot;** charPos=&quot; + charPos); String word = getWord(charPos); System.out.println(&quot;** word =&quot; + word); } } } } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-08T16:00:00Z NLEngine.java 2001-12-08T16:00:00Z 2001-12-08T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">// nlbean.NLEngineLocal.java // // Copyright 1997, 1999 Mark Watson. // package nlbean; import java.net.*; import java.io.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.text.*; import java.util.*; import java.beans.*; import java.sql.*; import java.util.Vector; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class NLEngine implements Serializable { public NLEngine() { // Create a DBInfo object and initialize it with the current // database properties: dbinfo = new DBInfo(); nlp = new NLP(dbinfo); // lexicon_data = nlp.lexicon_data; } public void addDB(String name, String user, String passwd, String tbls) { if (numDB &lt; 4) { databaseName[numDB] = name; userName[numDB] = user; password[numDB] = passwd; tableList[numDB] = tbls; numDB++; } } public void initDB() { for (int d=0; d&lt;numDB; d++) { if (databaseName[d]!=null) { String tl[] = Util.parseStrings(tableList[d]); if (tl!=null) { for (int i=0; i&lt;tl.length; i++) { try { String cols[] = DBInterface.getColumnNames(tl[i], databaseName[d], userName[d], password[d]); if (cols!=null) { // lexicon_data.addTableName(tl[i]); dbinfo.addTable(tl[i], databaseName[d], userName[d], password[d], cols); // if (lexicon_data!=null) { // for (int ii=0; ii&lt;cols.length; ii++) { // System.out.println(&quot;adding column name to lexicon: &quot; + cols[ii]); // lexicon_data.addColumnName(cols[ii]); // } // } else { // System.out.println(&quot;null lexicon_data&quot;); // } } } catch (Exception e) { } } } } } dbinfo.debug(); } // NLP data and methods: public void parse(String s) { // Remove any commas from the input text: for (int i=0; i&lt;20; i++) { int idx = s.indexOf(&quot;,&quot;); if (idx&gt;-1) { s = s.substring(0,idx) + s.substring(idx+1); } else { break; } } // Remove any periods from the input text: for (int i=0; i&lt;10; i++) { int idx = s.indexOf(&quot;.&quot;); if (idx&gt;-1) { s = s.substring(0,idx) + s.substring(idx+1); } else { break; } } // remove extra spaces and convert to lower case: s = &quot; &quot; + Util.removeExtraSpaces(s).toLowerCase() + &quot; &quot;; // before calling the NLP class parse method, we // need to replace synonyms: numSynReplacements = 0; for (int i=0; i&lt;numSynonyms; i++) { // allow for multiple uses of the same synonym: for (int repeat=0; repeat&lt;4; repeat++) { int idx = s.indexOf(synonymDescription[i]); if (idx&gt;-1) { s = s.substring(0,idx+1) + synonymColumnName[i] + s.substring(idx + synonymDescription[i].length() - 1); syns[numSynReplacements] = synonymColumnName[i]; origs[numSynReplacements] = synonymDescription[i]; numSynReplacements++; } else { break; } } } // remove extra spaces (just to make sure!): s = Util.removeExtraSpaces(s); nlp.parse(s); } // See if a word is &quot;known&quot; (this includes table and column names): // public boolean goodWord(String s) { // if (lexicon_data.wordInLexicon(s.toLowerCase())) return true; // return false; // } public String getSQL() { return nlp.getSQL(); } private int num_rows_from_database = 0; public String [] breakLines(String s) { String [] ret = new String[40]; int count = 0; num_rows_from_database = 0; try { StringReader sr = new StringReader(s); BufferedReader br = new BufferedReader(sr); while (true) { String s2 = br.readLine(); if (s2 == null || s2.length() &lt; 1) break; num_rows_from_database++; // change for InstantDB: comma separated terms: int index = 0; while (true) { index = s2.indexOf(&quot;,&quot;); if (index == -1) { if (count &gt; 38) break; ret[count++] = s2.trim(); break; } else { if (count &gt; 38) break; ret[count++] = s2.substring(0, index); s2 = s2.substring(index + 1); } } } String [] ret2 = new String[count]; for (int i=0; i&lt;count; i++) ret2[i] = ret[i]; return ret2; } catch (Exception e) { } return null; } public String toEnglish(String r) { System.out.println(&quot;NLEngineLocal.toEnglish(&quot; + r + &quot;)&quot;); return nlp.toEnglish(breakLines(r), syns, origs, numSynReplacements, num_rows_from_database); } public void createResultSet(String sql_query, String database, String user, String password) { //SQL.createResultSet(sql_query, database, user, password); } public String [] getColumnNames(String sql_query, String database, String user, String password) { try { return DBInterface.getColumnNames(sql_query, database, user, password); } catch (Exception e) { } return null; } public String getRows(String sql_query, String database, String user, String password) { try { return DBInterface.query(sql_query, database, user, password); } catch (Exception e) { } return null; } public DBInfo dbinfo; private NLP nlp; // Allow developers to define a few synonyms for a particular // application: private String synonymColumnName[] = new String[11]; private String synonymDescription[] = new String[11]; private int numSynonyms = 0; // For use in generating nglish output for queries: private String syns[] = new String[11]; private String origs[] = new String[11]; private int numSynReplacements=0; public void clearSynonyms() { numSynonyms = 0; } public void addSynonym(String column, String description) { if (numSynonyms&lt;10) { synonymColumnName[numSynonyms] = column; synonymDescription[numSynonyms] = &quot; &quot; + description + &quot; &quot;; numSynonyms++; } } // for four properties each for up to five databases: private String databaseName[] = new String[5]; private String userName[] = new String[5]; private String password[] = new String[5]; private String tableList[] = new String[5]; private int numDB=0; } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-08T16:00:00Z Parser.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z Parser.java 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">/** * Parser.java * * Example program to demonstrate using both a set of * Prolog rules for parsing simple English sentences, * and shows how to embed Sieuwert van Otterloo's Prolog Engine * in a Java program. * * Mark Watson. */ import java.util.*; import java.io.*; public class Parser { public static void main(String [] args) { try { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); Prolog prologEngine = new Prolog(); prologEngine.consultFile(&quot;p.pl&quot;, true); while (true) { System.out.println(&quot;Enter a sentence:&quot;); String line = in.readLine(); if (line == null) return; if (line.length() &lt; 2) return; line = line.trim().toLowerCase(); if (line.endsWith(&quot;.&quot;)) line = line.substring(0, line.length() - 1); StringBuffer sb = new StringBuffer(&quot;sentence([&quot;); StringTokenizer st = new StringTokenizer(line); while (st.hasMoreTokens()) { sb.append(st.nextToken() + &quot;,&quot;); } // drop the last comma and close the brace: String query = sb.toString().substring(0, sb.length()-1) + &quot;],S).&quot;; System.out.println(&quot;Generated Prolog query: &quot; + query); Vector v = prologEngine.solve(query); Hashtable the_answers = (Hashtable)v.elementAt(0); Enumeration enum = the_answers.keys(); while (enum.hasMoreElements()) { String var = (String)enum.nextElement(); String val = (String)the_answers.get(var); System.out.println(val); } } } catch (Exception e) { System.out.println(&quot;Error: &quot; + e); } } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z Prolog.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z Prolog.java 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">/** * CKI Prolog is an prolog interpreter * Sieuwert van Otterloo * http://www.students.cs.uu.nl/~smotterl/prolog * smotterl@cs.uu.nl * 1999 */ /** * Note: from on the web site * http://www.students.cs.uu.nl/~smotterl/prolog * is a message: * &quot;The sourcecode of CKI prolog is free. This means * that it can be modified by anyone.&quot; * * In addition, I received specific permission from * Sieuwert van Otterloo use this code for an example * for my Java AI book. -Mark Watson */ /** * Note #2: Sieuwert's original code was a nice * Java applet with a user interface for Prolog. * I removed the user interface code and added an * API (top level Prolog class) for using the * Prolog engine in Java applications. -Mark Watson */ import java.util.*; import java.io.*; /********************************************************** * PROLOG **********************************************************/ public class Prolog { program prog; solver sv; static private boolean once = true; public Prolog() { prologop.makeops(); if (once) { System.out.println(&quot;CKI Prolog Engine. By Sieuwert van Otterloo.\n&quot;); once = false; } prog=new program(); sv=new solver(prog); prog.setsolver(sv); } public void assert(String s) { term inp=(new prologtokenizer(s)).gettermdot(null); if (sv.assert(inp) == false) { System.out.println(&quot;Error asserting: &quot; + s); } } public Vector solve(String s) { term inp=(new prologtokenizer(s)).gettermdot(null); sv.query(inp); return sv.getAnswers(); } public boolean consultFile(String filename) { return consultFile(filename, false); } public boolean consultFile(String filename, boolean quiet) { try { FileReader fr = new FileReader(filename); BufferedReader br = new BufferedReader(fr); int count = 0; while (true) { String line = br.readLine(); if (line == null) break; if (quiet == false) System.out.println(line); line = line.trim(); if (line.startsWith(&quot;%&quot;) || line.length() &lt; 1) continue; if (line.endsWith(&quot;.&quot;)) { assert(line); } else { while (line.endsWith(&quot;.&quot;) == false) { String s2 = br.readLine(); if (quiet == false) System.out.println(s2); line = line + &quot; &quot; + s2; } assert(line); } } br.close(); return true; // OK } catch (Exception e) { System.out.println(&quot;consultFile error: &quot; + e); e.printStackTrace(); } return false; } static public void main(String [] args) { if (args.length == 0) { /** * Simple example howing how to use embedded Prolog * in your Java programs: */ Prolog p = new Prolog(); p.assert(&quot;father(ken,mark).&quot;); p.assert(&quot;father(ken,ron).&quot;); p.assert(&quot;father(ron,anthony).&quot;); p.assert(&quot;grandfather(X,Z):-father(X,Y),father(Y,Z).&quot;); Vector v = p.solve(&quot;grandfather(X,Y).&quot;); System.out.println(&quot;test results:&quot;); // Vector v = p.solve(&quot;permutation([1,2,3],X).&quot;); for (int i=0; i&lt;v.size(); i++) { System.out.println(); Hashtable the_answers = (Hashtable)v.elementAt(i); Enumeration enum = the_answers.keys(); while (enum.hasMoreElements()) { String var = (String)enum.nextElement(); String val = (String)the_answers.get(var); System.out.println(&quot; var: &quot; + var + &quot; val: &quot; + val); } } } else if (args.length &gt; 1) { /** * Two arguments: a prolog file and a query */ try { Prolog p = new Prolog(); p.consultFile(args[0]); Vector v = p.solve(args[1]); for (int i=0; i&lt;v.size(); i++) { System.out.println(&quot;\nNext answer:&quot;); Hashtable the_answers = (Hashtable)v.elementAt(i); Enumeration enum = the_answers.keys(); while (enum.hasMoreElements()) { String var = (String)enum.nextElement(); String val = (String)the_answers.get(var); System.out.println(&quot; var: &quot; + var + &quot; val: &quot; + val); } } } catch (Exception e) { System.out.println(&quot;error: &quot; + e); e.printStackTrace(); } } } } /*The prologtokenizer breaks a string in such pieces that are usefull for parsing. It searches for constants, numbers, or special operators, and else it returns the characters one by one. It ignores spaces, tabs,enters and %comment.*/ class prologtokenizer { String unused;/*the unprocessed part of the string*/ Vector tokens;/*the allready extracted tokens*/ int cursor;/*the current position in the token vector.*/ static String normalchar= &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz1234567890&quot;; static String opchar=&quot;+-*/\\^&lt;&gt;=`~:.?@#$&amp;&quot;; static String numchar=&quot;1234567890&quot;; boolean splitoff() { /*extract a token from unused, and adds it to tokens*/ /*step 1: skip whitespace 2: decide on first character what the token kind is. 3: seek the end of the token (start) 4: shorten unused, add the token, return true;*/ if(unused==null) return false; int max=unused.length(); int start=0; boolean comment=false; for(start=0;start&lt;max;start++) { if(unused.charAt(start)=='%') comment=true; else if(unused.charAt(start)=='\n') comment=false; if(!comment&amp;&amp;unused.charAt(start)&gt;32) break; } if(start==max) { unused=null;return false; } StringBuffer buf=new StringBuffer(); char d; char c=unused.charAt(start); start++; buf.append(c); if(c==39||c=='&quot;') { boolean closed=false; for(;start&lt;max;start++) { d=unused.charAt(start); if(d==c) { start++; if(start&lt;max&amp;&amp;unused.charAt(start)==c);//mind the ; else {closed=true;break;} } buf.append(d); } if(!closed) return false; } else if(c=='\&quot;') { boolean closed=false; for(;start&lt;max;start++) { d=unused.charAt(start); if(d==c) { start++; if(start&lt;max&amp;&amp;unused.charAt(start)==c);//mind the ; else {buf.append(d);closed=true;break;} } buf.append(d); } } else if(in(c,numchar)) { //number for(;start&lt;max;start++) { d=unused.charAt(start); if(!in(unused.charAt(start),numchar)) break; buf.append(d); } } else if(in(c,opchar)) { //a special operator for(;start&lt;max;start++) { d=unused.charAt(start); if(!in(unused.charAt(start),opchar)) break; buf.append(d); } } else if(in(c,normalchar)) {//normal constant for(;start&lt;max;start++) { d=unused.charAt(start); if(!in(unused.charAt(start),normalchar)) break; buf.append(d); } } tokens.addElement(buf.toString()); unused=unused.substring(start); return true; } public prologtokenizer(String s) { unused=s; cursor=0; tokens=new Vector(); } public term gettermdot(Thread t) { /*get a term, closed by a . (dot or period).*/ term t1=term.getTerm(this); if(t1!=null&amp;&amp;&quot;.&quot;.equals(gettoken())) return t1; return null; } char get0() { /*get a single character.*/ char c='*'; if(unused!=null&amp;&amp;unused.length()&gt;0) { c=unused.charAt(0); unused=unused.substring(1); } return c; } public boolean more() { /*do we have more tokens?*/ if(cursor&lt;tokens.size()) return true; return splitoff(); } public String peek() { /*returns the first token, but does not remove it.*/ if(cursor&gt;tokens.size()) return null; if(cursor==tokens.size()) if(!splitoff())return null; return (String)tokens.elementAt(cursor); } public String gettoken() { /*removes a token out of this tokenizer, and returns that token*/ if(!more()) return null; cursor++; return (String)tokens.elementAt(cursor-1); } int getpos()/*return the position in the tokenvector*/ {return cursor;} void jumpto(int i)/*jump to a position in the tokenvector*/ {cursor=i;} static boolean in(char c,String s) { /*tells wether a char is in a string.*/ for(int i=s.length()-1;i&gt;=0;i--) if(c==s.charAt(i)) return true; return false; } } /********************************************************** * T E R M **********************************************************/ class term { int type; public final static int EQ=211,OPEN=212,NUMBER=213,FUNCTOR=214; String name;//the functor or constant name. String varname;//the name this term would have as a variable String qname;/*the name with quotes, if necessary.*/ int arity;//the number of arguments in a functor. term[] arg;//the arguments in case of functor; public final static int MAXARG=12;//the maximum number of arguments static term emptylist;//the unique empty list static String varstart=&quot;_ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;; static String normalstart= &quot;abcdefghijklmnopqrstuvwxyz'+-*/\\^&lt;&gt;=`~:.?@#$&amp;&quot;; static String numchar=&quot;1234567890&quot;; static int NaN=Integer.MIN_VALUE;/*Not a Number*/ term() { /*make anonymous variable*/ type=OPEN; arity=0; } term(String s) { /*named variable*/ type=OPEN; arity=0; varname=s; } term(prologop pre1,term t) { /*unary operator*/ type=FUNCTOR; name=pre1.name; qname=getqname(name); arity=0; addarg(t); } static term newconstant(String n) {return newconstant(n,getqname(n));} static term newconstant(String n,String qn) { /*make a constant (for example abc)*/ term t=new term(); t.type=FUNCTOR; t.name=n; t.qname=qn; return t; } static String getqname(String inp) /*decides wether a name should be quoted.*/ {if(inp.length()!=0&amp;&amp; prologtokenizer.in(inp.charAt(0),normalstart)) { boolean simple1=true,simple2=true; for(int i=0;i&lt;inp.length();i++) if(!prologtokenizer.in(inp.charAt(i), prologtokenizer.normalchar)) {simple1=false;break;} if(!simple1) for(int i=0;i&lt;inp.length();i++) if(!prologtokenizer.in(inp.charAt(i), prologtokenizer.opchar)) {simple2=false;break;} if(simple1||simple2) return inp; } return &quot;'&quot;+inp+&quot;'&quot;; } term(term t,prologop in1,term t2) { /*infix operator*/ type=FUNCTOR; name=in1.name; qname=getqname(name); arity=0; addarg(t); addarg(t2); } term(int n) { /*number*/ type=NUMBER; arity=n; } static term asciilist(String s) { /*make a list of asciivalues*/ term t=emptylist; for(int i=s.length()-1;i&gt;=0;i--) t=makelist(new term((int)s.charAt(i)),t); return t; } static String readasciilist(term t) { /*make a string from a list of asciivalues*/ StringBuffer buf=new StringBuffer(); term num; t=skipeq(t); while(t.name!=emptylist.name) { if(t.type!=t.FUNCTOR||t.name!=prologop.listcons.name) return null; num=skipeq(t.arg[0]); if(num.type!=NUMBER||num.arity&lt;0||num.arity&gt;255) return null; buf.append((char)num.arity); t=skipeq(t.arg[1]); } return buf.toString(); } static term makelist(term head,term tail) {return new term(head,prologop.listcons,tail);} void functor(String s)/*make this term a functor*/ {functor(s,getqname(s));} void functor(String s,String qs) { /*make this term a functor*/ type=FUNCTOR; name=s; qname=qs; arity=0; } void addarg(term g) { /*add an argument to this functor*/ if(arg==null) arg=new term[MAXARG]; arg[arity]=g; arity++; } static void is(term x,term y) { /*instatiate X to being the same as Y. */ if(x==y) return; x.arity=0; x.type=EQ; x.addarg(y); } static term skipeq(term t) { while(t.type==EQ) t=t.arg[0]; return t; } static boolean equal(term a,term b) { a=skipeq(a); b=skipeq(b); if(a.type!=b.type) return false; if(a.type==NUMBER) return a.arity==b.arity; if(a.type==OPEN) return a==b; if(!a.name.equals(b.name)||a.arity!=b.arity) return false; for(int i=0;i&lt;a.arity;i++) if(!equal(a.arg[i],b.arg[i])) return false; return true; } static boolean match(term in1,term in2, Stack substitutions) { /*match to variables. all variables that are instantiated are added to substitutions.*/ Stack s=new Stack(); Stack t=new Stack(); term top1,top2; s.push(in1); t.push(in2); int height=substitutions.size(); /*Instead of stacking pairs I have a pair of stacks. Both stacks will have the same number of elements.*/ while(!s.empty()) { top1=skipeq((term)s.pop()); top2=skipeq((term)t.pop()); if(top1.type==OPEN) { is(top1,top2); substitutions.push(top1); } else if(top2.type==OPEN) { is(top2,top1); substitutions.push(top2); } else if(top1.type!=top2.type) { unmatch(substitutions,height); return false; } else if(top1.type==NUMBER) { if(top1.arity!=top2.arity) { unmatch(substitutions,height); return false; } } else if(top1.arity!=top2.arity||!top1.name.equals(top2.name)) { unmatch(substitutions,height); return false; } else for(int i=0;i&lt;top1.arity;i++) { s.push(top1.arg[i]); t.push(top2.arg[i]); } } return true; } void open() { /*Make this term an open variable*/ type=OPEN; arity=0; arg=null; } static void unmatch(Stack subst,int height) { /*bring subst to the given height. Undo the instantations*/ while(subst.size()&gt;height) ((term)subst.pop()).open(); } static int numbervalue(term t) { /*calculate the number represented by a term. the term must consist of NUMBER constants kept together by +,-,*,/,mod.*/ t=skipeq(t); if(t.type==NUMBER) return t.arity; if(t.type!=FUNCTOR||t.arity==0) return NaN; int a1=numbervalue(t.arg[0]); if(a1==NaN) return NaN; if(t.arity==1) { if(t.name.equals(&quot;-&quot;)) return -a1; if(t.name.equals(&quot;+&quot;)) return a1; } if(t.arity!=2) return NaN; int a2=numbervalue(t.arg[1]); if(a2==NaN) return NaN; if(t.name.equals(&quot;+&quot;)) return a1+a2; if(t.name.equals(&quot;*&quot;)) return a1*a2; if(t.name.equals(&quot;-&quot;)) return a1-a2; if(t.name.equals(&quot;/&quot;)) { if(a2==0) return NaN; return a1/a2; } if(t.name.equals(&quot;mod&quot;)) { if(a2==0) return NaN; return a1%a2; } return NaN; } /*displaying terms as strings:*/ /*ebbinghaus makes nice names for new variables.*/ static String[] vowel={&quot;a&quot;,&quot;u&quot;,&quot;i&quot;,&quot;o&quot;,&quot;e&quot;}; static String[] conso1={&quot;B&quot;,&quot;D&quot;,&quot;F&quot;,&quot;G&quot;,&quot;H&quot;,&quot;K&quot;,&quot;L&quot;,&quot;M&quot;,&quot;N&quot;,&quot;Z&quot;,&quot;X&quot;}; static String[] conso2={&quot;&quot;,&quot;g&quot;,&quot;f&quot;,&quot;l&quot;,&quot;n&quot;,&quot;m&quot;,&quot;s&quot;,&quot;p&quot;,&quot;t&quot;}; static int count=0; static int total=0; static String ebbinghaus() { /*return a nonsense syllable as varname*/ if(total==0) total=conso1.length*vowel.length*conso2.length; count++; return conso1[count%conso1.length]+ vowel[count%vowel.length]+ conso2[count%conso2.length]; } String varname() { /*the name of this term if it were a variable*/ if(varname==null) varname=ebbinghaus(); return varname; } static String tailstring(term t,boolean quotes) { /*write a term as the end of a string (without [)*/ t=skipeq(t); if(t.type==FUNCTOR) {if(t.name==emptylist.name) return &quot;]&quot;; if(t.name==prologop.listcons.name) return &quot;,&quot;+toString(t.arg[0],1000,quotes) +tailstring(t.arg[1],quotes); } return &quot;|&quot;+t.toString()+&quot;]&quot;; } static String toString(term t,int level,boolean q) { /*write a term as a string.*/ t=skipeq(t); switch(t.type) { case NUMBER: return t.arity+&quot;&quot;; case FUNCTOR: if(t.name==prologop.listcons.name)/*try list display*/ return &quot;[&quot;+toString(t.arg[0],999,q)+tailstring(t.arg[1],q); if(t.arity==0) if(q) return t.qname; else return t.name; prologop o1=prologop.preop(t.name);/*try prefix operator*/ if(t.arity==1&amp;&amp;o1!=null) { if(o1.priority&lt;=level) return t.name+&quot; &quot;+ toString(t.arg[0],o1.rightunderlevel(),q); return &quot;(&quot;+t.name+&quot; &quot;+ toString(t.arg[0],o1.rightunderlevel(),q)+&quot;)&quot;; } o1=prologop.postop(t.name);/*try postfix*/ if(t.arity==1&amp;&amp;o1!=null) { if(o1.priority&lt;=level) return toString(t.arg[0],o1.leftunderlevel(),q) +&quot; &quot;+t.name; return &quot;(&quot;+toString(t.arg[0],o1.leftunderlevel(),q) +&quot; &quot;+t.name+&quot;)&quot;; } o1=prologop.inop(t.name);/*try infix*/ if(t.arity==2&amp;&amp;o1!=null) { String s=toString(t.arg[0],o1.leftunderlevel(),q)+ &quot; &quot;+t.name+&quot; &quot;+ toString(t.arg[1],o1.rightunderlevel(),q); if(o1.priority&lt;=level) return s; return &quot;(&quot;+s+&quot;)&quot;; } String s; if(q) s=t.qname; else s=t.name; s+=&quot;(&quot;+t.toString(t.arg[0],999,q); for(int i=1;i&lt;t.arity;i++) s+=&quot;,&quot;+toString(t.arg[i],999,q); return s+&quot;)&quot;; case OPEN: return t.varname(); } return null; } public String toString() {return toString(this,1201,true);} public String toString(boolean q) {return toString(this,1201,q);} /************** P A R S I N G *************/ public static term getTerm(prologtokenizer tok) /*get a term out of a tokenizer.*/ {return parset(tok,new Hashtable(),1200);} static term parset(prologtokenizer tok,Hashtable vars, int level) { /*parse a tokenized string to a term, with operatorlevel&lt;=level The hashtable contains the variables that are allready made. */ if(!tok.more()) return null; int tokpos=tok.getpos(); prologop p1=prologop.preop(tok.gettoken()); if(p1!=null&amp;&amp;p1.priority&lt;=level) { term t1=parset(tok,vars,p1.rightunderlevel()); if(t1!=null) { t1=readfurther(new term(p1,t1),p1.priority,tok,vars,level); if(t1!=null) return t1; } }/*:the paring of [prefixop][term]. (like -4)*/ tok.jumpto(tokpos); term t=parsetbasic(tok,vars); if(t!=null) { t=readfurther(t,0,tok,vars,level); if(t!=null) return t; }/*:the parsing of [term]*/ tok.jumpto(tokpos); return null; } static term readfurther(term t1,int t1level, prologtokenizer tok,Hashtable vars,int level) { /*try to add postfix and infix operators*/ int tokpos=tok.getpos(); term t; if(!tok.more()) return t1; prologop p1=prologop.postop(tok.gettoken()); if(p1!=null&amp;&amp;p1.priority&lt;=level&amp;&amp;t1level&lt;p1.leftunderlevel()) { t=readfurther(new term(p1,t1),p1.priority, tok,vars,level); if(t!=null) return t; } tok.jumpto(tokpos); p1=prologop.inop(tok.gettoken()); if(p1!=null&amp;&amp;p1.priority&lt;=level&amp;&amp;t1level&lt;p1.leftunderlevel()) { term t2=parset(tok,vars,p1.rightunderlevel()); if(t2!=null) { t=fixin(t1,p1,t2,tok,vars,level); if(t!=null) return t; } } tok.jumpto(tokpos); return t1;/*don't take next operator, wrong level.*/ } static term fixin(term t1, prologop o1,term t2, prologtokenizer tok,Hashtable vars,int highlevel) { if(!tok.more()) return new term(t1,o1,t2); int tokpos=tok.getpos(); term t; prologop o2=prologop.inop(tok.gettoken()); if(o2!=null&amp;&amp;o2.priority&lt;=highlevel) { term t3=parset(tok,vars,o2.rightunderlevel()); if(t3!=null) { if(o1.under(o1,o2)==1) { t=fixin(new term(t1,o1,t2),o2,t3,tok,vars,highlevel); if(t!=null) return t; } else if(o1.under(o1,o2)==2) return new term(t1,o1,new term(t2,o2,t3)); //fail: operators cannot be combined }//if t3 is null: fail. } else { /*there is no or a too high operator. succeed*/ tok.jumpto(tokpos); return new term(t1,o1,t2); } tok.jumpto(tokpos); return null; } static term listread(prologtokenizer tok,Hashtable vars) { /*listread transforms a tokenized string 3,4,5] to a list*/ int tokpos=tok.getpos(); term head=parset(tok,vars,999); if(head==null) { tok.jumpto(tokpos); return null; } int afterhead=tok.getpos(); if(&quot;]&quot;.equals(tok.gettoken())) return makelist(head,emptylist); tok.jumpto(afterhead); if(&quot;,&quot;.equals(tok.gettoken())) { term tail=listread(tok,vars); if(tail==null) {tok.jumpto(tokpos); return null; } return makelist(head,tail); } tok.jumpto(afterhead); if(&quot;|&quot;.equals(tok.gettoken())) { term tail=parset(tok,vars,699);/*under =*/ if(tail!=null&amp;&amp;&quot;]&quot;.equals(tok.gettoken())) return makelist(head,tail); } tok.jumpto(tokpos); return null; } static term parsetbasic(prologtokenizer tok,Hashtable vars) { /*null-pointer indicates failure.*/ term t; if(!tok.more()) return null; int tokpos=tok.getpos(); String f1=tok.peek(); char first=f1.charAt(0); if(f1.equals(&quot;!&quot;)) { tok.gettoken(); t=newconstant(prologop.CUT,prologop.CUT); return t; } if(f1.equals(&quot;(&quot;)) { tok.gettoken(); t=parset(tok,vars,1200); if(&quot;)&quot;.equals(tok.gettoken())) return t; else { tok.jumpto(tokpos); return null; } } if(f1.equals(&quot;[&quot;)) { tok.gettoken(); if(&quot;]&quot;.equals(tok.peek())) { tok.gettoken(); return emptylist; } return listread(tok,vars); } if(first=='&quot;') { tok.gettoken(); return asciilist(f1.substring(1)); } if(tok.in(first,varstart)) { tok.gettoken(); term old=(term)vars.get(f1); if(old!=null&amp;&amp;!f1.equals(&quot;_&quot;)) return old; t=new term(f1); vars.put(f1,t); return t; } else if(tok.in(first,numchar)) { int n; try{n=Integer.parseInt(tok.gettoken());} catch(NumberFormatException e) {return null;} return new term(n); } else if(tok.in(first,normalstart)) { tok.gettoken(); t=new term(); if(first==39) t.functor(f1.substring(1)); else t.functor(f1); if(&quot;(&quot;.equals(tok.peek())) { //try adding arguments tok.gettoken();//get the ( for(int arc=0;arc&lt;MAXARG;arc++) { term q=parset(tok,vars,999);/*under , */ if(q==null) return null;//failure t.addarg(q); if(&quot;)&quot;.equals(tok.peek())) { tok.gettoken(); return t; } if(!&quot;,&quot;.equals(tok.gettoken())) { tok.jumpto(tokpos); return null; } } } return t; } tok.jumpto(tokpos); return null; } /*make a copy of a term:*/ term copy() {return copy(new Hashtable());} term copy(Hashtable h) { term t; switch(type) {case EQ: return arg[0].copy(); case NUMBER: return new term(arity); case OPEN: t=(term)h.get(this); if(t==null) { t=new term(); h.put(this,t); } return t; case FUNCTOR: t=newconstant(name,qname); for(int i=0;i&lt;arity;i++) t.addarg(arg[i].copy(h)); return t; } return null; } static void vars(term t,Vector v) { /*put all vars in term t in the vector*/ t=skipeq(t); if(t.type==OPEN) { if(!v.contains(t)) v.addElement(t); } else if(t.type==FUNCTOR) for(int i=0;i&lt;t.arity;i++) vars(t.arg[i],v); } } /********************************************************** * P R O L O G O P **********************************************************/ class prologop { boolean prex,postx; int place,priority; static int pre=1,in=2,post=3; String name; static String AND,OR,MATCH,ARROW,CUT,REWRITE; /*all operators in play are defined here:*/ static Hashtable preops,inops,postops; static prologop listcons; prologop(){}/*empty constructor. use make as a (sometimes failing) constructor*/ static prologop make(String n,String type,int prior) { /*returns such an operator, or null*/ if(prior&lt;0||prior&gt;1200) return null; prologop p=new prologop(); p.name=n; p.priority=prior; if(type.length()==2&amp;&amp;type.charAt(0)=='f') {p.place=pre; if(type.equals(&quot;fx&quot;)) p.postx=true; else if(type.equals(&quot;fy&quot;)) p.postx=false; else return null; return p; } else if(type.length()==2&amp;&amp;type.charAt(1)=='f') {p.place=post; if(type.equals(&quot;xf&quot;)) p.prex=true; else if(type.equals(&quot;fy&quot;)) p.prex=false; else return null; return p; } else if(type.length()==3&amp;&amp;type.charAt(1)=='f') { p.place=in; if(type.equals(&quot;xfx&quot;)) { p.prex=true; p.postx=true; } else if(type.equals(&quot;xfy&quot;)) { p.prex=true; p.postx=false; } else if(type.equals(&quot;yfx&quot;)) { p.prex=false; p.postx=true; }/*note that yfy would give rise to ambiguity*/ else return null; return p; } return null; } public static void makeops() { if(term.emptylist!=null) return; term.emptylist=term.newconstant(&quot;[]&quot;,&quot;[]&quot;); AND=&quot;,&quot;; OR=&quot;;&quot;; MATCH=&quot;=&quot;; ARROW=&quot;:-&quot;; CUT=&quot;!&quot;; REWRITE=&quot;--&gt;&quot;; preops=new Hashtable(); inops=new Hashtable(); postops=new Hashtable(); addoperator(&quot;?-&quot;,&quot;fx&quot;,1200);// addoperator(ARROW,&quot;xfx&quot;,1200);//the if addoperator(ARROW,&quot;fx&quot;,1200);//the do in programs addoperator(REWRITE,&quot;xfx&quot;,1200);//grammar rules addoperator(&quot;not&quot;,&quot;fx&quot;,900); addoperator(OR,&quot;xfy&quot;,1100);//the ; addoperator(AND,&quot;xfy&quot;,1000);//the , addoperator(MATCH,&quot;xfx&quot;,700);//matchable addoperator(&quot;==&quot;,&quot;xfx&quot;,700);//exactly the same addoperator(&quot;\\==&quot;,&quot;xfx&quot;,700);//not the same addoperator(&quot;&gt;&quot;,&quot;xfx&quot;,700);//compare values addoperator(&quot;&lt;&quot;,&quot;xfx&quot;,700);//compare values addoperator(&quot;&gt;=&quot;,&quot;xfx&quot;,700);//compare values addoperator(&quot;&lt;=&quot;,&quot;xfx&quot;,700);//compare values addoperator(&quot;is&quot;,&quot;xfx&quot;,700);// calculate right addoperator(&quot;=:=&quot;,&quot;xfx&quot;,700);//values equal addoperator(&quot;=\\=&quot;,&quot;xfx&quot;,700);//values unequal addoperator(&quot;=..&quot;,&quot;xfx&quot;,700);//compose a(b)=..[a,b] addoperator(&quot;+&quot;,&quot;yfx&quot;,500); addoperator(&quot;-&quot;,&quot;yfx&quot;,500); addoperator(&quot;-&quot;,&quot;fx&quot;,500); addoperator(&quot;+&quot;,&quot;fx&quot;,500); addoperator(&quot;*&quot;,&quot;yfx&quot;,400); addoperator(&quot;/&quot;,&quot;yfx&quot;,400); addoperator(&quot;div&quot;,&quot;yfx&quot;,400); addoperator(&quot;mod&quot;,&quot;xfx&quot;,300); listcons=make(&quot;.&quot;,&quot;xfy&quot;,600); } public static boolean addoperator(String s,String type,int level) { prologop op=make(s,type,level); if(op==null) return false; if(op.place==op.pre) preops.put(s,op); else if(op.place==op.in) inops.put(s,op); else postops.put(s,op); return true; } public static prologop preop(String name) {return (prologop)preops.get(name);} public static prologop inop(String name) {return (prologop)inops.get(name);} public static prologop postop(String name) {return (prologop)postops.get(name);} int under(prologop o1,prologop o2) { /*1 means that that o1 can be under o2: like 3*4+2 2 means 2+3*4. 0 means they cannot be combined. for example let &lt;-- be xfx, then a &lt;-- b &lt;-- c is a syntax error. */ if(o1.priority&lt;o2.priority) return 1; if(o1.priority&gt;o2.priority) return 2; if(!o2.prex) return 1; if(!o1.postx) return 2; return 0; } int leftunderlevel() { if(prex) return priority-1; return priority; } int rightunderlevel() { if(postx) return priority-1; return priority; } } /********************************************************** * P R O G R A M **********************************************************/ class program { static Hashtable prelude; Hashtable user; /*the hashtables stores lists of clause of certain name and arity.*/ solver sv; program() { if(prelude==null) makeprelude(); user=new Hashtable(); fillwith(user,prelude); } void setsolver(solver S) { sv=S; } static void makeprelude() { prelude=new Hashtable(); assert(prelude,&quot;member(X,[X|_]).&quot;); assert(prelude,&quot;member(X,[_|H]):-member(X,H).&quot;); assert(prelude,&quot;not(X):-X,!,fail.&quot;); assert(prelude,&quot;not(X).&quot;); assert(prelude,&quot;append([],B,B).&quot;); assert(prelude,&quot;append([A|B],C,[A|D]):-append(B,C,D).&quot;); assert(prelude,&quot;select([X|B],X,B).&quot;); assert(prelude,&quot;select([A|B],X,[A|C]):-select(B,X,C).&quot;); assert(prelude,&quot;reverse(X,XR):-reverse(X,[],XR).&quot;); assert(prelude,&quot;reverse([],XR,XR).&quot;); assert(prelude,&quot;reverse([H|T],TR,XR):-reverse(T,[H|TR],XR).&quot;); assert(prelude,&quot;permutation([],[]).&quot;); assert(prelude,&quot;permutation(LX,[X|LP]):-select(LX,X,L),permutation(L,LP).&quot;); } void remove(String s) { /*remove a searchkey.*/ user.remove(s); } static void fillwith(Hashtable to,Hashtable from) { Enumeration enum=from.elements(); term oldlist,newlist; while(enum.hasMoreElements()) { oldlist=(term)enum.nextElement(); if(oldlist!=term.emptylist) to.put(searchkey(head(oldlist.arg[0])),copylist(oldlist)); } } static term copylist(term list) { if(list==term.emptylist) return list; return term.makelist(list.arg[0],copylist(list.arg[1])); } static void listaddz(term list,term t) { list=term.skipeq(list); while(list.arg[1]!=term.emptylist) list=list.arg[1]; list.arg[1]=term.makelist(t,term.emptylist); } public String toString() { Enumeration enum=user.elements(); Vector v; term t; StringBuffer buf=new StringBuffer(&quot;\n&quot;); while(enum.hasMoreElements()) { term list=(term)enum.nextElement(); while(list!=term.emptylist) { buf.append(list.arg[0] +&quot;.\n&quot;); list=list.arg[1]; } buf.append(&quot;\n&quot;); } return buf.toString(); } static boolean assert(Hashtable h,String s) {return assert(h,new prologtokenizer(s).gettermdot(null));} static term gramconvert(term t) { //we assume no eq's in the term (it is parsed or a copy). if(t.type!=term.FUNCTOR||t.arity!=2||!t.name.equals(prologop.REWRITE)) return t; term a,b; a=new term();/*differencelist a-b*/ b=new term(); t.arg[0].addarg(a); t.arg[0].addarg(b); t.arg[1]=makediflist(t.arg[1],a,b); t.name=prologop.ARROW; return t; } static term makediflist(term t,term a,term b) { //t has no eq's if(t.type!=term.FUNCTOR) return term.newconstant(&quot;error&quot;); if(t.name.equals(&quot;[]&quot;)&amp;&amp;t.arity==0) { term is=term.newconstant(prologop.MATCH); is.addarg(a); is.addarg(b); return is; } if(t.name.equals(prologop.listcons.name)) { listend(t,b); term is=term.newconstant(prologop.MATCH); is.addarg(a); is.addarg(t); return is; } if(t.name.equals(prologop.AND)) { term c=new term(); t.arg[0]=makediflist(t.arg[0],a,c); t.arg[1]=makediflist(t.arg[1],c,b); return t; } if(t.name.equals(prologop.OR)) { t.arg[0]=makediflist(t.arg[0],a,b); t.arg[1]=makediflist(t.arg[1],a,b); return t; } t.addarg(a); t.addarg(b); return t; } static void listend(term list,term t) { while(list.arg[1]!=term.emptylist) list=list.arg[1]; list.arg[1]=t; } static boolean assert(Hashtable h,term t) { if(t==null) return false; term thead=head(t); if(thead==null) return false; term list=(term)h.get(searchkey(thead)); if(list==null||list==term.emptylist) { list=term.makelist(t,term.emptylist); h.put(searchkey(thead),list); } else listaddz(list,t); return true; } static boolean asserta(Hashtable h,term t) { if(t==null) return false; //t=term.skipeq(t); term thead=head(t); if(thead==null) return false; term list=(term)h.get(searchkey(thead)); if(list==null) list=term.makelist(t,term.emptylist); else list=term.makelist(t,list); h.put(searchkey(thead),list); return true; } static String searchkey(term t) /*calculates a key for a head, to find it in a hashtable*/ {return t.name+&quot;/&quot;+t.arity;} term get(term head) /*give a predicate, it returns a list of all clauses */ {return (term)user.get(searchkey(head));} static term head(term t) { if(t.type!=t.FUNCTOR) return null; if(t.name.equals(prologop.ARROW)) return t.arg[0]; else return t; } static term body(term t) { if(t.type==t.FUNCTOR&amp;&amp;t.name.equals(prologop.ARROW)) return t.arg[1]; return null; } } /********************************************************** * R A C K **********************************************************/ class rack { term pred; int solveoption; static int BUILTIN=-4,NOTAGAIN=-2,UNKNOWN=-1; term clauses; int substdone; rack parent; rack(term h,rack p) { pred=h; solveoption=UNKNOWN; substdone=0; parent=p; } } /********************************************************** * S O L V E R **********************************************************/ class solver { Stack todo; Stack done; Stack subst; Thread mythread; program lib; Vector uservars; prologtokenizer inp; Stack consultstack; static Hashtable bi_pred; long time; static term ASK; boolean wait; void bi(String s,int a,int n) {bi_pred.put(s+&quot;/&quot;+a,new Integer(n));} solver(program l) { if(ASK==null) { ASK=term.newconstant(&quot;ask user &quot;); bi_pred=new Hashtable(); bi(&quot;repeat&quot;,0,1); bi(&quot;fail&quot;,0,2); bi(&quot;true&quot;,0,3); bi(&quot;!&quot;,0,4); bi(&quot;=&quot;,2,5); bi(&quot;is&quot;,2,6); bi(&quot;=:=&quot;,2,7); bi(&quot;&lt;&quot;,2,8); bi(&quot;&gt;&quot;,2,9); bi(&quot;&lt;=&quot;,2,10); bi(&quot;&gt;=&quot;,2,11); bi(&quot;=\\=&quot;,2,12); bi(&quot;get&quot;,1,15); bi(&quot;get0&quot;,1,16); bi(&quot;seen&quot;,0,17); bi(&quot;nl&quot;,0,20); bi(&quot;put&quot;,1,21); bi(&quot;told&quot;,0,22); bi(&quot;newprogram&quot;,0,23); bi(prologop.listcons.name,2,25); bi(&quot;assert&quot;,1,26); bi(&quot;assertz&quot;,1,26); bi(&quot;asserta&quot;,1,27); bi(&quot;retract&quot;,1,28); bi(&quot;writeprogram&quot;,0,29); bi(&quot;op&quot;,3,30); bi(&quot;var&quot;,1,31); bi(&quot;nonvar&quot;,1,32); bi(&quot;atom&quot;,1,33); bi(&quot;integer&quot;,1,34); bi(&quot;=..&quot;,2,35); bi(&quot;name&quot;,2,36); bi(&quot;==&quot;,2,37); bi(&quot;;&quot;,2,38); bi(&quot;,&quot;,2,39); bi(&quot;compound&quot;,1,40); bi(&quot;random&quot;,3,41); bi(&quot;\\==&quot;,2,42); bi(&quot;writenoq&quot;,1,43); bi(&quot;writeq&quot;,1,44); } lib=l; } int getbinum(term r) { Integer i=(Integer)bi_pred.get(lib.searchkey(r)); if(i==null) return -1; return i.intValue(); } void stacktodo(term q,rack r) { /*push all goals in q on the todo stack, with parent r.*/ if(q==null) return; if(q.type==q.FUNCTOR&amp;&amp;q.name==prologop.AND) { stacktodo(q.arg[1],r); stacktodo(q.arg[0],r); } else todo.push(new rack(q,r)); } void query(term q) { time=System.currentTimeMillis(); todo=new Stack(); done=new Stack(); subst=new Stack(); todo.push(new rack(ASK,null)); uservars=new Vector(); term.vars(q,uservars); stacktodo(q,null); run(5000); // max iters //mythread=new Thread(this); //mythread.start(); } static int FALSE=0,TRUE=1,ERROR=-1; int solve(rack r) { /*return one of FALSE=0,TRUE=1,ERROR=-1*/ if(r.solveoption==r.NOTAGAIN) return FALSE; term rpred=term.skipeq(r.pred); if(rpred.type!=term.FUNCTOR) return ERROR; String fname=rpred.name; int bi=getbinum(rpred); if(bi!=-1) { char c; term t,l; switch(bi){ case 1:return TRUE; case 2:return FALSE; case 3: r.solveoption=r.NOTAGAIN; return TRUE; case 4: r.solveoption=r.NOTAGAIN; rack todo1; rack realparent=r.parent; while(realparent!=null&amp;&amp; (realparent.pred.name==prologop.AND|| realparent.pred.name==prologop.OR)) {realparent=realparent.parent;} int todop=todo.size()-1; while(todop&gt;=0) { todo1=(rack)todo.elementAt(todop); if(todo1.parent!=null&amp;&amp; (todo1.parent.pred.name==prologop.AND|| todo1.parent.pred.name==prologop.OR) ) { todo1.parent=realparent; todop--; } else break; } r.parent=realparent; while(!done.empty()) { if(done.peek()!=r.parent) done.pop(); else break; } if(r.parent!=null) r.parent.solveoption=r.NOTAGAIN; return TRUE; case 5: r.solveoption=r.NOTAGAIN; if(term.match(rpred.arg[0],rpred.arg[1],subst)) return TRUE; else return FALSE; case 6: r.solveoption=r.NOTAGAIN; int n=term.numbervalue(rpred.arg[1]); if(n==term.NaN) return ERROR; if(term.match(rpred.arg[0],new term(n),subst)) return TRUE; else return FALSE; case 7: case 8: case 9: case 10: case 11: case 12: r.solveoption=r.NOTAGAIN; int n1=term.numbervalue(rpred.arg[0]); int n2=term.numbervalue(rpred.arg[1]); if(n1==term.NaN||n2==term.NaN) { System.out.println(&quot;No number&quot;); return ERROR; } if((bi==8&amp;&amp;n1&lt;n2)|| (bi==9&amp;&amp;n1&gt;n2)|| (bi==10&amp;&amp;n1&lt;=n2)|| (bi==11&amp;&amp;n1&gt;=n2)|| (bi==7&amp;&amp;n1==n2)|| (bi==12&amp;&amp;n1!=n2)) return TRUE; else return FALSE; case 15: r.solveoption=r.NOTAGAIN; do{ c=inp.get0(); }while(c&lt;=32); if(term.match(rpred.arg[0],new term((int)c),subst)) return TRUE; else return FALSE; case 16: r.solveoption=r.NOTAGAIN; c=inp.get0(); if(term.match(rpred.arg[0],new term((int)c),subst)) return TRUE; else return FALSE; case 17: r.solveoption=r.NOTAGAIN; inp=null; return TRUE; case 19: r.solveoption=r.NOTAGAIN; return TRUE; case 20: r.solveoption=r.NOTAGAIN; return TRUE; case 21: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type==term.NUMBER&amp;&amp;t.arity&gt;=0&amp;&amp;t.arity&lt;256) { return TRUE; } return ERROR; case 22: r.solveoption=r.NOTAGAIN; return TRUE; case 23: r.solveoption=r.NOTAGAIN; lib=new program(); return TRUE; case 24: case 25: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type!=term.FUNCTOR||t.arity!=0) return ERROR; return TRUE; case 26: r.solveoption=r.NOTAGAIN; if(assert(program.gramconvert(rpred.arg[0].copy()) )) return TRUE; return ERROR; case 27: r.solveoption=r.NOTAGAIN; if(program.asserta(lib.user, program.gramconvert(rpred.arg[0].copy()) )) return TRUE; return ERROR; case 28: r.solveoption=r.NOTAGAIN; return retract(rpred.arg[0]); case 29: r.solveoption=r.NOTAGAIN; return TRUE; case 30: r.solveoption=r.NOTAGAIN; term nam=term.skipeq(rpred.arg[2]); if(nam.type!=term.FUNCTOR||nam.arity!=0) return ERROR; term ty=term.skipeq(rpred.arg[1]); if(ty.type!=term.FUNCTOR||ty.arity!=0) return ERROR; if(prologop.addoperator(nam.name,ty.name, term.numbervalue(rpred.arg[0]))) return TRUE; return ERROR; case 31: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type==term.OPEN) return TRUE; return FALSE; case 32: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type!=term.OPEN) return TRUE; return FALSE; case 33: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type==term.FUNCTOR&amp;&amp;t.arity==0) return TRUE; return FALSE; case 34: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type==term.NUMBER) return TRUE; return FALSE; case 35: r.solveoption=r.NOTAGAIN; term left=term.skipeq(rpred.arg[0]); if(left.type==term.FUNCTOR) { term tail=term.emptylist; for(int i=left.arity-1;i&gt;=0;i--) tail=term.makelist(left.arg[i],tail); term head=term.newconstant(left.name,left.qname); if(term.match(term.makelist(head,tail),rpred.arg[1],subst)) return TRUE; return FALSE; } term right=term.skipeq(rpred.arg[1]); if(right.type==term.FUNCTOR&amp;&amp;right.name==prologop.listcons.name) { term h=term.skipeq(right.arg[0]); if(h.type==term.FUNCTOR&amp;&amp;h.arity==0) {t=term.newconstant(h.name,h.qname); l=term.skipeq(right.arg[1]); while(l!=term.emptylist) { if(t.arity==term.MAXARG||l.type!=term.FUNCTOR ||l.name!=prologop.listcons.name) return ERROR; t.addarg(term.skipeq(l.arg[0])); l=term.skipeq(l.arg[1]); } if(term.match(left,t,subst)) return TRUE; return FALSE; } } return ERROR; case 36: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type==term.FUNCTOR&amp;&amp;t.arity==0) {if(term.match(rpred.arg[1],term.asciilist(t.name),subst)) return TRUE; return FALSE; } String str=term.readasciilist(rpred.arg[1]); if(str!=null&amp;&amp;term.match(rpred.arg[0],term.newconstant(str),subst)) return TRUE; return FALSE; case 37: r.solveoption=r.NOTAGAIN; if(term.equal(rpred.arg[0],rpred.arg[1])) return TRUE; else return FALSE; case 38: if(r.solveoption==r.UNKNOWN) {r.solveoption=r.BUILTIN; stacktodo(rpred.arg[0],r); return TRUE; } r.solveoption=r.NOTAGAIN; stacktodo(rpred.arg[1],r); return TRUE; case 39: r.solveoption=r.NOTAGAIN; stacktodo(rpred.arg[1],r); stacktodo(rpred.arg[0],r); return TRUE; case 40: r.solveoption=r.NOTAGAIN; t=term.skipeq(rpred.arg[0]); if(t.type==term.FUNCTOR&amp;&amp;t.arity&gt;0) return TRUE; return FALSE; case 41: r.solveoption=r.NOTAGAIN; int a=term.numbervalue(rpred.arg[0]); int b=term.numbervalue(rpred.arg[1]); if(a&lt;=b&amp;&amp;a!=term.NaN&amp;&amp;b!=term.NaN) { if(term.match(rpred.arg[2], new term(a+(int)(Math.random()*(b-a))), subst)) return TRUE; return FALSE; } return ERROR; case 42: r.solveoption=r.NOTAGAIN; if(term.equal(rpred.arg[0],rpred.arg[1])) return FALSE; else return TRUE; case 43: r.solveoption=r.NOTAGAIN; return TRUE; case 44: r.solveoption=r.NOTAGAIN; return TRUE; default: System.out.println(&quot;bipred missing.&quot;); return ERROR; }}//OD switch, OD bi!=-1 if(rpred==ASK) { if(uservars.size()==0) return TRUE; substwrite(); return FALSE; } /*No builtin predicate. Get a fitting rule out the clause lib, match the head, and stack the body.*/ if(r.solveoption==r.UNKNOWN) { r.clauses=lib.get(rpred); if(r.clauses==null) { System.out.println(&quot;undefined predicate: &quot;+lib.searchkey(rpred)); return FALSE; } } else if(r.clauses!=term.emptylist) r.clauses=r.clauses.arg[1]; r.solveoption=1; term theclause; while(r.clauses!=term.emptylist) { theclause=r.clauses.arg[0].copy(); if(term.match(rpred,lib.head(theclause),subst)) { stacktodo(lib.body(theclause),r); return TRUE; } r.clauses=r.clauses.arg[1]; } return FALSE; } public void run(int max_iter) { rack current; wait=false; int substnum; int iter = 0; while(iter++ &lt; max_iter) { if(todo.size()==0) { System.out.println(&quot;\nyes&quot;); return; } current=(rack)todo.pop(); int v=solve(current); if(v==ERROR) { do { System.out.println(&quot;Error in: &quot;+current.pred); current=current.parent; } while(current!=null); return; } else if(v==TRUE) { current.substdone=subst.size(); done.push(current); } else {//v==FALSE current.solveoption=rack.UNKNOWN; todo.push(current); if(done.isEmpty()) return; current=(rack)done.pop(); while(((rack)todo.peek()).parent==current) {todo.pop();} todo.push(current); if(!done.isEmpty()) substnum=((rack)done.peek()).substdone; else substnum=0; term.unmatch(subst,substnum); } } } term executepred(term X) { /*returns A if X == (:-A), or null.*/ if(X==null) return null; X=term.skipeq(X); if(X.type==term.FUNCTOR&amp;&amp;X.arity==1&amp;&amp;X.name.equals(&quot;:-&quot;)) return X.arg[0]; return null; } boolean assert(term X) { return program.assert(lib.user,X); } int retract(term t) { term list=lib.get(t); if(list==null||list==term.emptylist) return FALSE; if(term.match(t,lib.head(list.arg[0]),subst)) { lib.user.put(lib.searchkey(t),list.arg[1]); return TRUE; } term superlist=list; list=list.arg[1]; while(list!=term.emptylist) { if(term.match(t,list.arg[0],subst)) { superlist.arg[1]=list.arg[1]; return TRUE; } superlist=list; list=list.arg[1]; } return FALSE; } void substwrite() { term g; StringBuffer buf=new StringBuffer(&quot;\n&quot;); Hashtable hash = new Hashtable(); for(int i=0;i&lt;uservars.size();i++) { g=(term)uservars.elementAt(i); String rightside=&quot;&quot;+g; String leftside=g.varname(); if(!leftside.equals(&quot;_&quot;)&amp;&amp;!leftside.equals(rightside)) { hash.put(leftside, rightside); } } answers.addElement(hash); } Vector answers = new Vector(); Vector getAnswers() { Vector ret = answers; answers = new Vector(); // clear for next time return ret; } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z p.pl 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><TEXTAREA name="code" class="pl" rows="16" cols="100">%% define words: determiner([D],determiner(D) ) :- member(D,[the,a,an]). noun([N], noun(N)) :- member(N,[dog, street, ball, bat, boy]). adj([A], adj(A)) :- member(A,[fast, little, big]). prep([P], prep(P)) :- member(P,[down, under]). verb([V], verb(V)) :- member(V,[ran, caught, yelled, see, saw]). %% parse noun phrases: noun_phrase(NP,noun_phrase(DTree,NTree)) :- append(D,N,NP), determiner(D,DTree), noun(N,NTree). %% parse prepositional phase: prep_phrase(PP, prep_phrase(PTree, NPTree)) :- append(P,NP,PP), prep(P, PTree), noun_phrase(NP, NPTree). %% parse verb phrases: verb_phrase(VP, verb_phrase(VTree, NPTree)) :- append(V,NP,VP), verb(V, VTree), noun_phrase(NP, NPTree). verb_phrase(VP, verb_phrase(VTree, PPTree)) :- append(V,PP,VP), verb(V, VTree), prep_phrase(PP, PPTree). verb_phrase(VP, verb_phrase(VTree)) :- verb(V, VTree). %% parse entences: sentence(S, sentence(NPTree,VPTree) ) :- append(NP,VP,S), noun_phrase(NP,NPTree), verb_phrase(VP,VPTree). %% throw away test code: %% test :- sentence([the,dog, ran], Tree), print(Tree). %% test1 :- sentence([the,dog, ran, down, the, street], Tree), print(Tree). </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z p0.pl 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><TEXTAREA name="code" class="pl" rows="16" cols="100">%% define words: determiner(D) :- member(D,[the,a,an]). noun(N) :- member(N,[dog, street, ball, bat, boy]). adj(A) :- member(A,[fast, little, big]). prep(P) :- member(P,[down, under]). verb(V) :- member(V,[ran, caught, yelled, see, saw]). %% parse noun phrases: noun_phrase([D,N]) :- determiner(D), noun(N). noun_phrase([N]) :- noun(N). %% parse prepositional phase: prep_phrase(PP) :- prep(P), noun_phrase(NP), append([P],NP,PP). %% parse verb phrases: verb_phrase(VP) :- verb(V), noun_phrase(NP), append(V,NP,VP). verb_phrase(VP) :- verb(V), prep_phrase(PP), append([V],PP,VP). verb_phrase([V]) :- verb(V). %% parse entences: sentence(S) :- noun_phrase(NP), verb_phrase(VP), append(NP,VP,S). %% throw away test code: test :- sentence([the,dog, ran]). test1 :- sentence([the,dog, ran, down, the, street]). </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z program.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z prologop.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z prologtokenizer.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z rack.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z solver.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z term.class 2000-06-25T16:00:00Z 2000-06-25T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-25T16:00:00Z default.dfPackage 2000-06-13T16:00:00Z 2000-06-13T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-13T16:00:00Z ATN.class 2000-06-12T16:00:00Z 2000-06-12T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-12T16:00:00Z ATN.java 2000-06-12T16:00:00Z 2000-06-12T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">/** * Title: ATN&lt;p&gt; * Description: Implements a simpl ATN parser that uses WordNet data * Copyright: Copyright (c) by Mark Watson, 2000&lt;p&gt; * @author Mark Watson * @version 1.2 */ import java.io.*; import java.util.*; public class ATN { public ATN() { try { // the following code will read either a local file of a // resource in a JAR file: InputStream ins = ClassLoader.getSystemResourceAsStream(&quot;wncache.dat&quot;); if (ins==null) { System.out.println(&quot;Failed to open 'wncache.dat'&quot;); System.exit(1); } else { ObjectInputStream p = new ObjectInputStream(ins); adj = (Hashtable)p.readObject(); adv = (Hashtable)p.readObject(); noun = (Hashtable)p.readObject(); verb = (Hashtable)p.readObject(); ins.close(); } // Augment the WordNet 1.6 entries: art = new Hashtable(); addWords(art, ARTS); conj = new Hashtable(); addWords(conj, CONJS); det = new Hashtable(); addWords(det, DETS); pron = new Hashtable(); addWords(pron, PRONS); prep = new Hashtable(); addWords(prep, PREPS); // fill in a few common verbs that are not in Wordnet 1.6: verb.put(&quot;ran&quot;, b); } catch (Exception e) { e.printStackTrace(); } } private Boolean b = new Boolean(true); private void addWords(Hashtable h, String [] ws) { for (int i=0; i&lt;ws.length; i++) { h.put(ws[i], b); } } Hashtable adj, adv, art, conj, det, noun, pron, verb, prep; String [] PRONS = {&quot;he&quot;, &quot;she&quot;, &quot;me&quot;, &quot;it&quot;, &quot;you&quot;, &quot;I&quot;}; String [] ARTS = {&quot;the&quot;, &quot;a&quot;, &quot;an&quot;}; String [] CONJS = {&quot;and&quot;, &quot;or&quot;}; String [] DETS = {&quot;who&quot;, &quot;what&quot;, &quot;where&quot;, &quot;when&quot;}; String [] PREPS = {&quot;on&quot;, &quot;at&quot;, &quot;under&quot;, &quot;above&quot;, &quot;behind&quot;, &quot;to&quot;, &quot;about&quot;,&quot;down&quot;}; private boolean checkWord(String word, int type) { if (type == PREP) { if (prep.get(word) != null) return true; } else if (type == VERB) { if (verb.get(word) != null) return true; // some simple kluges to accept words like &quot;likes&quot; when // only &quot;like&quot; is in the lexicon: if (word.endsWith(&quot;s&quot;) || word.endsWith(&quot;ed&quot;)) { String s = word.substring(0, word.length() - 1); if (verb.get(s) != null) return true; } } else if (type == NOUN) { if (noun.get(word) != null) return true; } else if (type == CONJ) { if (conj.get(word) != null) return true; } else if (type == ADJ) { if (adj.get(word) != null) return true; } else if (type == ADV) { if (adv.get(word) != null) return true; } else if (type == PRON) { if (pron.get(word) != null) return true; } else if (type == DET) { if (det.get(word) != null) return true; } else if (type == ART) { if (art.get(word) != null) return true; } return false; } public int [] parse(String s) { Vector v = new Vector(); StringTokenizer st = new StringTokenizer(s); while (st.hasMoreTokens()) { String str = st.nextToken(); if (str.length() &gt; 2 &amp;&amp; str.endsWith(&quot;,&quot;)) { str = str.substring(0, str.length() - 1); } if (str.length() &gt; 2 &amp;&amp; str.endsWith(&quot;.&quot;)) { str = str.substring(0, str.length() - 1); } if (str.length() &gt; 2 &amp;&amp; str.endsWith(&quot;:&quot;)) { str = str.substring(0, str.length() - 1); } if (str.length() &gt; 2 &amp;&amp; str.endsWith(&quot;;&quot;)) { str = str.substring(0, str.length() - 1); } v.addElement(str.toLowerCase()); } // It is easier to work with an array, so convert the Vector // to an array of Java strings: int size = v.size(); if (size == 0) return null; words = new String[size]; partsOfSpeech = new int[size]; num_words = size; for (int i=0; i&lt;size; i++) words[i] = (String)v.elementAt(i); // quick test against lexicon for word types: for (int i=0; i&lt;words.length; i++) { System.out.print(&quot;'&quot; + words[i] + &quot;' possible word types: &quot;); if (adj.get(words[i]) != null) System.out.print(&quot;adj &quot;); if (adv.get(words[i]) != null) System.out.print(&quot;adv &quot;); if (art.get(words[i]) != null) System.out.print(&quot;art &quot;); if (noun.get(words[i]) != null) System.out.print(&quot;noun &quot;); if (prep.get(words[i]) != null) System.out.print(&quot;prep &quot;); if (verb.get(words[i]) != null) System.out.print(&quot;verb &quot;); System.out.println(); } System.out.println(); // execute the parsing helper methods until one succeeds: parse_it(); return null; } String [] words; int [] partsOfSpeech; int wordIndex; int num_words; public static void main(String [] args) { ATN nf = new ATN(); if (args.length &lt; 1) { nf.parse(&quot;the dog ran down the street&quot;); } else { for (int i=0; i&lt;args.length; i++) { System.out.println(&quot;\nProcessing : &quot; + args[i]); nf.parse(args[i]); } } } //////////////// ATN functions: String getPOSname(int pos) { switch (pos) { case 1: return &quot;NP&quot;; case 2: return &quot;VP&quot;; case 3: return &quot;PP&quot;; case 1001: return &quot;noun&quot;; case 1002: return &quot;verb&quot;; case 1003: return &quot;prep&quot;; case 1004: return &quot;conj&quot;; case 1005: return &quot;adj&quot;; case 1006: return &quot;adv&quot;; case 1007: return &quot;pron&quot;; case 1008: return &quot;det&quot;; case 1009: return &quot;art&quot;; default: return &quot;unknown&quot;; } } public final static int NP = 1; public final static int VP = 2; public final static int PP = 3; public final static int NOUN = 1001; public final static int VERB = 1002; public final static int PREP = 1003; public final static int CONJ = 1004; public final static int ADJ = 1005; public final static int ADV = 1006; public final static int PRON = 1007; public final static int DET = 1008; public final static int ART = 1009; public final static int NUM_S = 9; // int [] LEN_S = { 5, 4, 3, 4, 3, 2, 2, 2, 1}; int [] ALL_S [] = { {NP, VP, NP, PP, VP}, {NP, VP, PP, NP}, {NP, VP, NP}, {VP, NP, PP, NP}, {VP, PP, NP}, {NP, VP}, {VP, PP}, {VP, NP}, {VP} }; //////////////// The actual parser: int parsePP(int start_word_index, int word_index) { if (word_index &gt;= num_words) return word_index; // test ATN transitions &lt;PREP&gt; --&gt; &lt;NP&gt; if (checkWord(words[word_index], PREP)) { partsOfSpeech[start_word_index + word_index] = PREP; int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { return ii; } } return -1; } int parseNP(int start_word_index, int word_index) { if (word_index &gt;= num_words) return word_index; // test ATN transitions &lt;NOUN&gt; --&gt; &lt;CONJ&gt; --&gt; &lt;NP&gt; if (word_index &lt; num_words - 2 &amp;&amp; checkWord(words[word_index], NOUN)) { if (checkWord(words[word_index + 1], CONJ)) { int ii = parseNP(start_word_index, word_index + 2); if (ii &gt; -1) { partsOfSpeech[start_word_index + word_index] = NOUN; partsOfSpeech[start_word_index + word_index + 1] = CONJ; return ii; } } } // test ATN transitions &lt;ART&gt; --&gt; &lt;NP&gt; if (word_index &lt; num_words - 1 &amp;&amp; checkWord(words[word_index], ART)) { int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { partsOfSpeech[start_word_index + word_index] = ART; return ii; } } // test ATN transitions &lt;DET&gt; --&gt; &lt;NP&gt; if (word_index &lt; num_words - 1 &amp;&amp; checkWord(words[word_index], ADJ)) { int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { partsOfSpeech[start_word_index + word_index] = ADJ; return ii; } } // test ATN transitions &lt;ADJ&gt; --&gt; &lt;NP&gt; if (checkWord(words[word_index], ADJ)) { int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { partsOfSpeech[start_word_index + word_index] = ADJ; return ii; } } // test ATN transitions &lt;ADV&gt; --&gt; &lt;NP&gt; if (word_index &lt; num_words - 1 &amp;&amp; checkWord(words[word_index], ADV)) { int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { partsOfSpeech[start_word_index + word_index] = ADV; return ii; } } // test ATN transitions &lt;NOUN&gt; --&gt; &lt;NOUN&gt; if (word_index &lt; num_words - 1 &amp;&amp; checkWord(words[word_index], NOUN)) { if (checkWord(words[word_index + 1], NOUN)) { partsOfSpeech[start_word_index + word_index] = NOUN; partsOfSpeech[start_word_index + word_index + 1] = NOUN; return word_index + 2; } } if (checkWord(words[word_index], NOUN)) { partsOfSpeech[start_word_index + word_index] = NOUN; return word_index + 1; } if (checkWord(words[word_index], PRON)) { int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { partsOfSpeech[start_word_index + word_index] = PRON; return ii; } } if (checkWord(words[word_index], PRON)) { partsOfSpeech[start_word_index + word_index] = PRON; return word_index + 1; } return -1; } int parseVP(int start_word_index, int word_index) { if (word_index &gt;= num_words) return word_index; // test ATN transitions &lt;V&gt; --&gt; &lt;NP&gt; --&gt; &lt;PP&gt; if (checkWord(words[word_index], VERB)) { partsOfSpeech[start_word_index + word_index] = VERB; int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { int jj = parsePP(start_word_index, ii); if (jj &gt; -1) { return jj; } } } // test ATN transitions &lt;V&gt; --&gt; &lt;NP&gt; if (checkWord(words[word_index], VERB)) { partsOfSpeech[start_word_index + word_index] = VERB; int ii = parseNP(start_word_index, word_index + 1); if (ii &gt; -1) { return ii; } } // test ATN transitions &lt;V&gt; --&gt; &lt;PP&gt; if (checkWord(words[word_index], VERB)) { partsOfSpeech[start_word_index + word_index] = VERB; int ii = parsePP(start_word_index, word_index + 1); if (ii &gt; -1) { return ii; } } if (checkWord(words[word_index], VERB)) { partsOfSpeech[start_word_index + word_index] = VERB; return word_index + 1; } return -1; } int parseHelper(int [] atn, int start_word_index) { int word_index = 0; int len_atn = atn.length; int last_word_index = word_index; for (int i=0; i&lt;len_atn; i++) { last_word_index = word_index; switch (atn[i]) { case NP: word_index = parseNP(start_word_index, word_index); break; case VP: word_index = parseVP(start_word_index, word_index); break; case PP: word_index = parsePP(start_word_index, word_index); break; } if (word_index == -1) return last_word_index; } return word_index; } int parseSentence(int start_word_index) { int max_val = -1; int max_word_index = 0; for (int i=0; i&lt;NUM_S; i++) { int k = parseHelper(ALL_S[i], start_word_index); //System.out.println(&quot;Score for ATN &quot; + i + &quot; is &quot; + k); if (k &gt; max_val) { max_val = k; max_word_index = i; } } System.out.println(&quot;Best ATN at word_index &quot; + max_word_index); parseHelper(ALL_S[max_word_index], start_word_index); for (int i=0; i&lt;num_words; i++) { if (partsOfSpeech[start_word_index + i] == 0) { if (checkWord(words[i], NOUN)) { partsOfSpeech[start_word_index + i] = NOUN; } if (checkWord(words[i], CONJ)) { partsOfSpeech[start_word_index + i] = CONJ; } } } return max_val; } void parse_it() { int word_index = parseSentence(0); //System.out.println(&quot;word_index from S ATN = &quot; + word_index); for (int i=0; i&lt;num_words; i++) { System.out.println(&quot; word: &quot; + words[i] + &quot; part of speech: &quot; + getPOSname(partsOfSpeech[i])); } } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-12T16:00:00Z MakeWordNetCache.class 2000-06-12T16:00:00Z 2000-06-12T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-12T16:00:00Z MakeWordNetCache.java 2000-06-12T16:00:00Z 2000-06-12T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">/** * Title: MakeWordNetCache&lt;p&gt; * Description: Reads WordNet 1.6 index files and makes a part of speech * serialized file consisting of 4 Java hash tables (for adj, * adv, noun, and verb). * Copyright: Copyright (c) by Mark Watson, 2000&lt;p&gt; * @author Mark Watson * @version 1.1 */ /** Wordnet 1.6 Copyright and License: 1 This software and database is being provided to you, the LICENSEE, by 2 Princeton University under the following license. By obtaining, using 3 and/or copying this software and database, you agree that you have 4 read, understood, and will comply with these terms and conditions.: 5 6 Permission to use, copy, modify and distribute this software and 7 database and its documentation for any purpose and without fee or 8 royalty is hereby granted, provided that you agree to comply with 9 the following copyright notice and statements, including the disclaimer, 10 and that the same appear on ALL copies of the software, database and 11 documentation, including modifications that you make for internal 12 use or for distribution. 13 14 WordNet 1.6 Copyright 1997 by Princeton University. All rights reserved. 15 16 THIS SOFTWARE AND DATABASE IS PROVIDED &quot;AS IS&quot; AND PRINCETON 17 UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 18 IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PRINCETON 19 UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANT- 20 ABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE 21 OF THE LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT 22 INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR 23 OTHER RIGHTS. 24 25 The name of Princeton University or Princeton may not be used in 26 advertising or publicity pertaining to distribution of the software 28 and/or database. Title to copyright in this software, database and 29 any associated documentation shall at all times remain with 30 Princeton University and LICENSEE agrees to preserve same. */ import java.io.*; import java.util.*; public class MakeWordNetCache { Hashtable adj = new Hashtable(); Hashtable adv = new Hashtable(); Hashtable noun = new Hashtable(); Hashtable verb = new Hashtable(); public MakeWordNetCache() { helper(&quot;index.adj&quot;, adj); helper(&quot;index.adv&quot;, adv); helper(&quot;index.noun&quot;, noun); helper(&quot;index.verb&quot;, verb); //System.out.println(verb.get(&quot;run&quot;)); try { FileOutputStream ostream = new FileOutputStream(&quot;wncache.dat&quot;); ObjectOutputStream p = new ObjectOutputStream(ostream); p.writeObject(adj); p.writeObject(adv); p.writeObject(noun); p.writeObject(verb); p.flush(); ostream.close(); } catch (Exception e) { e.printStackTrace(); } } Boolean t = new Boolean(true); public void helper(String file, Hashtable hash) { int count = 0; try { FileReader fr = new FileReader(file); BufferedReader br = new BufferedReader(fr); // skip copyright notice: for (int i=0; i&lt;30; i++) br.readLine(); while (true) { String line = br.readLine(); if (line == null) break; line = line.trim(); int index1 = line.indexOf(&quot; &quot;); if (index1 == -1) continue; line = line.substring(0, index1); int index2 = line.indexOf(&quot;.&quot;); if (index2 != -1) continue; index2 = line.indexOf(&quot;_&quot;); if (index2 != -1) continue; line = line.toLowerCase(); Object o = hash.get(line); if (o == null) { hash.put(line, t); //System.out.println(file + &quot; : &quot; + line); count++; } } System.out.println(&quot;&quot; + count + &quot; words added for &quot; + file); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { MakeWordNetCache MakeWordNetCache1 = new MakeWordNetCache(); } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-12T16:00:00Z SmartDate.java 2000-05-28T16:00:00Z 2000-05-28T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">// nlbean.SmartDate.java // // Copyright 1997, 1999 Mark Watson. // package nlbean; import java.text.*; import java.util.*; import java.io.*; // Utility class to handle dates in fairly arbitrary natural language formats: class SmartDate implements Serializable { private java.util.Date date = null; private Calendar calendar = null; public SmartDate(String s) { System.out.println(&quot;\n***** SmartDate(&quot; + s + &quot;)&quot;); // Try to create a 'SimpleDate' parse string for this string: SimpleDateFormat sdf; try { if (date == null) { sdf = new SimpleDateFormat(&quot;MMM d yyyy&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } if (date == null) { sdf = new SimpleDateFormat(&quot;yyyy MM dd hh mm ss&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } if (date == null) { sdf = new SimpleDateFormat(&quot;yyyy mm dd&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } if (date == null) { sdf = new SimpleDateFormat(&quot;yy mm dd&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } if (date == null) { sdf = new SimpleDateFormat(&quot;EEE MMM d yyyy&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } if (date == null) { sdf = new SimpleDateFormat(&quot;EEE MMM d ''yy&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } if (date == null) { sdf = new SimpleDateFormat(&quot;yyy-mm-dd hh:mm:ss&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } if (date == null) { sdf = new SimpleDateFormat(&quot;MMM d ''yy&quot;); try { date = sdf.parse(s); } catch (Exception pe) { date = null; } } } catch (Exception e) { System.out.println(&quot;Parse error: &quot; + s + &quot;, &quot; + e); } if (date!=null) { calendar = GregorianCalendar.getInstance(); calendar.setTime(date); //System.out.print(&quot;ERA: &quot; + calendar.get(Calendar.ERA) + &quot;. &quot;); System.out.print(&quot;YEAR: &quot; + calendar.get(Calendar.YEAR) + &quot;. &quot;); System.out.print(&quot;MONTH: &quot; + calendar.get(Calendar.MONTH) + &quot;. &quot;); //System.out.print(&quot;WEEK_OF_YEAR: &quot; + calendar.get(Calendar.WEEK_OF_YEAR) + &quot;. &quot;); //System.out.print(&quot;WEEK_OF_MONTH: &quot; + calendar.get(Calendar.WEEK_OF_MONTH) + &quot;. &quot;); System.out.print(&quot;DATE: &quot; + calendar.get(Calendar.DATE) + &quot;. &quot;); System.out.print(&quot;DAY_OF_MONTH: &quot; + calendar.get(Calendar.DAY_OF_MONTH) + &quot;. &quot;); //System.out.print(&quot;DAY_OF_YEAR: &quot; + calendar.get(Calendar.DAY_OF_YEAR) + &quot;. &quot;); //System.out.print(&quot;DAY_OF_WEEK: &quot; + calendar.get(Calendar.DAY_OF_WEEK) + &quot;. &quot;); //System.out.print(&quot;DAY_OF_WEEK_IN_MONTH: &quot; // + calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH) + &quot;. &quot;); //System.out.print(&quot;AM_PM: &quot; + calendar.get(Calendar.AM_PM) + &quot;. &quot;); //System.out.print(&quot;HOUR: &quot; + calendar.get(Calendar.HOUR) + &quot;. &quot;); //System.out.print(&quot;HOUR_OF_DAY: &quot; + calendar.get(Calendar.HOUR_OF_DAY) + &quot;. &quot;); //System.out.print(&quot;MINUTE: &quot; + calendar.get(Calendar.MINUTE) + &quot;. &quot;); //System.out.print(&quot;SECOND: &quot; + calendar.get(Calendar.SECOND) + &quot;. &quot;); //System.out.print(&quot;MILLISECOND: &quot; + calendar.get(Calendar.MILLISECOND) + &quot;. &quot;); System.out.println(&quot;&quot;); } else { System.out.println(&quot;Parse error: &quot; + s); } } public int getYear() { if (date!=null &amp;&amp; calendar!=null) { return calendar.get(Calendar.YEAR); } return 0; } public int getMonth() { if (date!=null &amp;&amp; calendar!=null) { return calendar.get(Calendar.MONTH); } return 0; } public int getDayOfMonth() { if (date!=null &amp;&amp; calendar!=null) { return calendar.get(Calendar.DAY_OF_MONTH); } return 0; } public long getMilliseconds() { if (date!=null &amp;&amp; calendar!=null) { return calendar.get(Calendar.MILLISECOND); } return 0; } public boolean valid() { if (calendar==null) return false; if (calendar.get(Calendar.MILLISECOND)!=0) return true; if (calendar.get(Calendar.YEAR)!=0) return true; if (calendar.get(Calendar.DAY_OF_MONTH)!=0) return true; if (calendar.get(Calendar.DATE)!=0) return true; return false; } public String toString() { if (valid()==false) return &quot;&lt;not valid date&gt;&quot;; //return getMonth() + &quot;/&quot; + getDayOfMonth()+1 + &quot;/&quot; + getYear(); int month = getMonth() + 1; return getYear() + &quot;-&quot; + month + &quot;-&quot; + getDayOfMonth(); //SimpleDateFormat formatter // = new SimpleDateFormat (&quot;mm/dd/yyyy&quot;); //return formatter.format(date); } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-28T16:00:00Z nlbean.jar 2000-05-28T16:00:00Z 2000-05-28T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-28T16:00:00Z nlbean.jrl 2000-05-28T16:00:00Z 2000-05-28T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-28T16:00:00Z readme.txt 2000-05-28T16:00:00Z 2000-05-28T16:00:00Z <br/>Thank you for downloading the new version 4 of the NLBean.<br/><br/>This version is released under an Open Source license agreement<br/>and is free for private and commercial use.<br/><br/>Peter Hearty kindly gave me permission to include the compiled<br/>version of his VERY COOL pure Java database program InstantDB.<br/><br/>Please note that InstantDB is only free for non-commercial<br/>use! Peter charges a very reasonable fee for commercial<br/>use of InstantDB. Please visit his web site at<br/><a href="http://instantdb.enhydra.org/">http://instantdb.enhydra.org/</a> for details. Thanks Peter! <br/>(The directories 'jdbc' and 'db' contain Peter's compiled<br/>code and the directory 'database' contains a small test<br/>database created with the nlbean.MakeTestDB program.)<br/><br/>The source code and compiled files for the NLBean are in<br/>the directory 'nlbean'.<br/><br/>Some of you may have noticed a large jump in version number.<br/>Version 4 is a major cleanup of the NLBean: it needed it!<br/>(I had originally written the NLBean quite quickly for my own<br/>use, and the old source code was very ugly.) Anyway, I had a<br/>lot of experimental code in teh NLBean, which I have removed.<br/><br/>There is still some more cleanup work to be done on the<br/>source code, so look for a future update with a small<br/>version number change.<br/><br/>To run the NLBean, use the run.bat file. There are several<br/>example queries in a selection list. If you are typing<br/>a query and the word that you just typed changes to all<br/>uppercase characters, that means that the NLBean does not<br/>understand that word; click the mouse on the upper case word<br/>to get a popup window with suggested alternative words.<br/><br/>The c.bat command file can be used to re-compile everything,<br/>but I included compiled class files so you will not have to<br/>do this until you edit the source.<br/><br/>The NLBean is packaged up as a demo. The file nlbean.NLBean.java<br/>contains a hardwired database, usename, and password. In a future<br/>version, I will use a small config file to change the database setup<br/>so that you don't have to edit the code to use another database system.<br/><br/>Enjoy!<br/><br/>-Mark Watson www.markwatson.com<br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-28T16:00:00Z trace.log 2000-05-28T16:00:00Z 2000-05-28T16:00:00Z <br/><TEXTAREA name="code" class="log" rows="16" cols="100">AWT-EventQueue-0 SELECT Employees.Salary FROM Employees WHERE Employees.EmpName = 'mark' </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-28T16:00:00Z wncache.dat 2000-05-12T16:00:00Z 2000-05-12T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-12T16:00:00Z