SWI-Prolog:如何在 when/2 中使用我自己的谓词作为条件

SWI-Prolog: How to use my own predicate as a condition in when/2

我正在尝试实现一个可以与 java 交互的 Prolog 程序。为此,我使用 JPL 作为 Prolog/Java 接口。

我正在寻找一种机制,使我能够在条件变为真时自动执行操作。

条件也由谓词表示。我已尝试使用预定义谓词 "when/2",问题是如文档 here 中指定的,条件必须是以下之一:

后两个条件似乎是我应该使用的条件,但我无法使它们起作用。

我需要更改什么才能满足自己的条件?

请将 J 视为局部 Prolog 变量。

:- 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 是触发变量实例化操作的协程基础结构的一部分。它在后台使用 属性变量 。所以,如果你的 J 通常是一个可以在某个时间绑定的变量

   ...,
   when(nonvar(X), propagate(X)).

propagate(X) :-
    should_engage(X),
    call_java(X).

propagate(X) :-
    (   should_engage(X)
    ->  call_java(X)
    ;   true
    ).

如果should_engage/1失败,第一个版本将导致X的实例化失败。后一个版本没有。

如果不是变量的绑定可能使 should_engage/1 为真,您将需要找到一些其他触发器或可能有一个线程定期监视环境并传播。

请注意,从 when/1 调用非逻辑构造通常没有什么意义,因为 Prolog 的计算可能会回溯、解除绑定 X 并再次将其重新绑定到相同或不同的值,因此您的传播可能被多次调用 不同或相同的值。