Концепция Пролога - замена атома с помощью рекурсии - PullRequest
1 голос
/ 23 марта 2020

Мне трудно понять концепцию обхода дерева в Прологе.

При заданном списке ввода следующий код заменяет атом привет, если присутствует в листьях (игнорируйте функторы). Я помещаю комментарии% рядом с частями, которые меня смущают:

replace([],[]).

replace([H | T], [H1 | T1]):-
    (  H == hi -> H1 = bye;  
       replace(H, H1)  % P1: What exactly does replace (H,H1) do? I know that
                       %     is saying if H = hi then H1 = bye; else ..
    ),
replace(T, T1).        

% The rule below is called in the replace(H,H1) above as well as the replace(T,T1). 
% I am unsure as to what exactly this does.

replace(L, R):-
    L =.. [F1 | Args1],
    replace(Args1, Args2),
    R =.. [F1 | Args2].

Код выше выводит:

?- replace(put(hi,table,aside(hi(dont,replace),hi)),X).
X = put(bye, table, aside(hi(dont, replace), bye)) 

Буду признателен за любую помощь. Заранее спасибо.

1 Ответ

1 голос
/ 23 марта 2020

Во втором пункте замены / 2 применяется оператор = .. (вызванный по историческим причинам univ ), чтобы получить другое представление термина в виде списка [Functor|Arguments], затем пытается заменить такие Аргументы и, наконец, повторно собирает термин, всегда с помощью univ.

Если вы также хотите заменить функтор, просто упростите предложение:

replace(L, R):-
    L =.. In,
    replace(In, Out),
    R =.. Out.

Так как Prolog имеет реляционную модель данных , иногда различие ввода / вывода не помогает, и в любом случае это просто соглашение об именах. Важно то, что это образец шаблона аргументов. Предикаты Builtin (если это пример) обычно пытаются предложить наиболее гибкую модель, то есть они могут работать в обратном направлении , но эта функция не всегда выполнима.

Для этого фрагмента в / Четко передать смысл ...

...