I have the following Prolog files:
(clauses.qa2.pl)
get(mary,milk,1).
go(john,bedroom,1).
go(sandra,kitchen,1).
go(mary,hallway,1).
get(john,football,1).
go(john,hallway,2).
drop(john,football,2).
go(mary,garden,2).
go(john,kitchen,3).
and (rules.pl)
/*This rule finds last location of a person */
isAt(X,Y) :- go(X, Y, T), \+ (go(X,_,T2), T2 > T).
/* This rule finds the last location of an object */
whereIs(Q,R) :- findall(R,(get(P,Q,I),go(P,R,_)),L), last(L,R),!.
along with the following java code:
import java.util.Hashtable;
import jpl.*;
import java.io.*;
import jpl.Query;
import java.util.Scanner;
public class PrologTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//include the prolog file with clauses to test
File clauseFile = new File ("C:\\Natural_Language_Final_Project\\PrologTest\\src\\clauses_qa2.pl");
File ruleFile = new File ("C:\\Natural_Language_Final_Project\\PrologTest\\src\\rules.pl");
String clausePath = clauseFile.getAbsolutePath();
String rulePath = ruleFile.getAbsolutePath();
System.out.println("Clause file path: " + clausePath);
System.out.println("Rule file path: " + rulePath);
Query q1 = new Query("consult",new Term[]{new Atom("C:\\Natural_Language_Final_Project\\PrologTest\\src\\clauses_qa2.pl")});
Query q2 = new Query("consult",new Term[]{new Atom("C:\\Natural_Language_Final_Project\\PrologTest\\src\\rules.pl")});
Scanner scan = new Scanner(ruleFile);
while (scan.hasNextLine()){
System.out.println(scan.nextLine());
}
jpl.JPL.init();
Variable X = new Variable("X");
Variable Y = new Variable ("Y");
Query q = new Query(new Compound("isAt",new Term[]{new Atom("john"),X}));
Hashtable solution = q.oneSolution();
System.out.println( "X = " + solution.get("X"));
}
The java code, given the Prolog should return X = kitchen. Instead, I get the following error:
Exception in thread "main" jpl.PrologException: PrologException:
error(existence_error(procedure, /(isAt, 3)), context(:(system, /('$c_call_prolog', 0)), _0))
at jpl.Query.get1(Query.java:336)
at jpl.Query.hasMoreSolutions(Query.java:258)
at jpl.Query.oneSolution(Query.java:688)
at PrologTest.main(PrologTest.java:43)
Any ideas on how to correct this?
Related
I want to check and verify that all of the contents in the ArrayList are similar to the value of a String variable. If any of the value is not similar, the index number to be printed with an error message like (value at index 2 didn't match the value of expectedName variable).
After I run the code below, it will print all the three indexes with the error message, it will not print only the index number 1.
Please note that here I'm getting the data from CSV file, putting it into arraylist and then validating it against the expected data in String variable.
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
public class ValidateVideoDuration {
private static final String CSV_FILE_PATH = "C:\\Users\\videologs.csv";
public static void main(String[] args) throws IOException {
String expectedVideo1Duration = "00:00:30";
String expectedVideo2Duration = "00:00:10";
String expectedVideo3Duration = "00:00:16";
String actualVideo1Duration = "";
String actualVideo2Duration = "";
String actualVideo3Duration = "";
ArrayList<String> actualVideo1DurationList = new ArrayList<String>();
ArrayList<String> actualVideo2DurationList = new ArrayList<String>();
ArrayList<String> actualVideo3DurationList = new ArrayList<String>();
try (Reader reader = Files.newBufferedReader(Paths.get(CSV_FILE_PATH));
CSVParser csvParser = new CSVParser(reader,
CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());) {
for (CSVRecord csvRecord : csvParser) {
// Accessing values by Header names
actualVideo1Duration = csvRecord.get("Video 1 Duration");
actualVideo1DurationList.add(actualVideo1Duration);
actualVideo2Duration = csvRecord.get("Video 2 Duration");
actualVideo2DurationList.add(actualVideo2Duration);
actualVideo3Duration = csvRecord.get("Video 3 Duration");
actualVideo3DurationList.add(actualVideo3Duration);
}
}
for (int i = 0; i < actualVideo2DurationList.size(); i++) {
if (actualVideo2DurationList.get(i) != expectedVideo2Duration) {
System.out.println("Duration of Video 1 at index number " + Integer.toString(i)
+ " didn't match the expected duration");
}
}
The data inside my CSV file look like the following:
video 1 duration, video 2 duration, video 3 duration
00:00:30, 00:00:10, 00:00:16
00:00:30, 00:00:15, 00:00:15
00:00:25, 00:00:10, 00:00:16
Don't use == or != for string compare. == checks the referential equality of two Strings and not the equality of the values. Use the .equals() method instead.
Change your if condition to if (!actualVideo2DurationList.get(i).equals(expectedVideo2Duration))
Below is my code to take a somewhat simple user input of hello or mouse and search a String(I will later use this on much larger text files).
I use it to create a Java line of code that uses the contains method. After, I need to evaluate it. I found some help using the Script engine, but I keep getting this error: Exception in thread "main" javax.script.ScriptException: ReferenceError: "name" is not defined in <eval> at line number 1 The output that comes from the code that I want to evaluate is name.contains("hello") || name.contains("mouse").
Any help would be great. Thanks
public static void main(String args[]) throws ScriptException {
String searchString = "name";
String terms = "(hello) || (mouse)";
String command = "";
//multiple commands
if(terms.contains("(") && terms.contains(")") && terms.contains("[") && terms.contains("]")){
command = terms.replace(")","\")");
command=command.replace("(", searchString + ".contains(\"");
command = command.replace("[","(");
command = command.replace("]",")");
}
//only ands/ only ors
else {
command = terms.replace("(", searchString + ".contains(\"");
command = command.replace(")", "\")");
}
System.out.println(command);
String name = "mousehellonamepe";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval(command);
System.out.println(result);
What are you trying to do exactly ?
======= Update ======
First, String terms should be a list.
Make it:
ArrayList<String> searchTerms = new ArrayList();
Add as many words as you like to that list as follows:
// using add() to initialize values
arr.add("Hello");
arr.add("Mouse");
arr.add("Bike");
arr.add("House");
// use contains() to check if the element
// 2 exits or not
boolean mouseExists = arr.contains("Mouse");
if (ans)
System.out.println("Our list contains the word mouse");
else
System.out.println("Our list does not contain the word mouse");
This should output this:
Our list contains the word mouse
Code should look like this:
public static void main(String args[]) throws ScriptException {
ArrayList<String> searchTerms = new ArrayList();
arr.add("Hello");
arr.add("Mouse");
arr.add("Bike");
arr.add("House");
boolean mouseExists = arr.contains("Mouse");
if (ans)
System.out.println("Our list contains the word mouse");
else
System.out.println("Our list does not contain the word mouse");
}
Interpreter i = new Interpreter();
i.set("searchThis", searchString);
i.set("answer", i.eval(command));
Boolean answer2 = (Boolean) (i.get("answer"));
http://www.beanshell.org/manual/quickstart.html#Calling_BeanShell_From_Your_Application
I used this to evaluate the command.
the link above provides all the explanation!
I'm testing this class
/**
* Class to classify irises based on petal and sepal measurements.
*
* #author James Howard <jh#jameshoward.us>
*/
package us.jameshoward.iristypes;
import java.io.InputStream;
import java.util.Dictionary;
import java.util.Enumeration;
import weka.classifiers.Classifier;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.SerializationHelper;
public class Iris {
private Classifier classModel;
private Instances dataModel;
private String classModelFile = "/Irises/etc/iris.model";
/**
* Class constructor.
*/
public Iris() throws Exception {
InputStream classModelStream;
// Create a stream object for the model file embedded
// within the JAR file.
classModelStream = getClass().getResourceAsStream(classModelFile);
classModel = (Classifier)SerializationHelper.read(classModelStream) ;
}
/**
* Close the instance by setting both the model file string and
* the model object itself to null. When the garbage collector
* runs, this should make clean up simpler. However, the garbage
* collector is not called synchronously since that should be
* managed by the larger execution environment.
*/
public void close() {
classModel = null;
classModelFile = null;
}
/**
* Evaluate the model on the data provided by #param measures.
* This returns a string with the species name.
*
* #param measures object with petal and sepal measurements
* #return string with the species name
* #throws Exception
*/
public String classifySpecies(Dictionary<String, String> measures) throws Exception {
#SuppressWarnings("rawtypes")
FastVector dataClasses = new FastVector();
FastVector dataAttribs = new FastVector();
Attribute species;
double values[] = new double[measures.size() + 1];
int i = 0, maxIndex = 0;
// Assemble the potential species options.
dataClasses.addElement("setosa");
dataClasses.addElement("versicolor");
dataClasses.addElement("virginica");
species = new Attribute("species", dataClasses);
// Create the object to classify on.
for (Enumeration<String> keys = measures.keys(); keys.hasMoreElements(); ) {
String key = keys.nextElement();
double val = Double.parseDouble(measures.get(key));
dataAttribs.addElement(new Attribute(key));
values[i++] = val;
}
dataAttribs.addElement(species);
dataModel = new Instances("classify", dataAttribs, 0);
dataModel.setClass(species);
dataModel.add(new Instance(1, values));
dataModel.instance(0).setClassMissing();
// Find the class with the highest estimated likelihood
double cl[] = classModel.distributionForInstance(dataModel.instance(0));
for(i = 0; i < cl.length; i++)
if(cl[i] > cl[maxIndex])
maxIndex = i;
return dataModel.classAttribute().value(maxIndex);
}
}
when start initialising its instance from another class with
Iris irisModel = new Iris();
i got following error
Exception in thread "main" java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2320)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2333)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2804)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at weka.core.SerializationHelper.read(SerializationHelper.java:288)
at us.jameshoward.iristypes.Iris.<init>(Iris.java:33)
at us.jameshoward.iristypes.IrisDriver.main(IrisDriver.java:11)
I guess this error is case specific, by comparing with other posts, i still cant find out where it went wrong. in fact, this class was downloaded from IBMknowledge website, it supposes to be error-proof i guess.
anyone knows how to fix this?
thanks
I have a fairly simple stored java procedure in an oracle database. The intended purpose is to read the contents of a folder which resides on the Oracle server. If it encounters a folder it will step into the folder and write the name of the contents into a global temp table, and move on to the next folder. The Java procedure compiles fine and submits into the database with no issues. When it's called by a stored Oracle procedure it runs successfully as well. But produces no results into the global temp table. I am using TOAD and i'm not sure how to put a break or view the variables during run time so i'm kind of flying blind. And i'm admittedly not great a java.
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED BALT_CHECK."WebDirList" AS
import java.io.*;
import java.sql.*;
import java.util.Date;
import java.text.SimpleDateFormat;
public class WebDirList
{
public static void getList(String rootdirectory) throws SQLException
{
File path = new File( rootdirectory );
String[] rootDirList = path.list();
String element;
for( int x = 0; x < rootDirList.length; x++)
{
element = rootDirList[x];
String newPath = rootdirectory + "/" + rootDirList[x] ;
File f = new File(newPath);
if (f.isFile()){
/* Do Nothing */
} else {
/*if it is a folder than load the subDirPath variable with the newPath variable */
File subDirPath = new File( newPath+"/");
String[] subDirList = subDirPath.list();
String efileName;
for(int i = 0; i < subDirList.length; i++)
{
efileName = subDirList[i];
String fpath = subDirPath + "/" + subDirList[i];
File nf = new File(fpath);
long len;
Date date;
String ftype;
String sqlDate;
SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss");
if (f.isFile()) {
len = f.length();
date = new Date(f.lastModified());
sqlDate = df.format(date);
#sql { INSERT INTO WEB_DIRLIST (FILENAME, LENGTH, CREATEDATE)
VALUES (:efileName, :len, to_date(:sqlDate, 'YYYY-MM-DD HH24:MI:SS')) };
}else{
/* Do nothing */
}
}
}
}
}
}
/
Procedure is created as
CREATE OR REPLACE procedure BALT_CHECK.get_webdir_list( p_directory in varchar2)
as language java
name 'WebDirList.getList( java.lang.String )';
/
Procedure is called as
exec get_webdir_list( '/transfer_edi/hs122/');
in the folder /transfer/edi/hs122/ are 10 sub directories each have between 1 and 100 items in them at any given time.
I'm not sure how you check the results (same session or not). Do you perform commit somewhere? There are some specifics with global temp tables (there is option whether data is purged after commit or not). You may wish to initially try with permanent one until you sort out the problem.
It may be useful if you add some logging (e.g. to another table). E.g. rootDirList.length may be a good indicator to check.
Some other remarks:
The /* Do nothing */ branches in your if statements are adding additional noise. Good to remove them.
Perhaps would be better to use .isDirectory() if you want to check if the paths is a directory (instead of isFile).
There were a few errors in this code that prevented it from writing to the database. Based on Yavor's suggestion of writing String variables to a temp table I was able to find that I had duplicated "/" on the file path e.g. (/transfer_edi/hs122//Acctg). I also found I had an incorrect data type on one of my columns in my data table that I was writing too. I also switched to a regular table instead of a global temp table which was deleting after commit. Again thanks Yavor. Regardless of all that I ended up re-writing the entire thing. I realized that I needed to traverse down the directory structure to get all the files so here is the final code that worked for me. Again i'm not a java guy so i'm sure this could be done better.
This link helped me quite a bit
http://rosettacode.org/wiki/Walk_a_directory/Recursively#Java
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED BALT_CHECK."WebDocs" AS
import java.io.*;
import java.sql.*;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.lang.String;
public class WebDocs
{
public static long fileID;
public static void GetDocs(String rootdirectory) throws SQLException
{
stepinto(rootdirectory);
}
public static void stepinto(String rootdirectory) throws SQLException
{
File path = new File( rootdirectory );
String[] DirList = path.list();
for( int x = 0; x < DirList.length; x++)
{
String newPath = rootdirectory + DirList[x];
if (newPath != null) {
File f = new File(newPath);
if (f.isDirectory()) {
GetDocs(newPath +"/");
}
if (f.isFile()){
WriteFile(f);
}else{
}
}
}
}
public static void WriteFile(File file) throws SQLException
{
String fileName;
String filePath;
String elementID;
long len;
Date date;
String sqlDate;
SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss");
fileID = fileID + 1;
elementID = String.valueOf(fileID);
fileName = file.getName();
filePath = file.getPath();
len = file.length();
date = new Date(file.lastModified());
sqlDate = df.format(date);
#sql { INSERT INTO WEB_STATICDOCS (ID, FILE_NAME, FILE_SIZE, CREATE_DATE, FILE_PATH)
VALUES (:elementID, :fileName, :len, to_date(:sqlDate, 'YYYY-MM-DD HH24:MI:SS'), :filePath) };
}
}
/
Oracle Stored Procedure
CREATE OR REPLACE procedure BALT_CHECK.getWebDocs( p_directory in varchar2)
as language java
name 'WebDocs.GetDocs( java.lang.String )';
/
Calling the stored Procedure
exec getWebDocs( '/transfer_edi/hs122/');
I want to create a WEKA Java program that reads a group of newly created data that will be fed to a premade model from the GUI version.
Here is the program:
import java.util.ArrayList;
import weka.classifiers.Classifier;
import weka.core.Attribute;
import weka.core.DenseInstance;
import weka.core.Instances;
import weka.core.Utils;
public class UseModelWithData {
public static void main(String[] args) throws Exception {
// load model
String rootPath = "G:/";
Classifier classifier = (Classifier) weka.core.SerializationHelper.read(rootPath+"j48.model");
// create instances
Attribute attr1 = new Attribute("age");
Attribute attr2 = new Attribute("menopause");
Attribute attr3 = new Attribute("tumor-size");
Attribute attr4 = new Attribute("inv-nodes");
Attribute attr5 = new Attribute("node-caps");
Attribute attr6 = new Attribute("deg-malig");
Attribute attr7 = new Attribute("breast");
Attribute attr8 = new Attribute("breast-quad");
Attribute attr9 = new Attribute("irradiat");
Attribute attr10 = new Attribute("Class");
ArrayList<Attribute> attributes = new ArrayList<Attribute>();
attributes.add(attr1);
attributes.add(attr2);
attributes.add(attr3);
attributes.add(attr4);
attributes.add(attr5);
attributes.add(attr6);
attributes.add(attr7);
attributes.add(attr8);
attributes.add(attr9);
attributes.add(attr10);
// predict instance class values
Instances testing = new Instances("Test dataset", attributes, 0);
// add data
double[] values = new double[testing.numAttributes()];
values[0] = testing.attribute(0).addStringValue("60-69");
values[1] = testing.attribute(1).addStringValue("ge40");
values[2] = testing.attribute(2).addStringValue("10-14");
values[3] = testing.attribute(3).addStringValue("15-17");
values[4] = testing.attribute(4).addStringValue("yes");
values[5] = testing.attribute(5).addStringValue("2");
values[6] = testing.attribute(6).addStringValue("right");
values[7] = testing.attribute(7).addStringValue("right_up");
values[8] = testing.attribute(0).addStringValue("yes");
values[9] = Utils.missingValue();
// add data to instance
testing.add(new DenseInstance(1.0, values));
// instance row to predict
int index = 10;
// perform prediction
double myValue = classifier.classifyInstance(testing.instance(10));
// get the name of class value
String prediction = testing.classAttribute().value((int) myValue);
System.out.println("The predicted value of the instance ["
+ Integer.toString(index) + "]: " + prediction);
}
}
My references include:
Using a premade WEKA model in Java
the WEKA Manual provided in the 3.7.10 version - 17.3 Creating datasets in memory
Creating a single instance for classification in WEKA
So far the part where I create a new Instance inside the script causes the following error:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 10, Size: 1
in the line
double myValue = classifier.classifyInstance(testing.instance(10));
I just want to use a latest row of instance values to a premade WEKA model. How do I solve this?
Resources
Program file
Arff file
j48.model
You have the error because you are trying to access the 11th instance and have only created one.
If you always want to access the last instance you might try the following:
double myValue = classifier.classifyInstance(testing.lastInstance());
Additionally, I don't believe that you are creating the instances you hope for. After looking at your provided ".arff" file, which I believe you are trying to mimic, I think you should proceed making instances as follows:
FastVector atts;
FastVector attAge;
Instances testing;
double[] vals;
// 1. set up attributes
atts = new FastVector();
//age
attAge = new FastVector();
attAge.addElement("10-19");
attAge.addElement("20-29");
attAge.addElement("30-39");
attAge.addElement("40-49");
attAge.addElement("50-59");
attAge.addElement("60-69");
attAge.addElement("70-79");
attAge.addElement("80-89");
attAge.addElement("90-99");
atts.addElement(new Attribute("age", attAge));
// 2. create Instances object
testing = new Instances("breast-cancer", atts, 0);
// 3. fill with data
vals = new double[testing.numAttributes()];
vals[0] = attAge.indexOf("10-19");
testing.add(new DenseInstance(1.0, vals));
// 4. output data
System.out.println(testing);
Of course I did not create the whole dataset, but the technique would be the same.