Exception 确保谓词决定性地成功
要求几乎相同,但不完全相同。相反,我如何要求一个目标决定性地成功(恰好一次),并且不留下任何选择点 这在用作命令行工具的Prolog程序环境中特别有用:可能从标准输入读取、获取参数以及写入标准输出。在这样的程序中,在完成工作后留下一个选择点总是程序员的错误 SWI Prolog提供了以下内容:Exception 确保谓词决定性地成功,exception,error-handling,prolog,swi-prolog,Exception,Error Handling,Prolog,Swi Prolog,要求几乎相同,但不完全相同。相反,我如何要求一个目标决定性地成功(恰好一次),并且不留下任何选择点 这在用作命令行工具的Prolog程序环境中特别有用:可能从标准输入读取、获取参数以及写入标准输出。在这样的程序中,在完成工作后留下一个选择点总是程序员的错误 SWI Prolog提供了以下内容: ( deterministic(true) -> true ; fail ) 有人提出了实现这一目标的另一种更便捷的方法: is_det(Goal, IsDet) :- setu
( deterministic(true)
-> true
; fail
)
有人提出了实现这一目标的另一种更便捷的方法:
is_det(Goal, IsDet) :-
setup_call_cleanup(true, Goal, Det=true),
( Det == true
-> IsDet = true
; !,
IsDet = false
).
然而,发生这种情况时抛出一个错误似乎很有用,但我不知道这个错误是什么。我非常仔细地看了一遍,找不到一个可以明显描述这种情况的错误
还是我应该失败呢?如果抛出错误是首选,那么该错误是什么
编辑:我不确定该怎么办,因为特别是当涉及到副作用时,比如在标准输出中写入内容,让副作用发生然后失败感觉非常错误。几乎有必要抛出异常。这也使得确定剩余的选择点是无害的(如果不需要的话)并捕获异常,然后写入标准错误或返回不同的退出代码成为可能
但我真的不知道是什么恰当地描述了异常,所以我不知道该抛出什么术语。查看Ulrich Neumerke在SWI Prolog邮件列表中提出的
调用semidet/1
:
他在报告中提出:
call_semidet(Goal) :-
( call_nth(Goal, 2)
-> throw(error(mode_error(semidet,Goal),_))
; once(Goal)
).
呼叫semidet(目标):-
(呼叫第n个(目标2)
->投掷(错误(模式错误(半决赛,进球),)
;一次(目标)
).
这一拟议的模式错误
是一个很好的开端
在精神上,它遵循了其他错误:在这种情况下,模式
semidet
是预期的,这反映在抛出的错误术语中。“发生副作用然后失败感觉非常错误”:我已经为这句话投票了@马特:这就是哈斯克尔教授的,计划好你的副作用。如果你需要副作用,就把它们和你的推理分开。@MiloslavRaus把副作用分开是很好的,但你最终还是要致力于它们。永远推迟像输出这样的副作用是不现实的。选择点确实有潜入代码的方式,特别是当使用DCG时。(只要你注意到,有许多被很好地描述的技术可以消除不必要的非确定性。)你需要一个新的错误术语,不知道如何称呼它@米洛斯拉夫·劳斯:很高兴看到其他语言现在也提倡这种分离。我不想编辑您的答案,但也许添加到显示相同解决方案的链接也很有用。谢谢您将此作为一个答案写下来:我实际上错过了相关部分(您以粗体显示)从我链接的相当大的答案来看,我也不知道这个电子邮件线程。call\n/2
当然对我的情况不起作用(副作用!),但这不是重点。SO答案的链接也很好。瞧,不久前SWI邮件列表是多么酷!在Ulrich和Richard仍然参与的那些年里,信噪比要高得多。好吧,有强烈意见的人加上这一令人遗憾的谷歌集团的举动。如果能从技术上解决第二个问题,那就太好了。就目前而言,没有gmail地址让你成为了二等网民。一系列糟糕的项目管理决策让我对SWI Prolog失去了兴趣,但如果你提出这些问题,我希望你比我幸运,我会支持他们!