2009-11-20 8 views
1

/* substitute (X, Y, Xs, Ys)는 목록 Y가 Xs 목록의 모든 X에 대해 Y를 대체 한 결과 인 경우 true입니다.중첩 목록 (프롤로그)에서 대체

이것은 내가 지금까지 무엇을 : 그것은 중첩 된 목록에 다음과 같은 요소를 생략 제외

subs(_,_,[],[]). 
subs(X,Y,[X|L1],[Y|L2]):- subs(X,Y,L1,L2). 
subs(X,Y,[H|L1],[H|L2]):- X\=H, not(H=[_|_]), subs(X,Y,L1,L2). 
subs(X,Y,[H|_],[L2]):- X\=H, H=[_|_], subs(X,Y,H,L2). 

내 코드가 작동합니다. 예 :

?- subs(a,b,[a,[a,c],a],Z). 
Z = [b, [b, c]] . 

이 프로그램에 추가해야 할 내용은 무엇입니까?

+0

이것은 homewo로 밝혀졌습니다. rk : http://www.cs.toronto.edu/~yilan/324f09/324f09a4.pdf 다음 번에 ** ** 같이 태그를 달아주세요! – Stephan202

답변

1

중첩 목록을 찾으면 중첩 목록 뒤에 뒤에있는 이 무엇이든 잊어 버리는 것이 문제입니다. 대신 중첩 된 중첩을 사용하여 반복 한 후 이전과 같이 계속 진행하십시오. (!/0)에

  1. 사용 cuts :

    그에서 제외
    subs(X,Y,[H|L1],[H2|L2]):- X\=H, H=[_|_], subs(X,Y,H,H2), subs(X, Y, L1, L2). 
    

    , 코드를 개선 할 수있는 몇 가지 방법이 있습니다 : 다음과 같이 따라서, 당신은 마지막 절을 변경해야합니다 역 추적을 중지하십시오. 이런 식으로 자신을 반복 할 필요가 없습니다.

  2. is_list/1을 사용하여 인수가 목록인지 테스트 할 수 있습니다.
  3. 더 많은 공백을 사용할 수 있습니다. 정말.

그래서, 대안 솔루션 (지금 \+/1 대신 not/1의 사용)입니다 :

subs(_, _, [], []). 
subs(X, Y, [X|T1], [Y|T2]) :- subs(X, Y, T1, T2), !. 
subs(X, Y, [H|T1], [H|T2]) :- \+ is_list(H), subs(X, Y, T1, T2), !. 
subs(X, Y, [H1|T1], [H2|T2]) :- subs(X, Y, H1, H2), subs(X, Y, T1, T2). 

데모 :

다음
?- subs(a, b, [a, [a, [d, f, a]], a, b, a, [g]], Z). 
Z = [b, [b, [d, f, b]], b, b, b, [g]]. 
+0

알았어요! 감사!! – linda

+0

인하는 추악합니다. 다음 절에서 함축적 인 부정을 숨 깁니다. 함수형 프로그래밍에서 if-then-else와 유사한 (... -> ...; ...)을 사용하는 것이 더 좋습니다. – starblue

+0

@starblue : 예, 나는 삭감에 문제가 있음을 막연하게 기억합니다 (최근에는 프롤로그에 관심을 보였습니다). 나는 그것을 가까운 장래에 읽을 것이다. 머리를 주셔서 감사합니다, 그리고 난 대답을 upvote거야 :) – Stephan202

2

당신이 (사용하여 쓸 수있는 방법은 ... - > ...; ...) :

subs(_, _, [], []). 
subs(X, Y, [H1|T1], [H2|T2]) :- 
    (H1 == X -> 
     H2 = Y 
    ; is_list(H1) -> 
     subs(X, Y, H1, H2), 
     subs(X, Y, T1, T2) 
    ; 
     H1 = H2, 
     subs(X, Y, T1, T2) 
    ).