package com.igormaznitsa.prol.test;
import com.igormaznitsa.prol.exceptions.ProlCustomErrorException;
import com.igormaznitsa.prol.exceptions.ProlException;
import com.igormaznitsa.prol.exceptions.ProlInstantiationErrorException;
import com.igormaznitsa.prol.io.DefaultProlStreamManagerImpl;
import com.igormaznitsa.prol.logic.Goal;
import com.igormaznitsa.prol.logic.ProlContext;
import com.igormaznitsa.prol.parser.ProlConsult;
import junit.framework.TestCase;
import org.junit.Test;
public class SomeFromISOTest extends TestCase {
@Test
public void testAbolish() throws Exception {
//[abolish(abolish/1), permission_error(modify,static_procedure,abolish/1)].
//[abolish(foo/a), type_error(integer,a)].
//[abolish(foo/(-1)), domain_error(not_less_than_zero,-1)].
//[(current_prolog_flag(max_arity,A), X is A + 1, abolish(foo/X)), representation_error(max_arity)].
//[abolish(5/2), type_error(atom,5)].
checkOnce("assert(test(1)),test(X),X==1,abolish(test/1),\\+ test(_).", true);
checkException("abolish(abolish/1).");
checkException("abolish(foo/a).");
//checkException("abolish(foo/(-1))."); // prol doesn't check the right part
//checkException("abolish(5/2)."); // prol just remove record at vocabulary for such signature
}
@Test
public void testRetract() throws Exception {
//[retract((4 :- X)), type_error(callable, 4)].
//[retract((atom(_) :- X == '[]')),permission_error(modify,static_procedure,atom/1)].
checkException("retract((4:-X)).");
checkException("retract((atom(_):-X=='[]')).");
}
@Test
public void testFindAll() throws Exception {
//[findall(X,(X=1 ; X=2),S),[[S <-- [1,2]]]].
//[findall(X+Y,(X=1),S),[[S <-- [1+_]]]].
//[findall(X,fail,L),[[L <-- []]]].
//[findall(X,(X=1 ; X=1),S),[[S <-- [1,1]]]].
//[findall(X,(X=2 ; X=1),[1,2]), failure].
//[findall(X,(X=1 ; X=2),[X,Y]), [[X <-- 1, Y <-- 2]]].
//[findall(X,Goal,S),instantiation_error]. % Culprit Goal
//[findall(X,4,S),type_error(callable, 4)].
//[findall(X,call(1),S),type_error(callable, 1)].
checkOnceVar("findall(X,(X=1;X=2),S).", "S", "[1,2]");
checkOnceVar("findall(X+Y,(X=1),S).", "S", "[1 + Y]"); // changes
checkOnceVar("findall(X,fail,L).", "L", "[]");
checkOnceVar("findall(X,(X=1;X=1),S).", "S", "[1,1]");
checkOnce("findall(X,(X=2;X=1),[1,2]).", false);
final Goal goal = proveGoal("findall(X,(X=1;X=2),[X1,Y1])."); // changed from original because at Prol all variables linked by their names inside a goal, so that it is not a bug, it is a feature
assertEquals(goal.getVarAsText("X1"), "1");
assertEquals(goal.getVarAsText("Y1"), "2");
assertNull(goal.solve());
checkException("findall(X,Goal,S).");
checkException("findall(X,4,S).");
checkException("findall(X,call(1),S).");
}
@Test
public void testAssertZ() throws Exception {
//[assertz((foo(X) :- X -> call(X))), success].
//[assertz(_), instantiation_error].
//[assertz(4), type_error(callable, 4)].
//[assertz((foo :- 4)), type_error(callable, 4)].
//[assertz((atom(_) :- true)), permission_error(modify,static_procedure,atom/1)].
checkOnce("assertz((foo(X):-X->call(X))).", true);
checkException("assertz(_).");
checkException("assertz(4).");
//checkException("assertz((foo:-4)).");// prol doesn't check the term fully
checkException("assertz((atom(_):-true)).");
}
@Test
public void testAssertA() throws Exception {
//[(asserta((bar(X) :- X)), clause(bar(X), B)), [[B <-- call(X)]]].
//[asserta(_), instantiation_error].
//[asserta(4), type_error(callable, 4)].
//[asserta((foo :- 4)), type_error(callable, 4)].
//[asserta((atom(_) :- true)), permission_error(modify,static_procedure,atom/1)].
checkOnceVar("asserta(bar(X):-call(X)),clause(bar(X),B).", "B", "call(X)");
checkException("asserta(_).");
checkException("asserta(4).");
//checkException("asserta((foo:-4)).");
checkException("asserta((atom(_):-true)).");
}
@Test
public void testNumberCodes() throws Exception {
//[number_codes(33,L), [[L <-- [0'3,0'3]]]].
//[number_codes(33,[0'3,0'3]), success].
//[number_codes(33.0,L), [[L <-- [51,51,46,48]]]].
//[number_codes(33.0,[0'3,0'.,0'3,0'E,0'+,0'0,0'1]), success].
//[number_codes(A,[0'-,0'2,0'5]), [[A <-- (-25)]]].
//[number_codes(A,[0' ,0'3]), [[A <-- 3]]].
//[number_codes(A,[0'0,0'x,0'f]), [[A <-- 15]]].
//[number_codes(A,[0'0,39,0'a]), [[A <-- 97]]].
//[number_codes(A,[0'4,0'.,0'2]), [[A <-- 4.2]]].
//[number_codes(A,[0'4,0'2,0'.,0'0,0'e,0'-,0'1]), [[A <-- 4.2]]].
//
//[number_codes(A,L), instantiation_error].
//[number_codes(a,L), type_error(number,a)].
//[number_codes(A,4), type_error(list,4)].
//[number_codes(A,[ 0'1, 0'2, 1000]), representation_error(character_code)]. % 1000 not a code
checkOnceVar("number_codes(33,L).", "L", "[" + (int) '3' + "," + (int) '3' + "]");
checkOnce("number_codes(33,[51,51]).", true);
checkOnceVar("number_codes(33.0,L).", "L", "[51,51,46,48]");
checkOnce("number_codes(33.0,[" + (int) '3' + ',' + (int) '.' + ',' + (int) '3' + ',' + (int) 'E' + ',' + (int) '0' + ',' + (int) '1' + "]).", true);
checkOnceVar("number_codes(A,[" + (int) '-' + ',' + (int) '2' + ',' + (int) '5' + "]).", "A", "-25");
checkOnceVar("number_codes(A,[" + (int) ' ' + ',' + (int) '3' + "]).", "A", "' 3'");
checkOnceVar("number_codes(A,[" + (int) '0' + ',' + (int) 'x' + ',' + (int) 'f' + "]).", "A", "15");
checkOnceVar("number_codes(A,[" + (int) '4' + ',' + (int) '.' + ',' + (int) '2' + "]).", "A", "4.2");
// checkOnceVar("number_codes(A,["+(int)'4'+','+(int)'2'+','+(int)'.'+','+(int)'0'+','+(int)'e'+','+(int)'-'+','+(int)'1'+"]).","A","4.2"); // prol returns 42.0e-1 because it is based on Java number output
}
@Test
public void testTermLtEq() throws Exception {
//['@=<'(1.0,1), success].
//['@=<'(aardvark,zebra), success].
//['@=<'(short,short), success].
//['@=<'(short,shorter), success].
//['@=<'(foo(b),foo(a)), failure].
//['@=<'(X,X), success].
//['@=<'(foo(a,X),foo(b,Y)), success].
checkOnce("'@=<'(1.0,1).", true);
checkOnce("'@=<'(aardvark,zebra).", true);
checkOnce("'@=<'(short,short).", true);
checkOnce("'@=<'(short,shorter).", true);
checkOnce("'@=<'(foo(b),foo(a)).", false);
checkOnce("'@=<'(X,X).", true);
checkOnce("'@=<'(foo(a,X),foo(b,Y)).", true);
}
@Test
public void testTermLt() throws Exception {
//['@<'(1.0,1), success].
//['@<'(aardvark,zebra), success].
//['@<'(short,short), failure].
//['@<'(short,shorter), success].
//['@<'(foo(b),foo(a)), failure].
//['@<'(X,X), failure].
//['@<'(foo(a,X),foo(b,Y)), success].
checkOnce("'@<'(1.0,1).", false);// ???
checkOnce("'@<'(aardvark,zebra).", true);
checkOnce("'@<'(short,short).", false);
checkOnce("'@<'(short,shorter).", true);
checkOnce("'@<'(foo(b),foo(a)).", false);
checkOnce("'@<'(X,X).", false);
checkOnce("'@<'(foo(a,X),foo(b,Y)).", true);
}
@Test
public void testTermGtEqu() throws Exception {
//['@>='(1.0,1), failure].
//['@>='(aardvark,zebra), failure].
//['@>='(short,short), success].
//['@>='(short,shorter), failure].
//['@>='(foo(b),foo(a)), success].
//['@>='(X,X), success].
//['@>='(foo(a,X),foo(b,Y)), failure].
checkOnce("'@>='(1.0,1).", true);// ???
checkOnce("'@>='(aardvark,zebra).", false);
checkOnce("'@>='(short,short).", true);
checkOnce("'@>='(short,shorter).", false);
checkOnce("'@>='(foo(b),foo(a)).", true);
checkOnce("'@>='(X,X).", true);
checkOnce("'@>='(foo(a,X),foo(b,Y)).", false);
}
@Test
public void testTermGt() throws Exception {
//['@>'(1.0,1), failure].
//['@>'(aardvark,zebra), failure].
//['@>'(short,short), failure].
//['@>'(short,shorter), failure].
//['@>'(foo(b),foo(a)), success].
//['@>'(X,X), failure].
//['@>'(foo(a,X),foo(b,Y)), failure].
checkOnce("'@>'(1.0,1).", false);
checkOnce("'@>'(aardvark,zebra).", false);
checkOnce("'@>'(short,short).", false);
checkOnce("'@>'(short,shorter).", false);
checkOnce("'@>'(foo(b),foo(a)).", true);
checkOnce("'@>'(X,X).", false);
checkOnce("'@>'(foo(a,X),foo(b,Y)).", false);
}
@Test
public void testEqu() throws Exception {
//['=='(1,1), success].
//['=='(X,X), success].
//['=='(1,2), failure].
//['=='(X,1), failure].
//['=='(X,Y), failure].
//['=='(_,_), failure].
//['=='(X,a(X)), failure].
//['=='(f(a),f(a)), success].
checkOnce("'=='(1,1).", true);
checkOnce("'=='(X,X).", true);
checkOnce("'=='(1,2).", false);
checkOnce("'=='(X,1).", false);
checkOnce("'=='(X,Y).", false);
checkOnce("'=='(_,_).", false);
checkOnce("'=='(X,a(X)).", false);
checkOnce("'=='(f(a),f(a)).", true);
}
@Test
public void testDiff() throws Exception {
//['\\=='(1,1), failure].
//['\\=='(X,X), failure].
//['\\=='(1,2), success].
//['\\=='(X,1), success].
//['\\=='(X,Y), success].
//['\\=='(_,_), success].
//['\\=='(X,a(X)), success].
//['\\=='(f(a),f(a)), failure].
checkOnce("'\\\\=='(1,1).", false);
checkOnce("'\\\\=='(X,X).", false);
checkOnce("'\\\\=='(1,2).", true);
checkOnce("'\\\\=='(X,1).", true);
checkOnce("'\\\\=='(X,Y).", true);
checkOnce("'\\\\=='(_,_).", true);
checkOnce("'\\\\=='(X,a(X)).", true);
checkOnce("'\\\\=='(f(a),f(a)).", false);
}
@Test
public void testLtEqu() throws Exception {
//['=<'(0,1), success].
//['=<'(1.0,1), success].
//['=<'(3*2,7-1), success].
//['=<'(X,5), instantiation_error].
//['=<'(2 + floot(1),5), type_error(evaluable, floot/1)].
checkOnce("'=<'(0,1).", true);
checkOnce("'=<'(1.0,1).", true);
checkOnce("'=<'(3*2,7-1).", true);
checkException("'=<'(X,5).");
checkException("'=<'(2+floot(1),5).");
}
@Test
public void testLt() throws Exception {
//['<'(0,1), success].
//['<'(1.0,1), failure].
//['<'(3*2,7-1), failure].
//['<'(X,5), instantiation_error].
//['<'(2 + floot(1),5), type_error(evaluable, floot/1)].
checkOnce("'<'(0,1).", true);
checkOnce("'<'(1.0,1).", false);
checkOnce("'<'(3*2,7-1).", false);
checkException("'<'(X,5).");
checkException("'<'(2+floot(1),5).");
}
@Test
public void testGtEqu() throws Exception {
//['>='(0,1), failure].
//['>='(1.0,1), success].
//['>='(3*2,7-1), success].
//['>='(X,5), instantiation_error].
//['>='(2 + floot(1),5), type_error(evaluable, floot/1)].
checkOnce("'>='(0,1).", false);
checkOnce("'>='(1.0,1).", true);
checkOnce("'>='(3*2,7-1).", true);
checkException("'>='(X,5).");
checkException("'>='(2+floot(1),5).");
}
@Test
public void testGt() throws Exception {
//['>'(0,1), failure].
//['>'(1.0,1), failure].
//['>'(3*2,7-1), failure].
//['>'(X,5), instantiation_error].
//['>'(2 + floot(1),5), type_error(evaluable, floot/1)].
checkOnce("'>'(0,1).", false);
checkOnce("'>'(1.0,1).", false);
checkOnce("'>'(3*2,7-1).", false);
checkException("'>'(X,5).");
checkException("'>'(2+floot(1),5).");
}
@Test
public void testArithEq() throws Exception {
//['=:='(0,1), failure].
//['=:='(1.0,1), success].
//['=:='(3 * 2,7 - 1), success].
//['=:='(N,5), instantiation_error].
//['=:='(floot(1),5), type_error(evaluable, floot/1)].
//[0.333 =:= 1/3, failure].
checkOnce("'=:='(0,1).", false);
checkOnce("'=:='(1.0,1).", true);
checkOnce("'=:='(3*2,7-1).", true);
checkException("'=:='(N,5).");
checkException("'=:='(floot(1),5).");
checkOnce("0.333=:=1/3.", false);
}
@Test
public void testArithDiff() throws Exception {
//['=\\='(0,1), success].
//['=\\='(1.0,1), failure].
//['=\\='(3 * 2,7 - 1), failure].
//['=\\='(N,5), instantiation_error].
//['=\\='(floot(1),5), type_error(evaluable, floot/1)].
checkOnce("'=\\\\='(0,1).", true);
checkOnce("'=\\\\='(1.0,1).", false);
checkOnce("'=\\\\='(3*2,7-1).", false);
checkException("'=\\\\='(N,5).");
checkException("'=\\\\='(floot(1),5).");
}
@Test
public void testCopyTerm() throws Exception {
//[copy_term(X,Y), success].
//[copy_term(X,3), success].
//[copy_term(_,a), success].
//[copy_term(a+X,X+b),[[X <-- a]]].
//[copy_term(_,_), success].
//[copy_term(X+X+Y,A+B+B),[[B <-- A]]].
//[copy_term(a,a), success].
//[copy_term(a,b), failure].
//[copy_term(f(a),f(X)),[[X <-- a]]].
//[(copy_term(a+X,X+b),copy_term(a+X,X+b)), failure].
checkOnce("copy_term(X,Y).", true);
checkOnce("copy_term(X,3).", true);
checkOnce("copy_term(_,3).", true);
checkOnceVar("copy_term(a+X,X+b).", "X", "'a'");
checkOnce("copy_term(_,_).", true);
//checkOnceVar("copy_term(X+X+Y,A+B+B).","B","A"); // prol links variables as objects so it is no so easy to say which variable is parent
checkOnce("copy_term(a,a).", true);
checkOnce("copy_term(a,b).", false);
checkOnceVar("copy_term(f(a),f(X)).", "X", "'a'");
checkOnce("copy_term(a+X,X+b),copy_term(a+X,X+b).", false);
}
@Test
public void testClause() throws Exception {
//[clause(x,Body), failure].
//[clause(_,B), instantiation_error].
//[clause(4,B), type_error(callable,4)].
//[clause(f(_),5), type_error(callable,5)].
//[clause(atom(_),Body), permission_error(access,private_procedure,atom/1)].
checkOnce("clause(x,Body).", false);
checkException("clause(_,B).");
checkException("clause(4,B).");
checkException("clause(f(_),5).");
checkException("clause(atom(_),Body).");
}
@Test
public void testCall() throws Exception {
//[call(!),success].
//[call(fail), failure].
//[call((fail, X)), failure].
//[call((fail, call(1))), failure].
//[call((write(3), X)), instantiation_error].
//[call((write(3), call(1))), type_error(callable,1)].
//[call(X), instantiation_error].
//[call(1), type_error(callable,1)].
//[call((fail, 1)), type_error(callable,(fail,1))].
//[call((write(3), 1)), type_error(callable,(write(3), 1))].
//[call((1; true)), type_error(callable,(1; true))].
checkOnce("call(!).", true);
checkOnce("call(fail).", false);
checkOnce("call((fail,X)).", false);
checkOnce("call((fail,call(1))).", false);
checkException("call((write(3),X)).");
checkException("call((write(3),call(1))).");
checkException("call(X).");
checkException("call(1).");
// checkException("call((fail,1))."); // it iw not working at proll because prol checks sequentially and fail will be the first one
checkException("call([fail]).");
checkException("call((write(3),1)).");
checkException("call((1;true)).");
}
@Test
public void testAtomCodes() throws Exception {
checkOnceVar("atom_codes('',L).", "L", "[]");
checkOnceVar("atom_codes([],L).", "L", "[" + (int) '[' + ',' + (int) ']' + "]");
checkOnceVar("atom_codes('\\'',L).", "L", "[39]");
checkOnceVar("atom_codes('iso',L).", "L", "[" + (int) 'i' + ',' + (int) 's' + ',' + (int) 'o' + ']');
checkOnceVar("atom_codes(A,[" + (int) 'p' + ',' + (int) 'r' + ',' + (int) 'o' + ',' + (int) 'l' + ',' + (int) 'o' + ',' + (int) 'g' + "]).", "A", "'prolog'");
checkOnceVar("atom_codes('North',[" + (int) 'N' + '|' + "L]).", "L", "[" + (int) 'o' + ',' + (int) 'r' + ',' + (int) 't' + ',' + (int) 'h' + ']');
checkOnce("atom_codes('iso',[" + (int) 's' + ',' + (int) 'o' + "]).", false);
checkException("atom_codes(A,L).");
checkException("atom_codes(f(a),L).");
checkException("atom_codes(A," + (int) 'x' + ").");
checkException("atom_codes(A,[" + (int) 'i' + ',' + (int) 's' + ",1.1]).");
}
@Test
public void testCharCode() throws Exception {
//[char_code(Char,0'c),[[Char <-- c]]].
//[char_code(Char,163),[[Char <-- '\xa3\']]].
checkOnceVar("char_code(a,Code).", "Code", (int) 'a');
checkOnceVar("char_code(Char,99).", "Char", "'c'");
checkOnce("char_code(b,98).", true);
checkOnce("char_code(b,4).", false);
checkException("char_code('ab',Code).");
checkException("char_code(a,x).");
checkException("char_code(Char,Code).");
checkException("char_code(Char,-2).");
}
@Test
public void testAtomChars() throws Exception {
checkOnceVar("atom_chars('',L).", "L", "[]");
checkOnceVar("atom_chars([],L).", "L", "['[',']']");
checkOnceVar("atom_chars('iso',L).", "L", "['i','s','o']");
checkOnceVar("atom_chars(A,['p','r','o','l','o','g']).", "A", "'prolog'");
checkOnceVar("atom_chars('North',['N'|X]).", "X", "['o','r','t','h']");
checkOnce("atom_chars('iso',['i','s']).", false);
checkException("atom_chars(A,L).");
checkException("atom_chars(A,[a,E,c]).");
checkException("atom_chars(A,[a,b|L]).");
checkException("atom_chars(f(a),L).");
checkException("atom_chars(A,iso).");
checkException("atom_chars(A,[a,f(b)]).");
checkException("atom_chars(X,['1','2']),Y is X+1.");
}
@Test
public void testFunctor() throws Exception {
checkOnce("functor(foo(a,b,c),3).", true);
Goal goal = proveGoal("functor(foo(a,b,c),X,Y).");
assertEquals(goal.getVarAsText("X"), "'foo'");
assertEquals(goal.getVarAsNumber("Y"), 3);
assertNull(goal.solve());
checkOnceVar("functor(X,foo,3).", "X", "foo(_,_,_)");
checkOnceVar("functor(X,foo,0).", "X", "foo");
goal = proveGoal("functor(mats(A,B),A,B).");
assertEquals(goal.getVarAsText("A"), "'mats'");
assertEquals(goal.getVarAsNumber("B"), 2);
assertNull(goal.solve());
checkOnce("functor(foo(a),foo,2).", false);
checkOnce("functor(foo(a),fo,1).", false);
goal = proveGoal("functor(1,X,Y).");
assertEquals(goal.getVarAsNumber("X"), 1);
assertEquals(goal.getVarAsNumber("Y"), 0);
assertNull(goal.solve());
checkOnceVar("functor(X,1.1,0).", "X", "1.1");
checkOnce("functor([_|_],'.',2).", true);
checkOnce("functor([],[],0).", true);
checkException("functor(X,Y,3).");
checkException("functor(X,foo,N).");
checkException("functor(X,foo,a).");
checkException("functor(F,1.5,1).");
checkException("functor(F,foo(a),1).");
checkException("functor(T,foo,-1).");
}
@Test
public void testNotProvable() throws Exception {
checkOnce("\\+(true).", false);
checkOnce("\\+(!).", false);
checkOnce("\\+((!,fail)).", true);
checkOnceVar("((X=1;X=2),\\+((!,fail))).", "X", 1, 2);
checkOnce("\\+(4=5).", true);
checkException("\\+(3).");
checkException("\\+(X).");
}
@Test
public void testOnce() throws Exception {
checkOnce("once(!).", true);
checkOnceVar("once(!),(X=1;X=2).", "X", 1, 2);
checkOnce("once(repeat).", true);
checkOnce("once(fail).", false);
checkException("once(3).");
checkException("once(X).");
}
@Test
public void testArg() throws Exception {
checkOnce("arg(1,foo(a,b),a).", true);
checkOnceVar("arg(1,foo(X,b),a).", "X", "'a'");
checkOnceVar("arg(1,foo(a,b),X).", "X", "'a'");
final Goal goal = proveGoal("arg(2,foo(a, f(X,b), c), f(a, Y)).");
assertEquals(goal.getVarAsText("X"), "'a'");
assertEquals(goal.getVarAsText("Y"), "'b'");
assertNull(goal.solve());
checkOnceVar("arg(1,foo(a(X),b),Y).", "Y", "a(X)");
checkOnce("arg(1,foo(a,b),b).", false);
checkOnce("arg(0,foo(a,b),foo).", false);
checkOnce("arg(3,foo(3,4),N).", false);
checkException("arg(X,foo(a,b),a).");
checkException("arg(1,X,a).");
checkException("arg(0,atom,a).");
checkException("arg(0,3,A).");
checkException("arg(-3,foo(a,b),A).");
checkException("arg(a,foo(a,b),X).");
}
@Test
public void testIs() throws Exception {
checkOnceVar("'is'(Result,3+11.0).", "Result", 14.0f);
Goal goal = proveGoal("X=1+2,'is'(Y,X*3).");
assertEquals(goal.getVarAsText("X"), "1 + 2");
assertEquals(goal.getVarAsNumber("Y"), 9);
assertNull(goal.solve());
checkException("'is'(foo,77).");
checkException("'is'(77,N).");
checkException("'is'(77,foo).");
}
@Test
public void testAtomLength() throws Exception {
checkOnceVar("atom_length('enchanted evening', N).", "N", 17);
checkOnceVar("atom_length('', N).", "N", 0);
checkException("atom_length(Atom, 4).");
checkOnce("atom_length('scarlet',5).", false);
checkException("atom_length(1.23,4).");
checkException("atom_length(atom,'4').");
}
@Test
public void testFloat() throws Exception {
checkOnce("float(3.3).", true);
checkOnce("float(-3.3).", true);
checkOnce("float(3).", false);
checkOnce("float(atom).", false);
checkOnce("float(X).", false);
}
@Test
public void testUnify() throws Exception {
checkOnce("'='(1,1).", true);
checkOnceVar("'='(X,1).", "X", 1);
checkOnceVar("Y=3,'='(X,Y).", "X", 3);
Goal goal = proveGoal("X=Y,'='(X,abc).");
assertEquals(goal.getVarAsText("X"), "'abc'");
assertEquals(goal.getVarAsText("Y"), "'abc'");
assertNull(goal.solve());
checkOnceVar("X=Y,'='(X,abc).", "Y", "'abc'");
goal = proveGoal("'='(f(X,def),f(def,Y)).");
assertEquals(goal.getVarAsText("X"), "'def'");
assertEquals(goal.getVarAsText("Y"), "'def'");
assertNull(goal.solve());
checkOnce("'='(1,2).", false);
checkOnce("'='(1,1.000001).", false);
checkOnce("'='(g(X),f(f(X))).", false);
checkOnce("'='(g(X),f(f(X))).", false);
checkOnce("'='(f(X,1),f(a(X))).", false);
checkOnce("'='(f(X,Y,X),f(a(X),a(Y),Y,2)).", false);
checkOnce("'='(f(X,Y,X),f(a(X),a(Y),Y,2)).", false);
goal = proveGoal("'='(f(A,B,C),f(g(B,B),g(C,C),g(D,D))).");
assertEquals(goal.getVarAsText("A"), "g(g(g(D,D),g(D,D)),g(g(D,D),g(D,D)))");
assertEquals(goal.getVarAsText("B"), "g(g(D,D),g(D,D))");
assertEquals(goal.getVarAsText("C"), "g(D,D)");
assertNull(goal.solve());
}
@Test
public void testTrueFail() throws Exception {
checkOnce("true.", true);
checkOnce("fail.", false);
}
@Test
public void testRepeat() throws Exception {
checkOnce("repeat,!,fail.", false);
}
@Test
public void testNotUnify() throws Exception {
checkOnce("'\\\\='(1,1).", false);
checkOnce("'\\\\='(X,1).", false);
checkOnce("'\\\\='(X,Y).", false);
checkOnce("'\\\\='(X,Y),'\\\\='(X,abc).", false);
checkOnce("'\\\\='(f(X,def),f(def,Y)).", false);
checkOnce("'\\\\='(1,2).", true);
checkOnce("'\\\\='(1,1.00001).", true);
checkOnce("'\\\\='(g(X),f(f(X))).", true);
checkOnce("'\\\\='(f(X,1),f(a(X))).", true);
checkOnce("'\\\\='(f(X,Y,X),f(a(X),a(Y),Y,2)).", true);
}
@Test
public void testNonVar() throws Exception {
checkOnce("nonvar(33.3).", true);
checkOnce("nonvar(false).", true);
checkOnce("nonvar(Foo).", false);
checkOnceVar("foo=Foo,nonvar(Foo).", "Foo", "'foo'");
checkOnce("nonvar(_).", false);
checkOnce("nonvar(a(b)).", true);
}
@Test
public void testCompound() throws Exception {
checkOnce("compound(33.3).", false);
checkOnce("compound(-33.3).", false);
checkOnce("compound(-a).", true);
checkOnce("compound(_).", false);
checkOnce("compound(a).", false);
checkOnce("compound(a(b)).", true);
checkOnce("compound([]).", false);
checkOnce("compound([a]).", true);
}
@Test
public void testAtomic() throws Exception {
checkOnce("atomic(atom).", true);
checkOnce("atomic(a(b)).", false);
checkOnce("atomic(Var).", false);
checkOnce("atomic([]).", true);
checkOnce("atomic(6).", true);
checkOnce("atomic(3.3).", true);
}
@Test
public void testAtom() throws Exception {
checkOnce("atom(atom).", true);
checkOnce("atom('string').", true);
checkOnce("atom(a(b)).", false);
checkOnce("atom(Var).", false);
checkOnce("atom([]).", true);
checkOnce("atom(6).", false);
checkOnce("atom(3.3).", false);
}
@Test
public void testInteger() throws Exception {
checkOnce("integer(3).", true);
checkOnce("integer(-3).", true);
checkOnce("integer(3.3).", false);
checkOnce("integer(X).", false);
checkOnce("integer(atom).", false);
}
@Test
public void testOr() throws Exception {
checkOnce("';'(true, fail).", true);
checkOnce("';'((!, fail), true).", false);
checkOnce("';'(!, call(3)).", true);
checkOnceVar("';'((X=1, !), X=2).", "X", 1);
checkOnceVar("';'(X=1, X=2).", "X", 1, 2);
}
@Test
public void testAnd() throws Exception {
checkOnce("','(X=1,var(X)).", false);
checkOnceVar("','(var(X),X=1).", "X", 1);
checkOnce("','(fail,call(3)).", false);
checkOnceVar("','(X=true,call(X)).", "X", "true");
checkOnce("','(nofoo(X), call(X)).", false);
}
@Test
public void testIfThenElse() throws Exception {
checkOnce("';'('->'(true, true), fail).", true);
checkOnce("';'('->'(fail, true), true).", true);
checkOnce("';'('->'(true, fail), fail).", false);
checkOnce("';'('->'(fail, true), fail).", false);
checkOnceVar("true->X=1;X=2.", "X", 1);
checkOnceVar("';'('->'(fail, X=1), X=2).", "X", 2);
checkOnceVar("';'('->'(true, ';'(X=1, X=2)), true).", "X", 1, 2);
checkOnceVar("';'('->'(';'(X=1, X=2), true), true).", "X", 1);
}
@Test
public void testIfThen() throws Exception {
checkOnce("'->'(true, true).", true);
checkOnce("'->'(true, fail).", false);
checkOnceVar("true -> X=1.", "X", 1);
checkOnceVar("'->'(';'(X=1, X=2), true).", "X", 1);
checkOnceVar("'->'(true, ';'(X=1, X=2)).", "X", 1, 2);
}
@Test
public void testCut() throws Exception {
checkOnce("!.", true);
checkOnce("(!,fail;true).", false);
checkOnce("call(!),fail;true.", true);
}
@Test
public void testNumber() throws Exception {
checkOnce("number(3).", true);
checkOnce("number(3.3).", true);
checkOnce("number(-3).", true);
checkOnce("number(a).", false);
checkOnce("number(X).", false);
}
@Test
public void testNumberChars() throws Exception {
checkOnceVar("number_chars(33,L).", "L", "['3','3']");
checkOnceVar("number_chars(33.0,L).", "L", "['3','3','.','0']");
checkOnceVar("number_chars(X,['3','.','3','E','+','0']).", "X", 3.3f);
checkOnce("number_chars(3.3,['3','.','3','E','+','0']).", true);
checkOnceVar("number_chars(A,['-','2','5']).", "A", -25);
checkOnceVar("number_chars(A,['\n',' ','3']).", "A", 3);
try {
checkOnce("number_chars(A,['3',' ']).", true);
}
catch (ProlCustomErrorException ex) {
assertEquals(ex.getAsStruct().getFunctor().getText(), "syntax_error");
}
checkOnceVar("number_chars(A,['4','.','2']).", "A", 4.2f);
checkOnceVar("number_chars(A,['4','2','.','0','e','-','1']).", "A", 4.2f);
checkOnceVar("number_chars(A,['0',x,f]).", "A", 15);
try {
checkOnce("number_chars(A,L).", true);
fail();
}
catch (ProlInstantiationErrorException ex) {
assertTrue(true);
}
catch (Throwable ex) {
fail();
}
//[number_chars(A,['0','''','A']), [[A <-- 65]]].
}
private void checkOnce(String goal, boolean result) throws Exception {
final ProlContext context = makeContext(goal);
final Goal thisGoal = new Goal(goal, context);
if (result) {
assertNotNull(thisGoal.solve());
assertNull(thisGoal.solve());
}
else {
assertNull(thisGoal.solve());
}
}
private void checkException(String goal) throws Exception {
final ProlContext context = makeContext(goal);
final Goal thisGoal = new Goal(goal, context);
try {
thisGoal.solve();
fail();
}
catch (ProlException ex) {
assertTrue(ex.toString(), true);
}
}
private Goal proveGoal(String goal) throws Exception {
final ProlContext context = makeContext(goal);
final Goal thisGoal = new Goal(goal, context);
assertNotNull(thisGoal.solve());
return thisGoal;
}
private void checkOnceVar(String goal, String var, Object... result) throws Exception {
final ProlContext context = makeContext(goal);
final Goal thisGoal = new Goal(goal, context);
for (Object res : result) {
assertNotNull(thisGoal.solve());
if (res instanceof Number) {
if (res instanceof Float) {
assertTrue(Float.compare(thisGoal.getVarAsNumber(var).floatValue(), (Float) res) == 0);
}
else {
assertEquals(thisGoal.getVarAsNumber(var), res);
}
}
else {
assertEquals(thisGoal.getVarAsText(var), res.toString());
}
}
assertNull(thisGoal.solve());
}
private ProlContext makeContext(final String knowledgeBase) throws Exception {
final ProlContext context = new ProlContext("PreparedGoal test", DefaultProlStreamManagerImpl.getInstance());
final ProlConsult consult = new ProlConsult(knowledgeBase, context);
consult.consult();
return context;
}
}