确保谓词确定性成功

时间:2016-02-01 21:08:18

标签: exception error-handling prolog swi-prolog

This other question几乎一样,但不完全相同。相反,我如何要求确定性地(确切地一次)成功并且不留下任何选择点?

这在用作命令行工具的Prolog程序的上下文中特别有用:可能从标准输入读取,接受参数并写入标准输出。在这样的程序中,在完成工作后留下一个选择点总是程序员的错误。

SWI-Prolog提供deterministic/1,所以可以写一下:

(   deterministic(true)
->  true
;   fail
)

建议采用另一种更便携的方法:

is_det(Goal, IsDet) :-
    setup_call_cleanup(true, Goal, Det=true),
    (   Det == true
    ->  IsDet = true
    ;   !,
        IsDet = false
    ).

然而,在发生这种情况时抛出错误似乎很有用,但我不知道这个错误是什么。我仔细查看了ISO error terms并且找不到明显描述这种情况的错误。

抛出错误确实更好,还是我应该失败?如果首选抛出错误,该错误会是什么?

编辑:我不知道该怎么做,因为特别是当涉及副作用时,比如写一些标准输出,发生副作用感觉非常错误然后

但是我真的不知道什么是正确描述了异常,所以我不知道要抛出什么术语。

1 个答案:

答案 0 :(得分:3)

按照Ulrich Neumerkel在SWI-Prolog邮件列表上的建议查看call_semidet/1

call_semidet/1 - clean removal of choice-points

在其中,他建议:

call_semidet(Goal) :-
   (  call_nth(Goal, 2)
   -> throw(error(mode_error(semidet,Goal),_))
   ;  once(Goal)
   ).

这个提议的mode_error是一个非常好的开始。

在精神上,它遵循其他错误:在这种情况下,模式semidet 预期,这反映在抛出的错误术语中。