I am trying to implement a Prolog program that can interact with java. To do this I use JPL as the Prolog/Java interface.
I am looking for a mechanism that allows me to execute actions automatically when the conditions become true.
The conditions are also represented by predicates. I have tried to use the predefined predicate "when/2", the problem is that as specified in the documentation here, the condition must be one of these:
nonvar(X)
ground(X)
?=(X, Y)
(Cond1, Cond2)
(Cond2; Cond2)
The last two conditions seem the ones I should use, but I could not make them work.
What do I need to change to make make my own conditions ?
Please, consider J
as a local Prolog variable here.
:- use_module(library(jpl)).
:- use_module(library(when)).
should_engage(J) :-
jpl_get(J, 'shouldEngage', V),
V==true,
jpl_get(J, 'players', P),
jpl_call(P, 'canSeeEnemies', [], R),
R==true,
jpl_get(J, 'weaponry', W),
jpl_call(W, 'hasLoadedWeapon', [], R),
R==true.
call_java(J) :-
jpl_call(J, 'stateEngage', [], R).
when(should_engage(X), call_java(X)).
When/1 is part of the coroutining infrastructure that triggers actions on variable instantiation. It uses attributed variables in the background. So, if your
J
is normally a variable that can get bound at some time you can doOr
The first version will cause the instantiation of
X
to fail ifshould_engage/1
fails. The latter version not.If it is not the binding of a variable that may make
should_engage/1
true you'll need to find some other trigger or possibly have a thread that monitors the environment at intervals and propagates.Note that calling non-logical constructs from when/1 typically makes little sense because Prolog's computation may backtrack, unbinding
X
and rebinding it again to the same or a different value and thus your propagation may be called many times with different or the same value.