1

我正在尝试创建一个显示问题解决方案的程序,我需要一种方法来显示它创建的解决方案。我有两个可用于解决问题的操作以及它们被称为问题的顺序。

test(a) :- write('use a ').
test(b) :- write('use b '), fail.

test(c) :- test(a), test(b), test(a).
test(c) :- test(a), test(a).

请注意,这是一个示例,不应按字面意思理解。将 test(a) 和 test(b) 视为操作,将 test(c) 视为检查哪个订单有效的函数。

现在test(c).甚至会打印那些失败的。导致输出“使用 a 使用 b 使用 a 使用 a”。

4

2 回答 2

3

考虑使用描述目标列表的 DCG,而不是使用副作用。您的示例可以通过一些机械重写步骤轻松转换为 DCG,例如:

test(a) --> ['use a'].
test(b) --> ['use b'], { false }.

test(c) --> test(a), test(b), test(a).
test(c) --> test(a), test(a).

然后可以查询:

?- phrase(test(c), Ls).
Ls = ['use a', 'use a'].

当你有这样一个列表Ls时,你可以很容易地以任何你想要的方式编写它。请注意,尽管顶层已经以一种有用的方式打印了每个解决方案,但您自己可能没有理由这样做。

于 2013-10-10T21:24:02.610 回答
1

您的问题似乎是对 assertz/retract 的合理调用。

这些内置函数允许跟踪时间顺序,并存储任意 Prolog 术语,然后您可以编写

:- dynamic results/2.

test(a) :- a_code(Result), assertz(results(a, Result)).
test(b) :- b_code(Result), assertz(results(b, Result)).

test(c) :- test(a), test(b), test(a).
test(c) :- test(a), test(a).

check_results :- forall(retract(Name, Result), writeln(Name = Result)).

如果要跟踪失败的执行,可以扩展该模式:

test(a) :- a_code(Result) -> assertz(results(ok(a), Result)) ; assertz(results(ko(a), _)).
test(b) :- b_code(Result) -> assertz(results(ok(b), Result)) ; assertz(results(ko(b), _)).
于 2013-10-10T20:49:26.297 回答