Debugging gprolog:在异常后获取stacktrace

Debugging gprolog:在异常后获取stacktrace,debugging,prolog,gnu-prolog,program-slicing,Debugging,Prolog,Gnu Prolog,Program Slicing,在使用gprolog时,我经常会遇到没有任何行号或上下文的异常,例如: uncaught exception: error(instantiation_error,(is)/2) 没有任何背景。我知道我可以执行跟踪,但是使用跟踪调试它需要很长时间,因为在到达错误发生的地方之前,我需要执行很多事情 你知道怎么做吗?还是动态的跟踪/非跟踪 编辑:或仅自动打印整个跟踪输出。您可以跟踪/0和约束/1仅打印异常端口,例如: ?- trace. ?- leash([exception]). 然后您运行您

在使用gprolog时,我经常会遇到没有任何行号或上下文的异常,例如:

uncaught exception: error(instantiation_error,(is)/2)
没有任何背景。我知道我可以执行
跟踪
,但是使用
跟踪
调试它需要很长时间,因为在到达错误发生的地方之前,我需要执行很多事情

你知道怎么做吗?还是动态的
跟踪
/
非跟踪


编辑:或仅自动打印整个
跟踪
输出。

您可以
跟踪/0
约束/1
仅打印异常端口,例如:

?- trace.
?- leash([exception]).
然后您运行您的程序,它将在屏幕上打印跟踪,但只有在发生异常时才会停止。在那里,您可以通过按字母
g

@gusbro的答案(
s(X)
)来查看“堆栈跟踪”(祖先)显示如何使用GNU的调试器解决此问题。但是,如果你负担不起看到所有的打印正在进行,或者它太慢,你可以考虑下面的“调试器”。 我个人不使用Prolog系统提供的调试器,原因很简单,大多数调试器打印太多,本身经常有问题,并且有自己特定的不断变化的约定,我学不起

:- op(900, fx, [@,$,$-]).

$-(G_0) :-
   catch(G_0, Ex, ( portray_clause(exception:Ex:G_0), throw(Ex) ) ).

$(G_0) :-
   portray_clause(call:G_0),
   $-G_0,
   portray_clause(exit:G_0).

@(G_0) :-
   (   $-G_0
   *-> true
   ;   portray_clause(badfail:G_0),
       throw(goal_failed(G_0))
   ).

:- op(950, fy, *).
*(_).
要使用它,只需在特定目标前面添加
$-
$
@

$-
意味着:只有信号异常通过此目标

$
另外显示呼叫和退出

@
确保至少有一个答案,如果没有,则报告该答案并引发异常

请谨慎使用以上注释

*
删除目标。这是用于在纯单调程序中进行程序修改的程序的泛化。如果发生意外故障,则需要此选项。有关如何使用它的示例,请参见以下回答/调试会话 , , , , , , , ,

\uu/*术语*/
用匿名变量替换术语。这比单独的
*
更能概括程序。例会: , , , , , , , ,

通过这种方式,您可以显著减少所查看的信息

在支持
meta_谓词
指令的其他系统(如SICStus、YAP和SWI)中,在前面添加以下指令:

:- meta_predicate(( $-(0), $(0), @(0) )).

哇,两种解决方案都很棒!谢谢!