замена терминов в списке прологов - PullRequest
1 голос
/ 02 апреля 2012

Я пытаюсь написать прологическую программу, которая будет принимать в качестве входных данных список, old_subterm и new_subterm, и возвращать новый список, в котором каждый экземпляр old_subterm был заменен на new_subterm.Например,

| ?- sub_rep([h(A,g(x)),g(x),g(3)],g(x),p,T).
T = [h(A,p),p,g(3)] ? ;
no

Таким образом, я могу заставить это работать с базовыми списками, используя следующий код:

replace(E,S,[],[]).
replace(E,S,[E|T1],[S|T2]):-
    replace(E,S,T1,T2).
replace(E,S,[H|T1],[H|T2]):-
    E\=H, 
    replace(E,S,T1,T2).

%(here's some example input/output)

?- replace(b,e,[a,b,c],L).
L = [a, e, c] ;
false.

?- replace(f(Y),g(Y),[f(Y),1,2,f(Y)],L).
L = [g(Y), 1, 2, g(Y)] ;
false.

, но когда я пытаюсь сделать это с более сложным списком, таким как

?- replace(g(Y),h,[f(g(Y)),g(Y),g(1)],L).

Я получаю следующий ответ:

Y = 1,
L = [f(g(1)), h, h] ;
false.

, это не то, что я ищу, так как я надеюсь, что он вернется:

? - L = [f(h),h,g(1)] ;
false.

Я новичок в прологе и, возможно, мне не хватает чего-то очевидного, но я не понимаю, почему в этом случае создается экземпляр переменной Y?Это не проблема во втором примере.Я думаю, это как-то связано с появлением g (1), но я не понимаю, почему?Заранее спасибо!:)

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

Первое наблюдение по вашей проблеме: списки одинаковой длины!Это звучит как хороший кандидат на maplist/3!

replace(A, B, As, Bs) :-
   maplist(repl(A,B), As, Bs).

Так много для "рекурсивной" части вашей проблемы.Теперь мы должны определить repl/4.Вот мое предположение о том, что вы хотите:

repl(A, B, A0, B0) :-
   ( A == A0 -> B = B0 ; A0 = B0 ).

Может быть, вы хотите какой-то другой тест вместо (==)/2.

0 голосов
/ 02 апреля 2012

Вы должны «взорвать» ваши условия для сравнения.

replace(_, _, [], []).
replace(E, S, [X|T1], [Y|T2]):-
    replace_term(E, S, X, Y),
    !, replace(E, S, T1, T2).
replace(E,S, [H|T1], [H|T2]):-
    replace(E,S,T1,T2).

replace_term(E, S, E, S) :- !.
replace_term(E, S, T, R) :-
      T =.. [F|As],  % explode
      replace(E, S, As, Gs),
      R =.. [F|Gs].  % reassemble

тест:

?- replace(a,b,[a(a),b,c],L).
L = [a(b), b, c] ;
false.


?- replace(g(y),h,[f(g(y)),g(y),g(1)],L).
L = [f(h), h, g(1)] .

когда в шаблоне есть переменные, все становится более сложным:

?- replace(g(Y),h,[f(g(Y)),g(Y),g(1)],L).
Y = 1,
L = [f(h), h, h] ;

Возможно, число переменных может помочь, или мы должны разработать стратегию, которая бы сразу создавала переменные ...

...