Написано довольно плохо.Это может быть легче понять, если вы немного реорганизуете его и делаете его рекурсивным:
even_numbers( X , R ) :-
even_numbers( X , [] , T ) ,
reverse( T , R ).
even_numbers( [] , T , T ).
even_numbers( [X|Xs] , T , R ) :-
Z is X mod 2 ,
Z == 0 ,
! ,
even_numbers( Xs , [X|T] , R ).
even_numbers( [_|Xs] , T , R ) :-
even_numbers( Xs , T , R ).
Первый предикат, предикат even_numbers/2
, является общедоступной оболочкой.Он вызывает частного помощника even_numbers/3
, который возвращает список четных чисел в обратном порядке.Он отменяет это и пытается объединить его с результатом, переданным в оболочке.Вспомогательный метод делает это:
- , если список источников пуст: объедините аккумулятор (T) с результатом.
- , если список источников не пустой, и заголовоксписок (X) четный,
- рекурсивно опускается в конец списка (Xs), толкая X на аккумулятор.
- , если список источников непустой, а заголовок списка (X) нечетный,
- рекурсивно опускается в конец списка (Xs) без изменения аккумулятора.
Но, как заметил @ André Paramés, проработайте его в отладчике, и вам станет ясно, что происходит.