2017-01-18 1 views
4

나는 내 마음을 많이 감쌌다. 는 역 추적이 형식의 목록을 생성하여 해당 스크립트를 만드는 것이 가능 :프롤로그 - 백 트랙에서 번갈아 나타나는 기호 생성 : [a]; [a, b]; [a, b, a]; [a, b, a, b]

[a] 
[a,b] 
[a,b,a] 
[a,b,a,b] 
... 

내가 한 번에 두 가지 요소를 생성 한 만들었을하지만 내 머리 "는 발생 하나를 만들려고 상처를하기 시작 "다음에"b "와 다음"a "등등. 항상 DCG 표기을 사용하는 것이 좋습니다 목록을 설명 할 때

ab([a]). 
ab([b,a|T]):-ab([a|T]). 
ab([a,b|T]):-ab([b|T]). 

답변

7

: 여기

는 한 번에 두 가지 요소의 스크립트입니다.

이렇게하면 많은 변수와 인수를 추가하지 않고 본질의 내용을 원하는대로 집중시키는 것이 매우 편리합니다.

예를 들어, 고려 :

 
abs --> [a], abs_rest. 

abs_rest --> []. 
abs_rest --> [b], ([] | abs). 

샘플 쿼리 및 답변 :

 
?- phrase(abs, ABs). 
ABs = [a] ; 
ABs = [a, b] ; 
ABs = [a, b, a] ; 
ABs = [a, b, a, b] ; 
ABs = [a, b, a, b, a] ; 
ABs = [a, b, a, b, a, b] . 

이 편리 형식주의에 대한 자세한 내용은 하세요!

+0

감사합니다. 흥미 롭다. 전에 우연히 발견되지 않았고 우리 대학의 과정에서 배워야하는 것은 아닙니다. 귀중한 정보입니다! 어쨌든 나는 재귀를 죽이고 스크립트를 만드는 법을 배우고 있으며 DCG가 내 시험에서 받아 들여지는지 확신 할 수 없기 때문에 여전히 전통적인 방법으로 해결책을 찾고 있습니다 :) –

+1

"전통적인 방법으로" 당신은 "덜 읽을 수있는 방법으로"를 의미합니다. 단순히 다음 쿼리를 사용하여 DCG에 상응하는 일반 Prolog 코드를 얻습니다 :'? - listing (abs // 0), listing (abs_rest // 0) .' , 당신의 강사에게 그것을 건네고, 당신이 아마 사용하지 못하는 더 나은 해결책이 있다는 것을 알아야합니다. 왜냐하면 똑같은 것을 표현하는 더 복잡한 방법이있을 때 왜 피팅 형식주의를 사용해야할까요? – mat

+0

전통이 내가 필요한 것을 설명하는 가장 적합한 단어는 아니 었습니다. 머리글, 꼬리 및 목록의 재귀 속성을 사용하여 작성된 것만 알아 내려고합니다. 이러한 방식으로 : ab ([a]). ab ([b, a | T]) : - ab ([a | T]). ab ([a, b | T]) : - ab ([b | T]). –

3

나는 하나가 가능한 경우 이러한 문제 유형에 대한 사용해야 @mat에 동의합니다.

다음은 다른 규칙 집합입니다.

abs --> [a]. 
abs --> [a,b]. 
abs --> [a,b], abs. 

?- phrase(abs, Ls). 
Ls = [a] ; 
Ls = [a, b] ; 
Ls = [a, b, a] ; 
Ls = [a, b, a, b] ; 
Ls = [a, b, a, b, a] ; 
Ls = [a, b, a, b, a, b] ; 
Ls = [a, b, a, b, a, b, a] ; 
Ls = [a, b, a, b, a, b, a, b] ; 
Ls = [a, b, a, b, a, b, a, b, a] 

는 흥미롭게도 그 규칙은, DCG를 사용하지 않으려면 Using Definite Clause Grammars in SWI-Prolog

에서 운동 중 하나입니다

abs2 --> []. 
abs2 --> [a]. 
abs2 --> [a,b], abs2. 

?- phrase(abs2, Ls). 
Ls = [] ; 
Ls = [a] ; 
Ls = [a, b] ; 
Ls = [a, b, a] ; 
Ls = [a, b, a, b] ; 
Ls = [a, b, a, b, a] ; 
Ls = [a, b, a, b, a, b] ; 
Ls = [a, b, a, b, a, b, a] ; 
Ls = [a, b, a, b, a, b, a, b] 

그때 내가 @mat 동의 및 제안이 변화에서 시작 표준 Prolog 구문에서 DCG를 보려면 listing/1을 사용합니다.

listing(abs). 

abs([a|A], A). 
abs([a, b|A], A). 
abs([a, b|A], B) :- 
     abs(A, B). 

listing(abs2). 

abs2(A, A). 
abs2([a|A], A). 
abs2([a, b|A], B) :- 
     abs2(A, B). 

정상 프롤로그 규칙으로 그들과 같은 사용할 수 있습니다

abs(X,[]). 
X = [a] ; 
X = [a, b] ; 
X = [a, b, a] ; 
X = [a, b, a, b] ; 
X = [a, b, a, b, a] ; 
X = [a, b, a, b, a, b] ; 
X = [a, b, a, b, a, b, a] 

abs2(X,[]). 
X = [] ; 
X = [a] ; 
X = [a, b] ; 
X = [a, b, a] ; 
X = [a, b, a, b] ; 
X = [a, b, a, b, a] ; 
X = [a, b, a, b, a, b] 
+1

당신이 링크하는 텍스트는 구식 인 용어를 사용하고 있습니다. 더 나은 유지 문서를 사용하십시오. – mat

+0

@mat 나는 'SWI-Prolog에서 Definite Clause Grammars 사용하기'를 언급하고있다. 나는 다른 비슷한 문제가 있음을 보여주기 위해 링크를 추가했습니다. 기본적으로 링크의 이유입니다. –

+0

감사의 말, 더 자세히 설명해 주셔서 감사합니다! –

1

당신이 쓴 술어는 너무 일반적입니다 :

?- ab([b,a]). 
true 

원인은 다음과 같은 규칙

ab([b,a|T]) :- 
    ab([a|T]). 
입니다

당신이 말할 수있는 것은 당신이 실제 문제에 대한 해결책이 아닌 중간 결과를 산출하십시오.ab 순서가 a로 시작하고 나머지 흉상은 ba 시퀀스가 ​​다시 ab 시퀀스에 의해 정의되는 ba 시퀀스 수보다이 문제를 해결하려면, 당신은 명시 수 : 또는

ab([a]). 
ab([a|Xs]) :- 
    ba(Xs). 

ba([b]). 
ba([b|Xs]) :- 
    ab(Xs). 

, 당신은 abs 생각할 수 마지막 요소가 b이고 그 반대 인 경우 이 a 인 상태 기계. 우리가 지난 앞에 추가 한 같은 ab 순서를 정의 이제

abs(a,[a]). 
abs(b,[b]). 
abs(a,[a|Xs]) :- 
    abs(b,Xs). 
abs(b,[b|Xs]) :- 
    abs(a,Xs). 

a : 우리가 역사를 추적하기 위해 추가 인수를 도입하는 경우 에서 우리는 도착

ab(Xs) :- 
    abs(a,Xs). 

재미 되세요 :)

관련 문제