【问题标题】:Prolog only check variable is instantiatedProlog 仅检查变量被实例化
【发布时间】:2018-12-05 15:37:52
【问题描述】:

Prolog中,是否只有当变量为instantiated时才能检查variable是否为某个值。

? - my_rule(X).

my_rule(X):-
    X = 4,
    write('continue'). 

在这里我试图检查X is 4,如果X is 4,那么我们继续,但如果X_,我也希望规则继续,但是当它被其他东西调用时,比如X is 3 那么它不应该继续。

所以结果应该是这样的:

?- my_rule(X).

continue
true.

?- my_rule(4).

continue
true.

?- my_rule(3).

false.

【问题讨论】:

    标签: prolog rules


    【解决方案1】:

    看看var/1atom/1ground/1

    • var(X) 为真当且仅当X 是一个变量。

      ?- var(X), X= 1。 X = 1。

      ?- X=1, var(X)。 假的。

      ?- X=f(Y), var(X)。 假的。

    • 如果X 是原子,则atom(X) 为真。

      ?- 原子(a)。 真的。

      ?- 原子(f(a))。 假的。

      ?- 原子(X)。 假的。

    • ground(X) 为真,如果 X 为接地(不包含变量)。

      ?- 地面(f(a))。 真的。

      ?- 地面(f(X))。 假的。

    这三个谓词是确定性的(即不回溯),您可以安全地否定它们。

    你的代码变成这样:

    my_rule(4) :-
       % handle the 4 case
    my_rule(X) :-
       var(X),
       % general case
    

    我只是不确定这是否是您想要的。在大多数程序中,没有必要单独处理仅变量的情况。还要注意,这种元逻辑测试超出了经典逻辑的范围。如果比较查询X = 1, var(X)var(X), X = 1,您可以看到合取不再是可交换的,而是在逻辑 A ∧ B = B ∧ A 成立。

    【讨论】:

      【解决方案2】:

      你可以使用双重否定(\+(\+(...))):

      在你的例子中:

      my_rule(X):-
          \+(\+(X = 4)),
          write('continue'). 
      

      【讨论】:

      • 请问你会怎样检查它是否是not 4。这样它就可以在任何情况下工作,除非X = 4
      • @Richard:在这种情况下你可以使用\+(X==4)
      • 在很多情况下dif/2 效果更好(它更昂贵,因为它推迟了目标,直到它可以决定参数是否相等)。您也可以使用iso_dif/2,它不会传播,但在无法立即决定的情况下会抛出异常。
      【解决方案3】:
      my_rule(X):-
          check(X),
          write('continue').
      
      % A fact used to check a value.
      check(4).
      
      % A predicate that checks if X is unbound, e.g. a variable.
      check(X) :-
          var(X).
      

      验证预期结果。

      ?- my_rule(X).
      continue
      X = 4 ;
      continue
      true.
      
      ?- my_rule(4).
      continue
      true ;
      false.
      
      ?- my_rule(3).
      false.
      

      【讨论】:

      • 尽管这个答案看起来更简洁,但我必须接受gusbro 一个,因为我有多个这个例子的案例,而且那个更合适,但谢谢你的回答。
      • 我能问一下你会怎么做吗 - 检查它是否是not 4。这样它就可以在任何情况下工作,除非X = 4
      • @Richard Et tu, Brute?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多