2013-11-01 2 views
1

나는 Prolog를 처음 사용하며 목록의 모든 숫자와 하위 목록을 제곱하는 일종의 깊은 사각형 조건부를 구현하려고합니다. 나는 일종의 작동 코드를 썼다. 그러나 그것이 나에게 내가 기대 한 결과를주지 못했다.maplist를 사용하지 않고 sublist Prolog를 포함한리스트의 모든 멤버를

번호 :

dsquare([],S). 
dsquare([H|T],[R|S]):- number(H), dsquare(T,S), R is H*H, !. 
dsquare([H|T],S):- isList(H), dsquare(H,S). 
dsquare([H|T],[R|S]) :- dsquare(T,S), R = H, !. 

전류 출력 :

2?- dsquare([[2],4,a],X). 

X = [4| _VDHV] ; 

X = [[2], 16, a| _VDNM] ; 

fail. 

예상 출력 : 또한

X = [4] 16 A]

나는 왜 그걸 알고 싶었어. 제 출력물에 '_VDHV'와 '_VDNM'이 표시됩니다. 도움을 주시면 감사하겠습니다.

편집 :

dsquare([],[]). 
dsquare([H|T],[R|S]):- number(H), R is H*H, dsquare(T,S). 
dsquare([H|T],[R|S]):- isList(H), dsquare(H,R), dsquare(T,S). 
dsquare([H|T],[R|S]) :- R=H, dsquare(T,S). 

는하지만 얻을 출력은 다음과 같습니다 : 나는 내 코드를 업데이트 있도록 확인

13?- dsquare([a,3,[[2]],b,4],X). 

X = [a, 9, [[4]], b, 16] ; 

X = [a, 9, [[4]], b, 4] ; 

X = [a, 9, [[2]], b, 16] ; 

X = [a, 9, [[2]], b, 4] ; 

X = [a, 9, [[2]], b, 16] ; 

X = [a, 9, [[2]], b, 4] ; 

X = [a, 9, [[2]], b, 16] ; 

X = [a, 9, [[2]], b, 4] ; 

X = [a, 3, [[4]], b, 16] ; 

X = [a, 3, [[4]], b, 4] ; 

X = [a, 3, [[2]], b, 16] ; 

X = [a, 3, [[2]], b, 4] ; 

X = [a, 3, [[2]], b, 16] ; 

X = [a, 3, [[2]], b, 4] ; 

X = [a, 3, [[2]], b, 16] ; 

X = [a, 3, [[2]], b, 4] ; 

fail. 

나는 너무 많은 결과를 얻는 방법 단서가 없다.

편집 마침내 작업 솔루션은

dsquare([],[]). 
dsquare([H|T],[R|S]) :- number(H), !, R is H*H, dsquare(T,S). 
dsquare([H|T],[R|S]) :- isList(H), !, dsquare(H,R), dsquare(T,S). 
dsquare([H|T],[H|S]) :- dsquare(T,S). 
+0

@CapelliC : 실행을 위해 프로그램을 다시 시작해야했습니다. –

+0

@Nicholas Carey : 당신의 설명이 많은 도움이되었습니다. –

답변

0

당신의 프롤로그 첫 번째와 세 번째 규칙에서 '싱글'에 대해 경고해야합니다.

동기 부여 이유없이 상처를 두지 않는

dsquare([],[]). 
... 
dsquare([H|T],[S|R]):- isList(H), dsquare(H,S), dsquare(T,R). 

OT를 사용해보십시오.

편집 더 많은 결과가 나옵니다. 마지막 규칙은 역 추적으로 해고됩니다. 이제 삭감이 필요 를 배치 할 수있는 시간이 될 수 있습니다 (코드가 조건에 의해 보호 가지 입력 즉, 후) :

dsquare([],[]). 
dsquare([H|T],[R|S]) :- number(H), !, R is H*H, dsquare(T,S). 
dsquare([H|T],[R|S]) :- isList(H), !, dsquare(H,R), dsquare(T,S). 
dsquare([H|T],[R|S]) :- R=H, dsquare(T,S). 

또는 반복 코드를 차지하는 리팩토링 고려 :

dsquare([],[]). 
dsquare([H|T],[R|S]) :- 
    ( number(H) 
    -> R is H*H 
    ; isList(H) 
    -> dsquare(H,R) 
    ; R=H 
), 
    dsquare(T,S). 

편집 위의 정의는 (I 시험이 '/ 다음/다른 사람이있는 경우'에) 잘 보인다

1 ?- dsquare([[2],4,a],X). 
X = [[4], 16, a]. 

