我正在尝试解决有关枪支有两种损坏选择(选项:s,选项:c)的问题。选项s给予伤害D,选项c将当前伤害加倍至2 * D。规则的结构方式如下:
evaluate_damage(D,List,TotalDamage).
D是初始伤害。
列表是一个包含s和c的列表。
TotalDamage是列表造成的总损坏。
这里有一些例子。
?- evaluate_damage(1, [s,s], TotalDamage).
TotalDamage = 2
Yes
?- evaluate_damage(1, [s,c,s,c], TotalDamage).
TotalDamage = 3
Yes
?- evaluate_damage(1, [s,c,s,c,s,s], TotalDamage).
TotalDamage = 11
Yes
?- evaluate_damage(2, [s,s], TotalDamage).
TotalDamage = 4
Yes
它本身可以很好地工作,但是当我在另一条规则中使用它时,它并没有给出预期的结果。具体来说,我的程序中还有另一个规则,该规则重新排列字符的顺序以减少损害。 该规则的结构方式如下:
hack(List,Max,NewProgram,N).
“列表”是元素列表。 “最大”是重新排列的列表将造成的最大损坏。 NewProgram是重新排列的列表,
N是为到达重新排列的列表NewProgram而进行的交换次数。
以下是该规则的预期结果:
?- hack([c, s], 1, NewProgram, N).
NewProgram = [s, c]
N = 1
Yes
?- hack([s, s], 1, NewProgram, N).
No
?- hack([s, c, c, s, s, c], 6, NewProgram, N).
NewProgram = [s, s, c, c, s, c]
N = 2
Yes
?- hack([c, s, c, s, s], 3, NewProgram, N).
NewProgram = [s, s, s, c, c]
N = 5
Yes
这是我的代码。
evaluate_damage(_,[],0).
evaluate_damage(D,s,D).
evaluate_damage(D,c,Damage) :-
Damage is D*2.
evaluate_damage(D,[H|List],TotalDamage) :-
evaluate_damage(D,H,Damage),
(Damage=D;Damage=0),
evaluate_damage(D,List,TDamage),
TotalDamage is D+TDamage.
evaluate_damage(D,[H|List],TotalDamage) :-
evaluate_damage(D,H,Damage),
Damage>D,
evaluate_damage(Damage,List,TotalDamage).
cutList(List,List1,[c|List2]) :-
append(List1,[c|List2], List),!.
hack(List,Max,NewProgram,N) :-
cutList(List,L1,[c|L2]),
length(L2,Length2),
append(L2,c,NewList2),
append(L1,NewList2,NewList),
evaluate_damage(1,NewList,SecondDamage),
SecondDamage=<Max,
N is Length2,
NewProgram is NewList.
实际输出是
?- hack([c, s], 1, NewProgram, N).
No (0.00s cpu)
我通过跟踪器(工具-tkEclipse中的选项)调试了它,问题是当
evaluate_damage(D,Program,TotalDamage)
在内部被称为
hack(Program,Max,NewProgram,N)
它没有给出预期的输出。真的很奇怪,因为 Evaluation_damage(D,Program,TotalDamage)
被自己调用,可以完美工作。有人知道是什么问题吗?
答案 0 :(得分:1)
...
append(L2,c,NewList2),
...
append的第二个参数必须是列表。
和is / 2不会从右到左“复制”一个值。在头部或统一运算符= / 2中使用变量。认真考虑Daniel关于重命名后重新考虑代码的建议。
总体而言,您的Prolog进展顺利。 当然,现代Prolog系统中有一些库可以大大缩短代码。但是解决基本问题所获得的教学价值是无价的。