LISP 모드 일치
Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp by Peter Norvig (1992)
이 책의 챕터5에서는 원조 챗봇의'ELIZA'가 Common Lisp로 작성됐고, 설치된 해설에 등장하는 패턴 매칭 처리(5.2 Pattern Matching)가 첫 번째 기호 처리 프로그래밍 애플리케이션의 예(편견)인 만큼 Scheme로 다시 쓰면서 풀었다.
실행 예
GNU Guile3.0.4 및 Gauche0.9.6을 통해 확인. 처리 시스템의 고유한 디스플레이를 생략하는 등.
> (load "./pattern-matching.scm")
> (pat-match '(i need a ?X) '(i need a vacation))
((?X . vacation))
> (sublis (pat-match '(i need a ?X) '(i need a vacation))
'(what would it mean to you if you got a ?X ?))
(what would it mean to you if you got a vacation ?)
> (pat-match '(i need a ?X) '(i really need a vacation))
#f
> (pat-match '(this is easy) '(this is easy))
((#t . #t))
> (pat-match '(?X is ?X) '((2 + 2) is 4))
#f
> (pat-match '(?X is ?X) '((2 + 2) is (2 + 2)))
((?X 2 + 2))
> (pat-match '(?P need . ?X) '(i need a long vacation))
((?X a long vacation) (?P . i))
함수를 구성하는 정의
변수 검사
여기에 머리에 있는 기호(기호)를 변수로 간주하기 때문에 먼저 기호가 변수인지 검사하는 함수를 정의합니다.
(define (variable? x)
(and (symbol? x)
(equal? (string-ref (symbol->string x) 0) #\?)))
?
는 기호를 문자열로 변환하는 함수이고, symbol->string
는 위치 정보string-ref
를 통해 문자열의 한 문자를 가져오는 함수이며, 0
는 문자#\?
를 나타내는 함수이다.상수 정의
?
를 연상 목록의 초기 값으로 정의하고 이 연상 목록은 일치하는 데 실패했을 때의 반환 값의 상수fail
를 성공적으로 일치하는 변수와 값의 집합(변수 제약)을 저장한다.(define fail #f)
(define no-bindings '((#t . #t)))
또한 연상 목록은 다른 프로그래밍 언어가 말하는 사전형과 연상 배열에 해당하며 보통 점대(내부는 제어 단위 구조)를 통해 키와 값 집합을 목록으로 하는 것을 말한다.변수 제약조건 유틸리티 함수
함수
((#t . #t))
는 연상 목록에서 변수 제약을 추출하고, 함수get-binding
는 변수 제약에서 값을 추출하며, 함수binding-val
는 변수 제약을 연상 목록에 추가한다.(define (get-binding var bindings) (assq var bindings))
(define (binding-val binding) (cdr binding))
(define (extend-bindings var val bindings)
(cons (cons var val)
(if (equal? bindings no-bindings) '() bindings)))
변수 구속조건 확인
변수가 나타날 때의 처리: 제약 값이 없으면 연상 목록에 새로운 변수를 추가합니다. 제약 값이 있으면 현재 대응하는 값과 비교하고 같으면 연상 목록을 직접 되돌려주고 다르면'일치 실패'로 되돌려줍니다
extend-bindings
.(define (match-variable var input bindings)
(let ((binding (get-binding var bindings)))
(cond ((not binding) (extend-bindings var input bindings))
((equal? input (binding-val binding)) bindings)
(else fail))))
패턴 일치 처리 바디
첫 번째 파라미터로 도안을 표시하고 두 번째 파라미터를 일치 처리하는 대상을 지정하며 세 번째 파라미터에 변수가 결합된 집합을 저장하는 연상 목록을 지정한다.
(define (pat-match pattern input . r)
(let ((bindings (if (null? r) no-bindings (car r))))
(cond ((eq? bindings fail) fail)
((variable? pattern)
(match-variable pattern input bindings))
((equal? pattern input) bindings)
((and (pair? pattern) (pair? input))
(pat-match (cdr pattern) (cdr input)
(pat-match (car pattern) (car input)
bindings)))
(else fail))))
처리 주체로서 첫 번째 파라미터와 두 번째 파라미터는 첫 번째 호출할 때와 마찬가지로 목록의 상황fail
이고 첫 번째 파라미터와 두 번째 파라미터가 각 목록의 같은 위치의 요소의 일치 처리라고 가정하는 두 가지 처리.첫 번째 파라미터와 두 번째 파라미터 중의 모든 시작 요소를 추출하여 자신을 호출하여 후자의 일치 처리를 하고 연상 목록에서 결과를 받는 변수의 속박을 받는 동시에 각 목록에 남은 패턴의 일치 처리를 하기 위해 자신을 호출한다.프로그램 코드 한 세트
※ Common Lisp
(and (pair? pattern) (pair? input))
에 해당하는 것은 (왜) 발견되지 않았기 때문에 실행례에 적절한 자제품을 사용했습니다.pattern-matching.scm
;;;;
;;;; Pattern Matching example
;;;; ported from Section 5.2 at https://github.com/norvig/paip-lisp
;;;;
(define (variable? x)
(and (symbol? x)
(equal? (string-ref (symbol->string x) 0) #\?)))
(define (sublis al L)
(if (null? L) '()
(cons (let ((r (assq (car L) al)))
(if r (cdr r) (car L)))
(sublis al (cdr L)))))
(define fail #f)
(define no-bindings '((#t . #t)))
(define (get-binding var bindings) (assq var bindings))
(define (binding-val binding) (cdr binding))
(define (extend-bindings var val bindings)
(cons (cons var val)
(if (equal? bindings no-bindings) '() bindings)))
(define (match-variable var input bindings)
(let ((binding (get-binding var bindings)))
(cond ((not binding) (extend-bindings var input bindings))
((equal? input (binding-val binding)) bindings)
(else fail))))
(define (pat-match pattern input . r)
(let ((bindings (if (null? r) no-bindings (car r))))
(cond ((eq? bindings fail) fail)
((variable? pattern)
(match-variable pattern input bindings))
((equal? pattern input) bindings)
((and (pair? pattern) (pair? input))
(pat-match (cdr pattern) (cdr input)
(pat-match (car pattern) (car input)
bindings)))
(else fail))))
총결산
처리 변수 제약과 목록 요소의 순서 처리로 인해 이번 예는 실질적으로'언어 처리'의 일종이라고 할 수 있다. 책에서는 더욱 발전된 처리를 사용하여chatbot(위조 대화 프로그램)을 구성한다.
시험을 준비하다
문장의 보충
댓글이 없는 것은 고의(^^;)입니다.코드가 우선이기 때문에 예견성이 좋지만, 아래에서 위로 & 증량식으로 생각하면 어떨까...
책에서 Chapter11은 더욱 발전하여 Proog 해석기를 실현했다. 이전 글와 마찬가지로 다른 프로그래밍 언어도 Proloog 해석기를 실현할 수 없습니까? 매크로를 사용하는 곳이 엄격합니까?
역사를 갱신하다
Reference
이 문제에 관하여(LISP 모드 일치), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ytaki0801/articles/54bfdd24967f8de50f91텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)