문법을 통해 어떤 계산 모델을 표현할 수 있습니까?


18

이것은 문법 프로그램입니까? 의 재구성입니다 . Vag가 이전에 요청했으며 주석 작성자의 많은 제안이 있습니다.

문법은 어떤 방식으로 계산 모델을 지정하는 것으로 볼 수 있습니까? 예를 들어 다음과 같은 간단한 문맥없는 문법을 사용하는 경우

G ::= '1' -> '0' '+' '1'
      '1' -> '1' '+' '0'
      '2' -> '2' '+' '0'
      '2' -> '1' '+' '1'
      '2' -> '0' '+' '2'
      '3' -> '3' '+' '0'
      '3' -> '2' '+' '1'
      '3' -> '1' '+' '2'
      '3' -> '1' '+' '2'

파서가 여기에서 설명한 것처럼 터미널비 터미널 기호를 구분하지 않는다고 가정하면 최대 3의 숫자에 대해 간단한 산술을 수행 할 수 있습니다.

예를 들어, 문자열을

"2 + 0 + 1"

이 문자열에서 LR (1) 파서를 실행 하면 계산 결과가 트리의 루트에 저장되는 다음과 같은 구체적인 구문 트리 가 제공됩니다.

           '3'
         /  |  \
        /   |   \
      '2'  '+'  '1'
     / | \
    /  |  \
  '2' '+' '0' 

따라서 문법을 프로그램 으로, 파서 생성기를 컴파일러로 사용 하면 문법 사양 언어를 프로그래밍 언어로 볼 수 있습니까?

또한 celullar automata 또는 lambda calculus를 사용 하여 튜링 완료 프로그램을 빌드하는 방법과 유사한 문법을 ​​지정하여 튜링 완료 프로그램을 작성할 수 있습니까?

바꾸어 말하면, 언어 를 인식 한다는 의미에서 , 정규 언어유한 상태 오토마타에 대응하고 , 문맥이없는 언어는 오토마타푸시 다운 하고, 문맥에 민감한 언어선형 경계 오토마타에 대응하는 것으로 알려져있다 . 그러나 문법을 계산 장치 ( 위의 예에서 의미하는 프로그램 )로 보는 경우 Chomsky 계층 구조에서 각 문법 클래스의 계산 강도 를 어떻게 분류 합니까?

