package com.jaivox.interpreter; import java.io.*; import java.util.*; import com.jaivox.tools.Config; import com.jaivox.util.*; /** * TestInteract is a command line program to test just the interpreter * without the use of agents. there are various tests to see if the * answers generated are reasonable. The questions and answers will * be recorded in a text file. */ public class TestInteract extends Thread { static int waittime = 500; // milliseconds static String questions []; static String fullyspeced []; static String variablyspeced []; static TreeMap <String, Vector <String>> specLinks; static void gatherQuestions (Interact inter) { TreeMap<String, String> qspecs = inter.qspecs; Set<String> qq = qspecs.keySet (); int n = qspecs.size (); questions = new String[n]; int i = 0; for (Iterator<String> it = qq.iterator (); it.hasNext ();) { questions[i++] = it.next ().trim (); } } static void gatherSpecQuestions (Interact inter) { TreeMap<String, String> qspecs = inter.qspecs; Set<String> qq = qspecs.keySet (); Vector <String> full = new Vector <String> (); Vector <String> not = new Vector <String> (); for (Iterator<String> it = qq.iterator (); it.hasNext ();) { String q = it.next (); String s = qspecs.get (q); if (s.indexOf ("_") == -1) { full.add (q); } else { not.add (q); } } int n = full.size (); fullyspeced = new String [n]; for (int i=0; i<n; i++) { fullyspeced [i] = full.elementAt (i); } int m = not.size (); variablyspeced = new String [m]; for (int i=0; i<m; i++) { variablyspeced [i] = not.elementAt (i); } linkSpecs (inter); } static void linkSpecs (Interact inter) { String dummy = "dummy"; specLinks = new TreeMap <String, Vector <String>> (); for (int i=0; i<fullyspeced.length; i++) { String f = fullyspeced [i]; // String fspec = inter.qspecs.get (f.toLowerCase ()); Qapair fqa = new Qapair (inter, 0, f, dummy); Vector <String> hold = new Vector <String> (); for (int j=0; j<variablyspeced.length; j++) { String v = variablyspeced [j]; // String vspec = inter.qspecs.get (v.toLowerCase ()); Qapair vqa = new Qapair (inter, 0, v, dummy); if (qaMatches (fqa, vqa)) hold.add (v); } if (hold.size () > 0) { specLinks.put (f, hold); // System.out.println ("Added "+hold.size ()+" matches for "+f); } } } static boolean qaMatches (Qapair a, Qapair b) { if (!b.field.equals ("_") && !b.field.equals ("")) { if (!b.field.equals (a.field)) return false; } if (!b.attribute.equals ("_") && !b.attribute.equals ("")) { if (!b.attribute.equals (a.attribute)) return false; } if (!b.quant.equals ("_") && !b.quant.equals ("")) { if (!b.quant.equals (a.quant)) return false; } if (!b.nnp.equals ("_") && !b.nnp.equals ("")) { if (!b.nnp.equals (a.nnp)) return false; } return true; } static void doRandomTests (Interact inter) { int N = 20; int n = questions.length; double nx = (double)n; for (int j = 0; j < N; j++) { int id = (int) (nx * Math.random ()); if (id >= n) id = n - 1; String question = questions [id]; System.out.println ("> " + question); if (question.length () == 0) continue; String result = inter.execute (question); System.out.println (result); } } static void followonTests (Interact inter) { int N = 20; int M = 8; int n = fullyspeced.length; double nx = (double)n; for (int i=0; i<N; i++) { int id = (int) (nx * Math.random ()); if (id >= n) id = n - 1; // do the qa with the fully speced question String question = fullyspeced [id]; System.out.println ("> " + question); if (question.length () == 0) continue; String result = inter.execute (question); System.out.println (result); int Mnow = (int)(Math.random ()*M); Vector <String> matches = specLinks.get (question); if (matches == null) continue; int mn = matches.size (); int mxx = Math.min (mn, Mnow); for (int j=0; j<mxx; j++) { int jd = (int)(mn*Math.random ()); if (jd >= mn) jd = mn - 1; String follow = matches.elementAt (jd); System.out.println ("> " + follow); result = inter.execute (follow); System.out.println (result); } } } // cause num edit errors in the given word static String causeEditErrors (String word, int num) { char c [] = word.toCharArray (); int n = c.length; int count = 0; while (count < num) { int toss = (int)(Math.random () * 3.01); if (toss == 3) continue; switch (toss) { case 0: { // create a deletion error int i = (int)(Math.random () * n); StringBuffer sb = new StringBuffer (); for (int j=0; j<i; j++) { sb.append (c [j]); } for (int j=i+1; j<n; j++) { sb.append (c [j]); } word = new String (sb); c = word.toCharArray (); count++; n--; continue; } case 1: {// create an insertion error int i = (int)(Math.random () * n); StringBuffer sb = new StringBuffer (); for (int j=0; j<i; j++) { sb.append (c [j]); } sb.append ('a'); for (int j=i; j<n; j++) { sb.append (c [j]); } word = new String (sb); c = word.toCharArray (); count++; n++; continue; } case 2: { // switch two characters int i = (int)(Math.random () * n); int j = (int)(Math.random () * n); char d = c [i]; c [i] = c [j]; c [j] = d; count++; continue; } } } String result = new String (c); return result; } static String causeSentenceErrors (String sentence, int num) { String words [] = sentence.split (" "); int n = words.length; int count = 0; while (count < num) { int toss = (int)(Math.random () * 3.01); if (toss == 3) continue; switch (toss) { case 0: { // create a deletion error int i = (int)(Math.random () * n); StringBuffer sb = new StringBuffer (); for (int j=0; j<i; j++) { sb.append (words [j]); sb.append (" "); } for (int j=i+1; j<n; j++) { sb.append (words [j]); sb.append (" "); } String full = new String (sb); words = full.split (" "); n--; count++; continue; } case 1: {// create an insertion error int i = (int)(Math.random () * n); StringBuffer sb = new StringBuffer (); for (int j=0; j<i; j++) { sb.append (words [j]); sb.append (" "); } sb.append ("aaaaa "); for (int j=i; j<n; j++) { sb.append (words [j]); sb.append (" "); } String full = new String (sb); words = full.split (" "); count++; n++; continue; } case 2: { // switch two characters int i = (int)(Math.random () * n); int j = (int)(Math.random () * n); String d = words [i]; words [i] = words [j]; words [j] = d; count++; continue; } } } String result = join (words, " "); return result; } static String join (String words [], String sep) { StringBuffer sb = new StringBuffer (); for (int i=0; i<words.length-1; i++) { sb.append (words [i]); sb.append (sep); } sb.append (words [words.length-1]); String result = new String (sb); return result; } static String messup (String question) { // should we mess up some words int toss = (int)(Math.random ()*10.0); String result = ""; if (toss > 5) { // how many words to mess up? String words [] = question.split (" "); int n = words.length; int count = (int)(Math.random ()*4); for (int i=0; i<count; i++) { int j = (int)(Math.random ()*(n-1)); String word = words [j]; // int errors = (int)(Math.random ()*(word.length ()/2)); int errors = 2; words [j] = causeEditErrors (word, errors); } result = join (words, " "); } else { int count = 2; result = causeSentenceErrors (question, count); } return result; } static void fintestateTests (Interact inter) { int N = 20; int n = fullyspeced.length; double nx = (double)n; int count = 0; String question = ""; while (count < N) { String qs = inter.qstate; if (qs.equals ("initial")) { int id = (int) (nx * Math.random ()); if (id >= n) id = n - 1; question = fullyspeced [id]; // should we mess this up? if (Math.random () > 0.4) { // System.out.println ("original: "+question); question = messup (question); // System.out.println ("messed up: "+question); // record what was heard // inter.Record.record ("H: "+question); } } else if (qs.equals ("asking_confirmation")) { if (Math.random () > 0.4) { question = "yes"; } else { question = "no"; } } else { question = "Please enter quit interactively."; } System.out.println ("> " + question); if (question.length () == 0) continue; String result = inter.execute (question); System.out.println (result); count++; } } /** * Do various tests. You can specify the type of test using the second * command line argument. Here you can have "random" tests, tests of * "followon" or followup questions and tests of the finite state machine * involved in handling conversations. @param args */ public static void main (String args[]) { new Config (args [0]); Properties kv = Config.kv; Interact inter = new Interact ("./", kv); gatherQuestions (inter); gatherSpecQuestions (inter); try { if (args.length > 1) { String command = args[1]; if (command.equals ("random")) { doRandomTests (inter); return; } else if (command.equals ("followon")) { followonTests (inter); return; } else if (command.equals ("finitestates")) { fintestateTests (inter); return; } // else BufferedReader in = new BufferedReader ( new FileReader (command)); String line; while ((line = in.readLine ()) != null) { System.out.println ("> " + line); if (line.trim ().length () == 0) continue; String result = inter.execute (line); System.out.println (result); } in.close (); inter.terminate (); } else { BufferedReader in = new BufferedReader (new InputStreamReader ( System.in)); while (true) { System.out.print ("> "); String line = in.readLine (); if (line.equals ("quit")) { System.out.println ("Ending test program"); inter.terminate (); } String result = inter.execute (line); sleep (waittime); System.out.println ("Result: " + result); } } } catch (Exception e) { Log.severe ("Unknown file or command "+args [1]); } } }