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

时间:2018-12-08 16:14:29

标签: prolog prolog-coroutining

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

我正在寻找一种机制,该机制可以让我在条件变为真时自动执行操作。

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

  • nonvar(X)
  • ground(X)
  • ?=(X, Y)
  • (Cond1, Cond2)
  • (Cond2; Cond2)

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

我需要根据自己的条件进行哪些更改?

请在此处将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)).

1 个答案:

答案 0 :(得分:3)

当/ 1是相关基础结构的一部分时,该基础结构触发对变量实例化的操作。它在后台使用归因变量。因此,如果您的J 通常是一个可以在某个时间绑定的变量

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

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

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

如果X失败,则第一个版本将导致should_engage/1的实例化失败。后者不是。

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

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