또한 문법의 하위 클래스 (예 :

편집 : 그건 그렇고, 이것은 내 자신의 질문에 대한 이쑤시개이지만 나는 예제 문법에 대한 시작 상징을주지 않았고 터미널과 비 터미널을 구별 할 필요성에 수동으로 흔들렸다는 언급은하지 않았다. 기술적으로 또는 전통적으로 나는 문법이 아마도 다음과 같은 좀 더 복잡한 형태로 작성되어야한다고 생각합니다 (여기서 S는 시작 기호이고 $ 는 스트림 끝 터미널을 나타냄).

G ::= S -> R0 '$'
      S -> R1 '$'
      S -> R2 '$'
      R0 -> '0'
      R0 -> R0 '+' '0'
      R1 -> '1'
      R1 -> R0 '+' '1'
      R1 -> '1' '+' R0
      R1 -> R0 '+' '1' '+' R0
      R2 -> '2'
      R2 -> R0 '+' '2'
      R2 -> '2' '+' R0
      R2 -> R0 '+' '2' '+' R0
      R2 -> R1 '+' '1'
      R2 -> R1 '+' '1' '+' R0

... 아무것도 바뀌지 않지만 언급해야한다고 생각했습니다.

편집 : gasche의 대답을 읽을 때 염두에 두었던 것은 내 예제에서 트리의 각 분기가 하위 계산을 나타냅니다. 각 생산 규칙을 ​​LHS가 결과를 나타내고 RHS가 인수를 나타내는 함수로 보는 경우 문법 구조에 따라 함수 구성 방법이 결정됩니다.

다시 말해, 파서의 lookahead 메커니즘과 함께 어떤 함수를 적용 할 것인지 (parametric polymorphism과 같은 'kinda')뿐만 아니라 새로운 함수를 형성하기 위해 어떻게 구성해야하는지 결정하는 데 도움이됩니다.

적어도, 나는 당신이 그것을 모호하지 않은 CFG에 대해 이런 식으로 볼 수 있다고 생각합니다. 다른 문법에 대해서는 정신 체조가 지금 나에게 조금 너무 많습니다.


3
당신은 사랑스럽고 유망한 기기 인 Visibly Pushdown Automaton (Nested Words)을 언급하는 것을 잊었습니다! 대중적인 프로그래밍 언어로 작성된 프로그램을 구문 분석 할 수 있도록 정규 표현식보다 최소한의 개선이 필요한 것이므로 중요합니다. ( cis.upenn.edu/~alur/nw.html )
Vag

1
고마워, 그것은 매우 흥미 롭다, 나는 그것을 보지 않았다! 나는 또한 결정적 문맥 자유, 나무 인접한 그래서, 난 그냥 조금 한 질문에 대해 많은 비트 될 줄 알았는데 색인 ...하지만 어쩌면 내가 그들을 추가 할 것 같은 생략 다른 사람의 몇 가지있다
Rehno Lindeque

1
@imz 문법적으로 chomsky 계층 구조 (즉, 프로덕션 집합으로 정의 됨)를 의미합니다. 나는 당신이 말하는 것을 정확하게 주장하고 있기 때문에 : 문법은 프로그램이라는 것은 문법으로 표현할 수있는 프로그램 클래스를 의미합니다 (질문입니다).
Rehno Lindeque

1
@imz 솔직히 말해서 나는 인덱스 문법에 익숙하지 않다. 나는 단지 그것들을 나중에 생각할 때만 추가했다.
Rehno Lindeque

1
이 질문을 LtU 포럼에 게시하는 대신 멋진 토론을 보는 것이 좋을 것이라고 생각하기 시작했습니다. : P. Btw @imz, 아마도 "문크 함만의 대답에서 Jukka에 의해 기술 된 '기능적'의미의 어떤 프로그램 클래스와 어떤 문법 클래스가 대응 하는가"로 질문을 읽는 것이 가장 좋을 것입니다. 아마 나는 이것을 좀 더 분명하게해야한다.
Rehno Lindeque

답변:


10

Chomsky Type-0 문법 과 Turing 기계 사이에는 일대일 대응이 있습니다.

이것은 Thue 프로그래밍 언어로 탐색되어 초기 문자열 및 일련의 문자열 다시 쓰기 규칙 ( 반 -Thue 문법 , 유형-0 문법과 동일)으로 지정된 Turing-complete 프로그램을 작성할 수 있습니다 .

최신 정보:

Thue와 같은 난해한 "Turing tar-pit"언어 외에도 프로그래머가 구문을 확장 할 수있는 다양한 범용 언어를 사용하여 구문 분석 컴파일 단계에서 Turing-complete 계산을 수행 할 수 있습니다.

Lisp 패밀리의 언어 , 특히 Common Lisp 는 아마도 가장 명백한 예일뿐만 아니라 템플릿이 포함 된 C ++ , ScalaQi 와 같이 항상 정지 할 필요가없는 정적 유형 검사를 사용하는 언어 일 것입니다 .


그러나 문제는 다른 방식으로 작동하는 것에 관한 것입니다. 하나는 규칙에 따라 초기 기호 시퀀스를 다시 쓰지 않고 결과에 도달해야하지만이 질문에서 문법으로 정의 된 계산의 "결과"는 초기입니다 문법 규칙에 따라 "입력"시퀀스를 생성 할 수있는 기호.
imz-Ivan Zakharyaschev

2
그러나 올바르게 이해하면 두 가지가 본질적으로 동일합니다. 고정 된 초기 기호에서 시작하여 문법이 입력 시퀀스를 생성 할 수있는 경우 해당 Turing 기계가 해당 시퀀스를 수락합니다. 수락 / 거부 이외의 결과를 반환하지만 여전히 유한 세트에있는 계산을 고려하려면 초기 기호의 비 결정적 선택을 추가해야합니다 (실제로 이는 추가 규칙 일뿐입니다). 무한 세트로 결과를 허용하려면 문자열 를 생성하는 문법을 정의 할 수 있습니다영형(영형이자형(나는),영형)미디엄(나는)=영형

Type0 문법과 TM 간의 대응이 질문에 대한 올바른 답변이라는 데 동의합니다 (특히 예 / 아니오 함수 계산으로 제한되는 경우). 입력-출력 쌍을 나타내는 방법을 소개하여 문법으로 임의의 TM을 모델링하는 추가 제안은 원래 질문의 의도 된 관심과 일치하지 않는 것 같습니다 : (계속)
imz-Ivan Zakharyaschev

나는 기존 문법 프레임 워크와 계산을 수행하기 위해 해당 파서를 정확하게 활용하는 것에 대한 질문으로 이해합니다. 즉, 함수 f와 문법 사이의 허용되는 변환 형식은 다음과 같습니다. I) = S.
imz-Ivan Zakharyaschev

