Просто, это
cryptoA([1,1,0,1,0,0,0,1], [0,0,1,0,1,1,1,0]).
Но, конечно, слишком конкретно c. Вероятно, следует добавить больше случаев, например,
cryptoA([1,1,0,1,0,0,0], [0,0,1,0,1,1,1] ).
cryptoA([1,1,0,1,0,0], [0,0,1,0,1,1] ).
cryptoA([1,1,0,1,0], [0,0,1,0,1] ).
.....
cryptoA([1,1,0], [0,0,1] ).
.....
cryptoA([ 1 ], [ 0 ] ).
cryptoA([ 0], [ 1] ).
, верно? Но сколько конкретных случаев достаточно? Будет ли этого когда-нибудь достаточно?
Чтобы иметь дело с бесконечным количеством структурированных кейсов, мы можем написать структурированный код, используя рекурсию. Последние два предложения кажутся минимальными, и почему они должны быть заключены в такие списки?
cryptoB( 1 , 0 ).
cryptoB( , ).
% fill the blanks
Что такое рекурсивный регистр?
cryptoA( [A | B], [C | D] ) :-
cryptoB( , ), % fill the blanks
cryptoA( B, D).
Каков базовый случай?
cryptoA( [ ], [ ] ). % fill the blanks
Завершить определение последнего предложения особенно легко.
Мы могли бы прийти к этому «рекурсивному» решению, поиграв с данным примером, упростив его, а затем обобщив его.
Посмотрим. Если пойти в другом направлении, это
cryptoA( [1,1,0,1,0,0,0], [0,0,1,0,1,1,1] ). % which means this must hold:
cryptoA( [ 1,0,1,0,0,0], [ 0,1,0,1,1,1] ). % and also this must hold:
cryptoA( [1 ], [0 ] ). % which is to say,
cryptoB( 1 , 0 ). % this must hold
Итак, давайте запишем это!
cryptoA( [1,1,0,1,0,0,0], [0,0,1,0,1,1,1] ) :-
cryptoA([ 1,0,1,0,0,0], [ 0,1,0,1,1,1] ),
cryptoB( 1 , 0 ).
%% or, equivalently,
cryptoA( X, Y ) :-
X = [1,1,0,1,0,0,0], Y = [0,0,1,0,1,1,1], % specific case
X = [A | B ], Y = [C | D ], % general structure
cryptoA( B, D ), % recursive step
cryptoB( A , C ). % single-step processing
, и теперь мы можем обобщить, просто удалив это определение c case. Конечно, та же самая схема должна выполняться с любыми другими спецификациями c данных вообще!
Конечно, не каждый список может быть сопоставлен с шаблоном непустого списка [_ | _]
, просто потому что не все списки непустые. Некоторые списки на самом деле пусты, []
, и это приводит к базовому случаю.
Наконец, рекурсивный шаг предпочтительно указывать последним, в так называемой хвостовой позиции, для общий предикат должен быть хвостом рекурсивным. Так намного эффективнее.