Common Lisp允许通过条件和重新启动进行异常处理.粗略地说,当函数抛出异常时,"捕手"可以决定"投掷者"应该如何进行.Prolog是否提供类似的系统?如果没有,是否可以在现有谓词的基础上构建一个步行和检查调用堆栈?
在序言的ISO/IEC标准只提供了一个非常基本的异常和错误处理机制是-或多或少-这样的举动,Java提供,远离Common Lisp的丰富的机制,但仍存在一些值得注意的要点.特别是,除了实际的信令和处理机制之外,许多系统提供了类似的机制unwind-protect.也就是说,即使存在未处理的信号,也能确保执行目标的方法.
提出/抛出异常throw(Term).首先Term创建一个副本,copy_term/2让我们调用它Termcopy然后这个新副本用于搜索catch(Goal, Pattern, Handler)其第二个参数统一的对应Termcopy.当Handler被执行时,所有unifications造成Goal被撤消.因此Handler,在throw/1执行时无法访问存在的替换.并且没有办法继续throw/1执行被执行的地方.
内部谓词的错误是由于执行信号发送throw(error(Error_term, Imp_def)),其中Error_term对应于一个ISO的错误类和Imp_def可以提供实现定义额外的信息(如源文件,行数等).
在许多情况下,在本地处理错误会带来很大好处,但许多实现者认为它太复杂而无法实现.
使Prolog处理器在本地处理每个错误的额外工作是非常可观的,并且比Common Lisp或其他编程语言中的大得多.这是由于Prolog统一的本质.本地处理错误需要撤消在执行内置期间执行的统一:因此,实现者有两种可能性来实现:
在内置函数中利用WAM寄存器会导致类似的复杂性.同样,可以在慢速系统或具有显着实现开销的系统之间进行选择.
然而,许多系统提供了内部更好的机制,但很少有系统为程序员提供这些机制.IF/Prolog提供exception_handler/3的参数与参数相同catch/3但在本地处理错误或异常:
[user] ?- catch((arg(a,f(1),_); Z=ok), error(type_error(_,_),_), fail). no [user] ?- exception_handler((arg(a,f(1),_); Z=ok), error(type_error(_,_),_), fail). Z = ok yes
这个内置由很多系统提供.unwind-protect由于Prolog的回溯机制,它非常相似但需要一些额外的复杂性.查看其当前定义.
所有这些机制都需要由系统实现者提供,它们不能构建在ISO Prolog之上.