1
표면적으로 Thue 프로그래밍 언어는 문법 프레임 워크를 사용하는 이런 종류의 언어에 속하지 않는 것 같습니다. 문법과 같이 규칙을 다시 작성하더라도 입력 결과 계산은 규칙이 아닌 반대 방향으로 진행됩니다. 레노가 원하는 방향으로. (그러나 아마도 프로덕션에서 화살표의 방향을 바꾸는 것의 문제 일뿐입니다.이 Q의 의미에서 "파서로 계산"문법을 Thue로 변환하는 것은 규칙의 방향을 변경 한 다음 Thue 프로그램 만 변경할 수 있습니다 실제로 결과로 시작 기호에 도달합니다. ...)
imz-Ivan Zakharyaschev

6

내 대답은 공식적이고 정확하며 절대적으로 주제가 아닙니다. Marc Hamman의 대답은 확실하다고 생각하지만 귀하의 질문으로 인해 관련 주제를 생각하게되었습니다.

문법은 연역적 시스템의 특수한 경우로 간주 될 수 있습니다. 입력은 판단이고, 구문 분석 트리는 판단 의 파생 이거나 (문법) 규칙에 따라 판단이 유효하다는 증거 입니다.

그런 의미에서 귀하의 질문은 논리 프로그래밍 / 증거 검색 커뮤니티 ( 예를 들어 Dale Miller 를 생각하고 있습니다)의 일부 접근 방식과 관련이있을 수 있습니다. 즉, 증거 검색 에는 더 고전적인 것이 아니라 계산 내용이 있습니다. 계산이 증명 정규화 인 유형 / 증거 이론 관점 .

비고 : 내 대답을 다시 읽으면 "파서 트리 구성은 증거 검색"이라는 아이디어가 여기에서 조금 많이 나온 것 같습니다. 증명 검색은 오히려 다른 방향으로 진행됩니다. 하나는 다소 복잡한 판단에서 시작하고 증거의 구조에 대한 추론 규칙을 반복적으로 사용함으로써 더 이상 입증 할 필요가없는 간단한 공리를 얻습니다. 따라서 문법적으로 비 터미널로서의 복잡한 판단, 터미널로서의 원자, 단어 생성 문제로서의 증거 검색 또는 비-비만 테스트를 보는 것이 더 자연 스러울 것입니다.


그래도 매우 흥미로운 말입니다. 내 뇌는 지금 당장 좋은 반응을하기에는 너무 피곤하지만, 나의 예에서 나무의 가지들은 본질적으로 파싱 규칙에 따라 함께 구성된 하위 계산을 나타냅니다 ...
Rehno Lindeque

6

또한 문법을 ​​지정하여 Turing-complete 프로그램을 만들 수 있습니까?

내가 제대로 질문을 이해 있는지 확실하지 않습니다,하지만 당신은 문자열이 시스템을 재 작성의 종류에 따라 프로그래밍 언어를 찾고 있다면, 당신은 아마 둘다 될 Refal 을 기반으로, 마르코프 알고리즘 형식주의 (A Turing- 문법과 유사한 문자열 재 작성 시스템이기도합니다.


1
나는 다음과 같은 방식으로 그 질문을 이해했다 : Rehno는 결과 계산으로 볼 수있는 bootom-up 파싱 프로세스 (문법으로 정의)에 관심이있다. 계산은 문법의 생산 규칙과 반대 방향으로 진행되는 부분의 결과를 만들어야합니다. Refal의 재 작성 규칙 (IIUC, 위에서 언급 한 Thue 프로그래밍 언어와 유사)은 다른 방향 (입력에서 결과로)으로 진행됩니다.
imz-Ivan Zakharyaschev

문맥에 맞는 문법은 생산 규칙의 LHS에서 하나 이상의 기호를 갖습니다. 실제적인 차이는 없다고 생각합니다. 상황에 맞는 언어의 구문 분석기는 어떻게 보더라도 문자열 재 작성 시스템입니까?
Rehno Lindeque

@imz Rehno의 질문에 대한 설명을 해주셔서 감사합니다. @Rehno“컨텍스트에 민감한 언어를위한 파서는 어떻게 보든지 상관없이 문자열 재 작성 시스템일까요?”— 아마도 말이됩니다.
Artem Pelenitsyn

그러나 Refal의 재 작성 규칙은 비 결정적으로 처리됩니까? (또는 다르게 : Refal은 작업중인 재 작성 경로를 검색 할 때 역 추적을 수행 할 것인가?)이 "계산 분석"접근 방식을 반대 방향으로 재 작성 규칙으로 모델링하려면 비 결정적 규칙이 필요하다. 와 같은 문법을 고려하십시오 S -> A a; S -> B b; A -> 0; B -> 0. 규칙을 반대로하여이를 프로그래밍하는 경우 0"0a"또는 "0b"를로 평가하려면 런타임 에 처리 할 다른 규칙을 선택해야 합니다 S.
imz-Ivan Zakharyaschev

6

(단지 사소한 고려 사항입니다. 의견이 될 수 있지만 너무 깁니다.)

실제로, 당신이 묘사하는 것은 언어가 무엇인지 ( "언어"에 대한 인간의 이해에서) 언어가 문법을 어떻게 정의하는지 에 대한 매우 자연스러운 견해로서 효과적 입니다.

언어는 의미 론적 가치를 부여하기 위해 해석 되는 (무한한 많은) 올바른 구문 형태로 구성 됩니다 .

해석이 계산 가능한 경우, 언어의 구문 형태는 시맨틱 값을 계산하는 프로그램으로 볼 수 있습니다.

언어가 유한 장치로 구현되었다고 가정하면이 유한 언어 표현을 "문법"이라고 부를 수 있습니다. 이 이해에 따르면, 문법은 구문뿐만 아니라 의미론에도 관심이 있습니다. 즉, 부분 값 (원자 부분과 그 값이 "어휘집"에 저장 됨)에서 전체 표현식의 의미론 값을 계산하는 방법 .

자연 언어에 대한 일부 이론은 그러한 형태 (위의 고려 사항과 일치하는 형태입니다; @gasche의 답변에서 이미 언급되었습니다) : 입력의 파생을 검색 하는 연역 시스템 (의미론의 계산과 결합 됨) 가치 또는 증명 용어의 구축; 카레-하워드 서신 참조). 따라서, 우리가 그런 시스템을보고 문법을 고려 한다면, 당신의 질문은 사소한 것입니다 :이 시스템은 당신이 묘사 한 방식으로 계산을 수행하도록 정확하게 고안되었습니다.

