在SWI-Prolog中自动化我的pet调试策略
我有一个非常直截了当的问题,我很乐意得到任何指导 我正在研究确定子句语法,并对其输出进行抽查。如果一个解析树让我感到困惑,我想把它追溯到生成该树部分的谓词。所以我要做的是在谓词中插入数字原子。像这样:在SWI-Prolog中自动化我的pet调试策略,prolog,Prolog,我有一个非常直截了当的问题,我很乐意得到任何指导 我正在研究确定子句语法,并对其输出进行抽查。如果一个解析树让我感到困惑,我想把它追溯到生成该树部分的谓词。所以我要做的是在谓词中插入数字原子。像这样: 句子(句子(主语、动词、宾语))-->主语、动词、宾语。 变成 句子(句子(736,主语,动词,宾语))-->主语,动词,宾语。 然后,我可以搜索数字736并检查该特定谓词,以了解Prolog选择它的原因。随着我语法的膨胀,这变得非常方便。但是,每当我想要调试时,就必须进行这些文本编辑,这很不方便
句子(句子(主语、动词、宾语))-->主语、动词、宾语。
变成
句子(句子(736,主语,动词,宾语))-->主语,动词,宾语。
然后,我可以搜索数字736并检查该特定谓词,以了解Prolog选择它的原因。随着我语法的膨胀,这变得非常方便。但是,每当我想要调试时,就必须进行这些文本编辑,这很不方便
当我想以这种方式进行调试时,是否有一些优雅的Prolog规则可以添加到语法中,这些规则可以为每个谓词附加一个唯一的ID?这是高度特定于实现的,但SWI Prolog有一个
源位置/2
谓词,在术语扩展/2
规则中调用,提供要展开的子句的文件名和行号
因此,您可以使用以下内容:
term_expansion(Head --> Body, EnhancedHead --> Body) :-
source_location(File, Line),
format('~w --> ~w at ~w:~w~n', [Head, Body, File, Line]),
Head =.. [Functor, Arg1 | Args],
Arg1 =.. [ArgFunctor | ArgArgs],
EnhancedArg1 =.. [ArgFunctor, File:Line | ArgArgs],
EnhancedHead =.. [Functor, EnhancedArg1 | Args].
hello -->
[world].
sentence(sentence(Subject, Verb, Object)) -->
[Subject, Verb, Object].
请注意,此术语\u expansion/2
将打印程序中每个-->/2
规则的日志消息:
hello --> [world] at /home/isabelle/hello.pl:9
sentence(sentence(_2976,_2978,_2980)) --> [_2976,_2978,_2980] at /home/isabelle/hello.pl:12
但是如果规则的头部没有至少一个参数,并且第一个参数本身没有至少一个参数,那么它将失败。这很好,失败只是意味着“不要重写这个术语”:
但是句子//1
将被重写:
?- listing(sentence).
sentence(sentence('/home/isabelle/hello.pl':12, A, B, C), [A, B, C|D], D).
true.
?- phrase(sentence(sentence(Position, S, V, O)), [isabelle, likes, prolog]).
Position = '/home/isabelle/hello.pl':12,
S = isabelle,
V = likes,
O = prolog.
您可以在此基础上进行构建,也许可以使用一个单独的操作符-->
,只标记您真正想要重写的规则。我认为,当您试图用实际的基础术语(而不是源代码中出现的术语)来统一某些内容时,使用这个额外的隐式参数会导致许多意外的失败
所以也许更好的方法是这样的:
sentence(sentence(@position, Subject, Verb, Object)) -->
[Subject, Verb, Object].
和相应的<代码> Tym扩展/ 2 < /代码>规则,寻找这些<代码> @位置<代码>术语,并相应地替换它们。< / P>可选地,考虑技术。对于语法,添加
*(\u NT\u\u 0)-->seq(\u0)。
sentence(sentence(@position, Subject, Verb, Object)) -->
[Subject, Verb, Object].