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 do
...,
when(nonvar(X), propagate(X)).
propagate(X) :-
should_engage(X),
call_java(X).
Or
propagate(X) :-
( should_engage(X)
-> call_java(X)
; true
).
The first version will cause the instantiation of X
to fail if should_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.