2 ?- dsquare([a,[3],[[[5]]],[2],a],X). 
X = [a, [9], [[[25]]], [4], a]. 
+0

당신이 말하는 것을보고 내 코드에 맞추 었습니다. 질문과 결과물에 새롭게 업데이트 된 코드를 게시하고 있습니다. –

+0

좋아, '상처'는 내가 지금 더 잘 이해할 수있는 무언가이다. 하지만 지금은 매우 재미있는 결과를 얻고 있습니다. dsquare ([a, [3], [[[5]], [2], a], X). X = [a, "", [[[25]], [4], a]; 일부 '심층'의 경우 그림과 같이 빈 공간이 생깁니다. 그것 이외의 모든 것은 좋아 보인다. –

+0

그것은 여전히 ​​나에게 특별히 [3]을위한 빈 공간을 제공하지만, 그렇지 않으면 그 모든 것이 좋습니다. 도와 줘서 고마워. 내가 공백을 위해 무엇을 할 수 있는지, 어쩌면 다른 프롤로그 컴파일러에서 시도해 보자. –

0

_Vxxx 비트는 프롤로그의 결과에서 언 바운드 변수를 나타냅니다. 기본적으로 심볼 테이블의 키 또는 주소입니다.첫 번째 규칙에서

  • ,

    dsquare([],S). 
    

    당신은 결코 두 번째 인수에 아무 구속력없는 것입니다. 즉, dsquare([],X)으로 호출하면 X는 언 바운드 상태로 유지됩니다. dsquare([1,2,3],X) (모든 항목이 제대로 작동한다고 가정하면 결과 목록 구조가 깨져서 X[1,2,3|_VD3DC]과 같을 것입니다. 가장 마지막 항목은 atome [] (빈 목록)이 아니거나 ./2이 아니기 때문에 비어 있지 않은 목록입니다. 두 번째 규칙에서

  • ,

    dsquare([H|T],[R|S]):- number(H), dsquare(T,S), R is H*H, !. 
    

      가 컷 ( !)는 사업자의
    • 주문에 불필요
    • 부정확하다. Square H를 먼저 누른 다음 아래로 재귀하십시오. 이는 두 가지를 수행합니다. 즉, (A)는 일찍 실패하고 (결과가 바인딩 된 경우), (B)는 테일 재귀 최적화를 적용 할 수 있습니다. 3 번째 규칙에서
  • , 당신은 소스 목록의 머리 인 하위 목록을 아래로 재귀하지만, 전혀 소스리스트의 꼬리를 평가하고 대신 단순히 폐기되지

    dsquare([H|T],S):- isList(H), dsquare(H,S). 
    

    그것. 당신의 4 규칙에

  • ,

    dsquare([H|T],[R|S]) :- dsquare(T,S), R = H, !. 
    

    다시, 두 번째 규칙으로, 절단은 불필요한이며, 작업의 순서는 반전.

나는 이런 식으로 뭔가를 써서 :

deep_square([]  , [] ) % squaring an empty list produces an empty list 
    . 
deep_square([X|Xs] , [Y|Ys]) :- % otherwise... 
    number(X) ,      % if the head is a number, 
    Y is X*X ,      % square it 
    deep_square(Xs,Ys)    % and recurse down 
    .        % 
deep_square([X|Xs] , [Y|Ys]) :- % otherwise... 
    nonvar(X) ,      % if the head is bound, 
    X = [_|_] ,      % and is a non-empty list. 
    deep_square(X , Y) ,   % deep square the head 
    deep_square(Xs , Ys)   % and then recurse down 
    . 
deep_square([X|Xs] , [X|Ys]) :- % otherwise the head is unbound or something other than a number or a non-empty list... 
    deep_square(Xs , Ys)   % recurse down. 
    .        % Easy! 

당신은 프롤로그의 조항의 머리에서 일어나는 통일 마술 (magick)과 (銅)의 많은이 있음을 알 수 있습니다 술부.

+0

아주 좋은 설명. 귀하의 의견을 따르고 이에 따라 제 코드를 수정했습니다. 나는 또한 당신의 주어진 발췌 문장을 사용했지만 그것은 나에게 기대되는 결과를주지 않았다. deep_square ([a, 2, [[3]], r], X). X = [a, 4, [ ""], r]; X = [a, 4, [[3]], r]; X = [a, 4, [[3]], r]; X = [a, 4, [[3]], r]; X = [a, 2, [ ""], r]; X = [a, 2, [[3]], r]; X = [a, 2, [[3]], r]; X = [a, 2, [[3]], r]; 이 실패합니다. –