Ошибка в ожидаемом функциональном правиле в прологе - PullRequest
1 голос
/ 25 апреля 2019

Я пытаюсь решить проблему с оружием, у которого есть два варианта урона (опция: 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).

Где List - список элементов. Max - максимальный ущерб, который может нанести перестроенный список 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)

Я отлаживал его через tracer (опция в Tools - tkEclipse), и проблема в том, что когда

evaluate_damage(D,Program,TotalDamage)

вызывается внутри

hack(Program,Max,NewProgram,N)

не дает ожидаемого результата. Это действительно странно, потому что когда evaluate_damage (D, Программа, TotalDamage)

называется сам по себе, работает отлично. Кто-нибудь знает в чем проблема?

1 Ответ

1 голос
/ 27 апреля 2019
...
append(L2,c,NewList2),
...

вторым аргументом append должен быть список.

и / 2 не копирует значение справа налево.Используйте переменные в голове или оператор объединения = / 2.Относитесь серьезно к предложению Дэниела о пересмотре кода после переименования.

В целом, вы успешно продвигаетесь в Пролог.Конечно, в современных системах Prolog есть библиотеки, которые могут значительно сократить код.Но педагогическая ценность, полученная при решении основных задач, неоценима.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...