问题
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.
回答1:
Use Prolog's inbuilt failure and backtracking:
mylib([1,2]).
mylib(1).
test(X):-
mylib(X),
integer(X), % will fail on list, backtrack until a passing value for X is found, i.e. 1
length([1],X).
回答2:
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
来源:https://stackoverflow.com/questions/57316321/how-to-catch-exception-to-backtrackor-delimited-continuations-in-prolog