2013-10-10 70 views
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). 

请注意这是一个例子,不应该从字面上理解。将测试(a)和测试(b)视为操作和测试(c)作为检查哪个订单有效的功能。

现在test(c).将打印甚至失败的。导致输出“使用用户使用用户”。

+1

可能会显示一些代码? – lurker

+0

最优雅的方法是让Prolog顶层显示解决方案。定义一个谓词'solution(S)',如果'S'是一个解就是真的。当你查询'? - solution(S).'时,顶层将显示你的解决方案。 – mat

+0

写入将不起作用...为了打印它在测试下一步之前必须先发送的消息,导致即使该消息不起作用也会打印该消息,否则它将会倒退。 – johndoe

回答

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), _)). 
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,你可以随便写它以任何你想要的方式。但请注意,顶层已经以有用的方式打印每个解决方案,并且自己可能没有理由这样做。

+0

这看起来很有趣,我会试试看。虽然你能澄清一些句法上的差异吗?至于你为什么使用 - >?那究竟做了什么? – johndoe

+1

( - >)/ 2定义了DCG规则。在任何好的Prolog书籍中阅读有关DCG(“明确的从句语法”)。简而言之:DCG总是描述一个列表。在DCG中,您可以将(,)/ 2读为“然后”。 [T]代表一个终端,{目标}代表一个普通的Prolog目标,NT代表一个DCG非终端。在描述列表时,描述它似乎很复杂,所以请始终考虑使用DCG。 DCG通常会变得更容易。 – mat

相关问题