Рассмотрим эти изменения в tol33t/2
:
tol33t([], []).
tol33t([Code|Codes], Remainder) :-
translate([Code], Translation), !,
tol33t(Codes, Rest),
append(Translation, Rest, Remainder).
tol33t([Code|Codes], [Code|Remainder]) :-
tol33t(Codes, Remainder).
Первый пункт является базовым случаем.
Второе условие будет успешным тогда и только тогда есть перевод для текущего Code
через translate/2
, как список символов произвольной длины (Translation
- обратите внимание, вы имели [Lower]
вместо этого, что ограничивало результаты списков только длины 1). Вырез (!
) после проверки перевода кода обязывает к поиску решения Rest
рекурсивно, а затем присоединяет Translation
к фронту, так как возвращается Remainder
.
Третье предложение выполняется, если не было перевода для текущего Code
(т. Е. Вызов translate/2
) во втором предложении. В этом случае перевод для Code
означает, что мы просто возвращаем его как есть и вычисляем остальное.
EDIT:
Если вы не резали (!
), второй и третий пункты могут быть объединены, чтобы стать:
tol33t([Code|Codes], Remainder) :-
tol33t(Codes, Rest),
(translate([Code], Translation) ->
append(Translation, Rest, Remainder)
; Remainder = [Code|Rest]
).
Это (неоптимизированная) версия проверяет, на каждом Code
в списке персонажей, , если есть translate/2
, который преуспевает; если да, то Translation
прилагается к Rest
, ещеCode
передается без изменений. Обратите внимание, что это имеет ту же семантику, что и реализация выше, в том, что решения совершаются (например, имитируя разрез !
), если антецедент до ->
(translate/2
) преуспевает. Обратите внимание, что сокращение в обеих реализациях строго необходимо; без него программа вернется к поиску решений, в которых привязки Code
не переводятся, если существует применимое предложение translate/2
.
Я сделал что-то довольно близко к тому, что у вас там есть. Проблема в том, что я не могу использовать разрез, поэтому я все время зацикливаюсь – Matt
На самом деле это должно быть нормально без проверки, чтобы увидеть, существует ли перевод. Благодаря! – Matt
Aha ...если вы не можете использовать cut, вы можете использовать '->' вместо этого. Я добавлю код в редактирование. – sharky