package alice.tuprolog;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import alice.tuprolog.event.OutputEvent;
import alice.tuprolog.event.OutputListener;
public class RetractTest {
Prolog engine;
String output;
@Before
public void setUp() {
engine = new Prolog();
try {
engine.setTheory(new Theory(
":- dynamic(legs/2).\n" +
"legs(A, 4) :- animal(A).\n" +
"legs(octopus, 8).\n" +
"legs(A, 6) :- insect(A).\n" +
"legs(spider, 8).\n" +
"legs(B, 2) :- bird(B).\n" +
":- dynamic(insect/1).\n" +
"insect(ant).\n" +
"insect(bee).\n" +
":- dynamic(foo/1).\n" +
"foo(X) :- call(X), call(X).\n" +
"foo(X) :- call(X) -> call(X)."));
} catch (InvalidTheoryException e) {
}
}
@Test public void retractLegs() throws PrologException {
String fact = "retract(legs(octopus, 8)).";
SolveInfo solution = engine.solve(fact);
assertTrue(solution.isSuccess());
String missing = "retract(legs(spider, 6)).";
solution = engine.solve(missing);
assertFalse(solution.isSuccess());
String rule = "retract((legs(X, 2) :- T)).";
solution = engine.solve(rule);
assertTrue(solution.isSuccess());
assertEquals(new Struct("bird", new Var("X")), solution.getTerm("T"));
String ruleWithAlternatives = "retract((legs(X, Y) :- Z)).";
solution = engine.solve(ruleWithAlternatives);
assertEquals(new Int(4), solution.getTerm("Y"));
assertEquals(new Struct("animal", new Var("X")), solution.getTerm("Z"));
solution = engine.solveNext();
assertEquals(new Int(6), solution.getTerm("Y"));
assertEquals(new Struct("insect", new Var("X")), solution.getTerm("Z"));
solution = engine.solveNext();
assertEquals(new Struct("spider"), solution.getTerm("X"));
assertEquals(new Int(8), solution.getTerm("Y"));
assertEquals(Struct.TRUE, solution.getTerm("Z"));
solution = engine.solveNext();
assertFalse(solution.isSuccess());
solution = engine.solve(rule);
assertFalse(solution.isSuccess());
}
@Test(expected=AssertionError.class)
public void retractInsect() throws PrologException {
output = "";
engine.addOutputListener(new OutputListener() {
@Override
public void onOutput(OutputEvent e) {
output += e.getMsg();
}
});
String goal = "retract(insect(I)), write(I), retract(insect(bee)), fail.";
SolveInfo solution = engine.solve(goal);
assertFalse(solution.isSuccess());
assertEquals("antbee", output);
engine.removeAllOutputListeners();
}
@Test public void retractFoo() throws PrologException {
String goal = "retract((foo(A) :- A, call(A))).";
SolveInfo solution = engine.solve(goal);
assertFalse(solution.isSuccess());
goal = "retract((foo(C) :- A -> B)).";
solution = engine.solve(goal);
assertTrue(solution.isSuccess());
Struct callc = new Struct("call", new Var("C"));
assertEquals(callc, solution.getTerm("A"));
assertEquals(callc, solution.getTerm("B"));
}
@Test public void headAsVariable() throws PrologException {
String goal = "retract((X :- in_eec(Y))).";
SolveInfo solution = engine.solve(goal);
assertFalse(solution.isSuccess());
// TODO Should throw instantiation_error
// FIXME Actually throws a RuntimeException
}
@Test public void headAsNumber() throws PrologException {
String goal = "retract((4 :- X)).";
SolveInfo solution = engine.solve(goal);
assertFalse(solution.isSuccess());
// TODO Should throw type_error(callable, 4)
}
@Test public void retractStaticProcedure() throws PrologException {
String goal = "retract((atom(_) :- X == '[]')).";
SolveInfo solution = engine.solve(goal);
assertFalse(solution.isSuccess());
// TODO Should throw permission_error(modify, static_procedure, atom/1)
}
@After
public void tearDown() {
engine.clearTheory();
}
}