如何在 Prolog 中捕获异常以回溯(或分隔的延续)? [英] How to catch exception to backtrack(or Delimited Continuations) in Prolog?

查看:37
本文介绍了如何在 Prolog 中捕获异常以回溯(或分隔的延续)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Prolog 的新手,正在尝试了解 catch/3 的一些示例.

我要运行的代码在这里.(使用swi-prolog v8.0.3)

mylib.pl

mylib([1,2]).mylib(1).测试(X):- mylib(X),长度([1],X).

然后在 swipl 中查询它然后运行以下命令.

catch(test(X),error(Err,_Context),format('catch')).

所以在这里我想捕获typeError 异常 并得到X = 1.但结果是捕获异常,什么也没有继续.那么我应该怎么做才能达到我的目标?

在此处运行消息.

catchErr = type_error(integer, [1, 2]),_Context = 上下文(长度/2,_12488).

更新1:我尝试将 mylib.pl 修改为以下内容:

mylib([1,2]).mylib(1).test(X):- mylib(X),catch(length([1],X),error(Err,_Context),format('catch')).

然后运行test(X).命令,得到如下结果.

?- 测试(X).抓住X = [1, 2] ;X = 1.

但我想要的是跳过 X = [1, 2]

更新2:从 reddit 得到这个我正在探索 reset/3 和 shift/1 的用法.如果有人能举个例子就好了.

解决方案

只有少数 Prolog 系统提供 shift/reset,主要是那些将其用于递归表格的系统.但是,如果您的 Prolog 系统没有 shift/reset,您可以使用 meta-口译员:

solve([], ok).解决([shift|Y], S) :- !, S = stop(Y).解决([重置(X,Y)| Z],S): - !,解决(X,Y),解决(Z,S).解决([X | Y],S):-规则(X,L,Y),解决(L,S).

以上返回 ok 或 stop(continuation),取决于是否发生了 shift/0.延续以 reset/2 分隔.要获得一个抛球,请将其扩展到 shift/1 和 reset/3.

另见:

Prolog 中的分隔延续 - Schrijvers 等.艾尔,2012 年
https://pdfs.semanticscholar.org/ba6d/b9ffde405236a8237486cf82933e6bd97d5.pdf>

I'm new to Prolog and trying to know some example for catch/3.

The code I want to run is here. (Using swi-prolog v8.0.3)

mylib.pl

mylib([1,2]).
mylib(1).
test(X):- mylib(X), length([1],X).

then consult it in swipl then run the following command.

catch(test(X),error(Err,_Context),format('catch')).

So here I want to catch the typeError exception and get X = 1. But the result is catching the exception and nothing continues. So what should I do to reach my target?

Running messages here.

catch
Err = type_error(integer, [1, 2]),
_Context = context(length/2, _12488).

UPDATE1: I have tried to modify the mylib.pl to the following:

mylib([1,2]).
mylib(1).
test(X):- mylib(X),catch(length([1],X),error(Err,_Context),format('catch')).

Then run test(X). command and got following result.

?- test(X).
catch
X = [1, 2] ;
X = 1.

But what I want is skipping the X = [1, 2]

UPDATE2: got this from reddit I'm exploring the usage of reset/3 and shift/1. It will be great if someone could give an example.

解决方案

Only a few Prolog systems provide shift/reset, mostly those that use it for recursive tabling. But if your Prolog system does not have shift/reset, you might help yourself with a meta-interpreter:

solve([], ok).
solve([shift|Y], S) :- !, S = stop(Y).
solve([reset(X,Y)|Z], S) :- !, solve(X, Y), solve(Z, S).
solve([X|Y], S) :- rule(X, L, Y), solve(L, S).

The above returns ok or stop(continuation), depending whether a shift/0 happened or not. The continuation is delimited with reset/2. To have a throw ball, extend it to shift/1 and reset/3.

See also:

Delimited Continuations in Prolog - Schrijvers et. al, 2012
https://pdfs.semanticscholar.org/ba6d/b9ffde4052536a8237486cf82933e6bd97d5.pdf

这篇关于如何在 Prolog 中捕获异常以回溯(或分隔的延续)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