Logic and control

These predicates are simply derived from the control constructs and provide additional facilities for affecting the control flow during execution.

1. \+/1 (not provable)

'\\+'(Term) is true iff call(Term) is false.

Templates and modes for the predicate are as follows:

'\\+'(@callable_term)

Note that \+ is a predefined operator.

1.1 Example tests

Let's start with some simple tests verifying success or failure of single goals.

jTrolog.engine.SimpleGoalFixture
goalsuccess()exception()
'\\+'(true). false no exception
\+(!). false no exception
'\\+'((!, fail)). true no exception
'\\+'(4 = 5). true no exception
\+(3). false type_error(callable, 3)
'\\+'(X). false instantiation_error
\+(X = f(X)).

Now we run some tests also verifying the unification for some of the variables in goals.

First of all, let's start an appropriate fixture containing an engine.

fit.ActionFixture
start jTrolog.engine.EngineFixture

Then, ask the engine to solve a query, and check variable bindings.

fit.ActionFixture
enter query (X=1; X=2), \+((!, fail)).
check hasSolution true
enter variable X
check binding 1
check hasAnotherSolution true
enter variable X
check binding 2

The remaining tests cover the cases when an error or exception is thrown by the engine while solving a query.

jTrolog.engine.PrologActionFixture
enter query \+(3).
check hasSolution false
check exception type_error(callable, 3)
enter query '\\+'(X).
check hasSolution false
check exception instantiation_error

2. once/1

once(Term) is true iff call(Term) is true.

once(Term) behaves as call(Goal) but it is not re-executable.

Templates and modes for the predicate are as follows:

once(+callable_term)

1.1 Example tests

Let's start with some simple tests verifying success or failure of single goals.

jTrolog.engine.SimpleGoalFixture
goalsuccess()exception()
once(!). true no exception
once(repeat). true no exception
once(fail). false no exception
once(X = f(X)).

Now we run some tests also verifying the unification for some of the variables in goals.

First of all, let's start an appropriate fixture containing an engine.

fit.ActionFixture
start jTrolog.engine.EngineFixture

Then, ask the engine to solve a query, and check variable bindings.

fit.ActionFixture
enter query once(!), (X=1; X=2).
check hasSolution true
enter variable X
check binding 1
check hasAnotherSolution true
enter variable X
check binding 2

Note that there are no tests covering the cases when an error or exception is thrown by the engine while solving a query using this predicate.

3. repeat/0

repeat is true.

Templates and modes for the predicate are as follows:

repeat

Note that repeat is re-executable.

3.1 Example tests

Let's start with some simple tests verifying success or failure of single goals.

jTrolog.engine.SimpleGoalFixture
goalsuccess()exception()
repeat, !, fail. false no exception

4. cut/0

cut is true.

Cut or !/0 is a sneaky devil. Be aware of how it handles different points on the stack. When cut is called, it is a leaf node on the solution tree. Cut goes 'upwards' in the resolution tree. When it reaches the next node, it removes all alternatives in all the branches of this node (in practice previous alternatives on the left branch). If cut, encounters a 'transparent' node, it will continue upwards. If cut encounters a non-transparent node, it will cut on this node, but then stop. A transparent node is either: a) a comma or b) a semicolon that does not have '->'/2 as its left node (Prolog 'if').

cut !/0

4.1 ISO tests

Simple and more complex tests verifying success or failure of single goals and that the resolution tree has been traversed correctly.

jTrolog.engine.PrologActionFixture
enter theory twice(!) :- write('C').
twice(true) :- write('Moss').
goal((twice(_), !)).
goal(write('Three')).
enter query !.
check hasSolutionWithOutput true
enter query (!, fail ; true).
check hasSolutionWithOutput fail
enter query (call(!), fail ; true).
check hasSolutionWithOutput true
enter query twice(_), !, write('Forwards'), fail.
check hasSolutionWithOutput false
check output CForwards
enter query (! ; write('No')), write('Cut disjunction'), fail.
check hasSolutionWithOutput false
check output Cut disjunction
enter query twice(_), (write('No') ; !), write('Cut'), fail.
check hasSolutionWithOutput false
check output CNoCutCut
enter query twice(_), (!, fail; write('No')).
check hasSolutionWithOutput false
check output C
enter query twice(X), call(X), write('Forwards'), fail.
check hasSolutionWithOutput false
check output CForwardsMossForwards
enter query goal(X), call(X), write('Forwards'), fail.
check hasSolutionWithOutput false
check output CForwardsThreeForwards
enter query twice(_), \+(\+(!)), write('Forwards'), fail.
check hasSolutionWithOutput false
check output CForwardsMossForwards
enter query twice(_), once(!), write('Forwards'), fail.
check hasSolutionWithOutput false
check output CForwardsMossForwards
enter query twice(_), call(!), write('Forwards'), fail.
check hasSolutionWithOutput false
check output CForwardsMossForwards

The results of the tests for Logic and control are as follows:

fit.Summary