에프나는 에프(나는)=에스나는에스

(실제로 프로그래밍 언어의 실제 컴파일러는 구문과 의미가 모두있는 시스템과 비슷합니다. 프로그램의 구문 형식을 실행 파일로 변환합니다. 이는 프로그램의 의미 적 의미가 아니라 시작 기호가 아닙니다. 문법의.)


4

추가하기 만하면됩니다.

순수한 논리 프로그램에는 선언적 읽기와 절차 적 읽기가 있습니다. 이 보고서는 문법을 다시 작성하는 것으로 간주되는 문법 읽기로 보완 할 수 있다는 아이디어를 논의합니다. 이 관점은 로직 프로그래밍에서 프로그래밍 언어에 대한 다른 연구로 전문 지식의 이전을 용이하게하고 그 반대도 가능하다는 것을 보여주기위한 것입니다. 이러한 이전과 같은 일부 예가 논의됩니다. 반면에 제시된 문법적 관점은 순수한 로직 프로그래밍에 대한 일부 임시 확장을 정당화하고 그러한 확장에 대한 이론적 기초의 개발을 용이하게합니다.

Pierre Deransart와 Jan Maluszynski 의 논리 프로그래밍의 문법적 관점.


분명히 Prolog는 속성 문법에서 생겨 났으므로이 관점은 논리 프로그래밍을 시작한 것입니다.
reinierpost

1

Peano 번호와 같은 것은 어떻습니까?

S    -> int
int  -> zero
int  -> succ
zero -> "0"
succ -> "#" int

다음 형식의 문자열 (숫자)을 인식합니다.

0   // zero
#0  // one
##0 // two

깊이가 숫자 인 중첩 구조를 반환해야합니다.

그러나 추가를 구현하려고 할 때 복잡해지기 시작합니다.

S    -> int
int  -> sum
int  -> zero
int  -> succ
zero -> "0"
succ -> "#" int
sum  -> int "+" int

다음과 같이 잘 구성된 정수만 인식한다는 점에서 완벽하게 이해됩니다.

#####0 + ####0

그러나이 문법은 합계가있을 때마다 구문 분석 트리에서 분할을 도입하므로 숫자에 직접 매핑되는 멋진 1 분기 트리를 사용하는 대신 표현식의 구조를 가지지 만 여전히 효과적인 계산에서 몇 가지 계산 값. 따라서 계산이 수행되지 않고 인식 만 수행됩니다. 문제는 문법이 아니라 파서 일 수 있습니다. 대신 다른 것을 사용할 수도 있습니다. idk ... 기억해야 할 또 다른 요점은 계산을 표현하기위한 문법 형식의 적절성입니다. Peano의 공리를 볼 때 (Haskell과 같은 표기법으로) :

1) Nat = Zero
2) Nat = Succ Nat
3) Sum ( Succ X ) ( Y ) = Succ ( X + Y )
4) Sum Zero X = X

세 번째 규칙은 명시 적으로 변환을 나타냅니다. 누구나 문맥이없는 문법 규칙에서 같은 양의 의미를 가지고 있다고 상상할 수 있습니까? 그렇다면 어떻게!?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.