로직 프로그래밍과 관련하여 Prolog와 miniKanren의 주요 기술적 차이점은 무엇입니까? [닫은]


124

논리 프로그래밍에 대해 읽고 싶을 때 요즘에는 항상 두 가지 "주요"방법을 우연히 발견했습니다.

  • The Reasoned Schemer에 소개 된 미니 언어 인 miniKanren은 core.logic 으로 인해 현재 인기가 있습니다.
  • Prolog , 최초의 "큰"논리 프로그래밍 언어입니다.

내가 지금 관심있는 것은 : 둘 사이의 주요 기술적 차이점은 무엇입니까? 접근 방식과 구현이 매우 유사합니까, 아니면 논리 프로그래밍에 대해 완전히 다른 접근 방식을 취합니까? 수학의 어떤 분야에서 왔으며 이론적 기초는 무엇입니까?


3
이 질문이 닫혀서 슬프다. 매우 일관된 답변과 많은 수의 찬성 투표에서 알 수 있듯이 이것은 완벽하게 유용한 질문입니다. 나는 .... 다시 투표를
nealmcb을

한때 많은 업 보트와 함께 주제에 관한 @nealmcb 질문이 더 이상 없을 수 있습니다.
Tiago Martins Peres 李大仁

답변:


281

먼저, 귀하의 훌륭한 pw0n1e 아이콘에 대해 칭찬하겠습니다.

이것은 miniKanren과 Prolog의 변형이 너무 많기 때문에 대답하기 까다로운 질문입니다. miniKanren과 Prolog는 실제로 언어 군이므로 기능을 비교하거나 실제로 사용하는 방법을 비교하기가 어렵습니다. 이 때문에 제가 말하고자하는 모든 것을주의해서 취하십시오. Prolog가 깊이 우선 검색을 사용한다고 말하면 많은 Prolog 구현이 다른 검색 전략을 지원하고 대체 검색 전략도 메타에서 인코딩 될 수 있음을 유의하십시오. -통역사 수준. 그럼에도 불구하고 miniKanren과 Prolog는 서로 다른 디자인 철학을 가지고 있으며 서로 다른 절충안을 만듭니다.

Prolog는 상징적 인공 지능 프로그래밍을위한 두 가지 고전적인 언어 중 하나입니다 (다른 고전적인 언어는 Lisp입니다). Prolog는 선언적 지식이 1 차 논리로 인코딩되는 상징적 규칙 기반 시스템을 구현하는 데 탁월합니다. 언어는 이러한 유형의 응용 프로그램에 대한 표현력과 효율성에 최적화되어 있으며 때로는 논리적 순도를 희생합니다. 예를 들어, 기본적으로 Prolog는 통합에서 "발생 확인"을 사용하지 않습니다. 수학 / 논리적 관점에서 볼 때이 통합 버전은 올바르지 않습니다. 그러나 발생 확인은 비용이 많이 들고 대부분의 경우 발생 확인이 부족해도 문제가되지 않습니다. 이것은 Prolog의 깊이 우선 검색 사용과 컷 () 사용과 마찬가지로 매우 실용적인 디자인 결정입니다.!)를 사용하여 역 추적을 제어합니다. 나는 이러한 결정이 1970 년대의 하드웨어에서 실행될 때 절대적으로 필요했으며 오늘날 큰 문제를 처리 할 때나 거대한 (종종 무한한!) 검색 공간을 다룰 때 매우 유용하다고 확신합니다.

프롤로그는 다음을 사용하여 산술을위한 변수의 자르기 assertretract투영을 포함하여 많은 "비논리적"또는 "비논리적"기능 을 지원합니다.is, 기타 등등. 이러한 기능 중 다수는 복잡한 제어 흐름을보다 쉽게 ​​표현하고 Prolog의 글로벌 사실 데이터베이스를 조작 할 수 있도록합니다. Prolog의 매우 흥미로운 기능 중 하나는 Prolog 코드가 사실의 글로벌 데이터베이스에 자체적으로 저장되고 런타임에 쿼리 할 수 ​​있다는 것입니다. 따라서 해석중인 Prolog 코드의 동작을 수정하는 메타 인터프리터를 작성하는 것은 간단합니다. 예를 들어, 검색 순서를 변경하는 메타 인터프리터를 사용하여 Prolog에서 폭 우선 검색을 인코딩 할 수 있습니다. 이것은 Prolog 세계 밖에서는 잘 알려지지 않은 매우 강력한 기술입니다. 'The Art of Prolog'는이 기술을 자세히 설명합니다.

대부분이 Warren Abstract Machine (WAM)을 기반으로하는 Prolog 구현을 개선하는 데 엄청난 노력을 기울였습니다. WAM은 값이 논리 변수에 파괴적으로 할당되는 부작용 모델을 사용하며 이러한 부작용은 역 추적시 취소됩니다. WAM의 지침을 확장하여 Prolog에 많은 기능을 추가 할 수 있습니다. 이 접근 방식의 한 가지 단점은 WAM에 대한 확실한 이해없이 Prolog 구현 문서를 읽기 어려울 수 있다는 것입니다. 반면에 Prolog 구현자는 구현 문제를 논의하기위한 공통 모델을 가지고 있습니다. 병렬 프롤로그에 대한 많은 연구가 있었고 1990 년대 안도라 프롤로그에서 정점에 이르렀습니다. 이러한 아이디어 중 적어도 일부는 Ciao Prolog에 있습니다. (Ciao Prolog는 흥미로운 아이디어로 가득 차 있으며 그 중 상당수는 Prolog 표준을 훨씬 뛰어 넘습니다.)

Prolog는 매우 간결한 프로그램을 생성하는 아름다운 통합 기반 "패턴 일치"스타일 구문을 가지고 있습니다. Prologers는 Lispers가 s- 표현식을 좋아하는 것처럼 구문을 좋아합니다. Prolog에는 표준 술어의 방대한 라이브러리도 있습니다. WAM을 빠르게 만드는 모든 엔지니어링으로 인해 매우 유능하고 성숙한 Prolog 구현이 있습니다. 결과적으로 많은 대규모 지식 기반 시스템이 전적으로 Prolog로 작성되었습니다.

miniKanren은 작고 이해하기 쉽고 해킹하기 쉬운 구현으로 최소 논리 프로그래밍 언어로 설계되었습니다. miniKanren은 원래 Scheme에 포함되었으며 지난 10 년 동안 수십 개의 다른 호스트 언어로 포팅되었습니다. 가장 인기있는 miniKanren 구현은 Clojure의 'core.logic'으로, 현재 Prolog와 유사한 확장 기능과 여러 최적화 기능이 있습니다. 최근에 miniKanren 구현의 핵심이 더욱 단순화되어 "microKanren"이라고하는 작은 "마이크로 커널"이 만들어졌습니다. 그런 다음이 microKanren 코어 위에 miniKanren을 구현할 수 있습니다. microKanren 또는 miniKanren을 새로운 호스트 언어로 이식하는 것은 miniKanren을 배우는 프로그래머에게 표준 연습이되었습니다. 그 결과

miniKanren 및 microKanren의 표준 구현에는 한 가지 예외를 제외하고 돌연변이 나 기타 부작용이 없습니다. 일부 버전의 miniKanren은 논리 변수 비교를 위해 포인터 동등성을 사용합니다. 많은 구현에서 카운터를 구현에 전달하여이 효과조차 피할 수 있지만 저는 이것을 "양호한 효과"라고 ​​생각합니다. 글로벌 사실 데이터베이스도 없습니다. miniKanren의 구현 철학은 함수형 프로그래밍에서 영감을 얻었습니다. 돌연변이와 효과는 피해야하며 모든 언어 구성은 어휘 범위를 존중해야합니다. 구현을주의 깊게 살펴보면 몇 가지 모나드를 발견 할 수도 있습니다. 검색 구현은 다시 한 번 변형을 사용하지 않고 지연 스트림을 결합하고 조작하는 것을 기반으로합니다. 이러한 구현 선택은 Prolog 에서와는 매우 다른 트레이드 오프로 이어집니다. Prolog에서 변수 조회는 일정한 시간이지만 역 추적에는 부작용을 취소해야합니다. miniKanren에서 변수 조회는 더 비싸지 만 역 추적은 "무료"입니다. 실제로 miniKanren에는 스트림 처리 방식으로 인해 역 추적이 없습니다.

miniKanren 구현의 한 가지 흥미로운 측면은 코드가 본질적으로 스레드로부터 안전하고 적어도 이론적으로는 거의 병렬화 할 수 있다는 것입니다. 물론 각 스레드 또는 프로세스에 병렬화 오버 헤드를 보충 할 수있는 충분한 작업을 제공해야 하므로 속도를 늦추지 않고 코드를 병렬화하는 것은 쉬운 일이 아닙니다. 그럼에도 불구하고 이것은 내가 더 많은 관심과 실험을 받기를 희망하는 miniKanren 구현 영역입니다.

miniKanren은 통합을 위해 발생 확인을 사용하고 깊이 우선 검색 대신 완전한 인터리빙 검색을 사용합니다. 인터리빙 검색은 깊이 우선 검색보다 더 많은 메모리를 사용하지만 깊이 우선 검색이 영원히 분기 / 루프되는 경우에 답을 찾을 수 있습니다. miniKanren는 않는 몇 가지 추가 - 논리 연산자 --- 지원 conda, conduproject, 예를. conda그리고 condu프롤로그 컷을 시뮬레이션하는 데 사용 될 수 있으며, project논리 변수와 관련된 값을 취득 할 수 있습니다.

의 존재 conda, condu그리고project--- 그리고 검색 전략을 쉽게 수정할 수있는 능력 --- 프로그래머가 miniKanren을 임베디드 Prolog와 유사한 언어로 사용할 수 있도록합니다. 이것은 Prolog와 유사한 많은 확장을 포함하는 Clojure의 'core.logic'사용자에게 특히 그렇습니다. miniKanren의 이러한 "실용적인"사용은 산업에서 miniKanren의 사용 대부분을 설명하는 것으로 보입니다. Clojure, Python 또는 JavaScript로 작성된 기존 애플리케이션에 지식 기반 추론 시스템을 추가하려는 프로그래머는 일반적으로 Prolog에서 전체 애플리케이션을 다시 작성하는 데 관심이 없습니다. Clojure 또는 Python에 작은 논리 프로그래밍 언어를 포함하는 것이 훨씬 더 매력적입니다. 임베디드 Prolog 구현은 아마도이 목적을 위해 잘 작동 할 것입니다.

MiniKanren을 Prolog와 유사한 실용적인 임베디드 논리 프로그래밍 언어로 사용하는 것 외에도, miniKanren은 "관계형"프로그래밍 연구에 사용되고 있습니다. 즉, 수학적 기능이 아닌 수학적 관계로 동작하는 프로그램을 작성하는 것입니다. 예를 들어 Scheme에서 append함수는 두 개의 목록을 추가하여 새 목록을 반환 할 수 있습니다. 함수 호출 (append '(a b c) '(d e))은 list를 반환합니다 (a b c d e). 그러나 우리는 또한 append두 인수 함수가 아닌 세 자리 관계로 취급 할 수 있습니다 . (appendo '(a b c) '(d e) Z)그런 다음 호출 은 논리 변수 Z를 목록과 연관시킵니다 (a b c d e). 물론 논리 변수를 다른 위치에 배치하면 상황이 더 흥미로워집니다. 통화가 (appendo X '(d e) '(a b c d e))와 연결 X되고 (a b c)통화가(appendo X Y '(a b c d e))연결 XY추가 될 때와 동일한 목록 쌍 과 연결 됩니다 (a b c d e). 예를 들어 X= (a b)Y= (c d e)는 이러한 값 쌍 중 하나입니다. 우리는 또한 (appendo X Y Z)무한히 많은 트리플의리스트를 생성 할 수 X있고 Y, Z추가하는 X것은 Y생성 하는 것을 작성할 수 Z있습니다.

이 관계형 버전은 appendProlog에서 쉽게 표현할 수 있으며 실제로 많은 Prolog 자습서에 표시됩니다. 실제로 더 복잡한 프롤로그 프로그램은 결과 프로그램을 관계로 처리하는 기능을 방해하는 절단과 같은 몇 가지 추가 논리 기능을 사용하는 경향이 있습니다. 대조적으로, miniKanren은 이러한 스타일의 관계형 프로그래밍을 지원하도록 명시 적으로 설계되었습니다. miniKanren의 최신 버전은 (상징적 제약 조건 해결을위한 지원을 symbolo, numbero,absento, 불평등 제약, 명목 논리 프로그래밍) 관계로 사소하지 않은 프로그램을 더 쉽게 작성할 수 있습니다. 실제로 저는 miniKanren의 비논리적 기능을 전혀 사용하지 않으며 모든 miniKanren 프로그램을 관계로 작성합니다. 가장 흥미로운 관계형 프로그램은 Scheme의 하위 집합에 대한 관계형 인터프리터입니다. 이 인터프리터는 목록으로 평가되는 백만 개의 Scheme 프로그램을 (I love you)생성하거나 quines (자신을 평가하는 프로그램)을 사소 하게 생성하는 것과 같은 많은 흥미로운 능력을 가지고 있습니다 .

miniKanren은 프롤로그가 만드는 트레이드 오프와는 매우 다른 이러한 관계형 프로그래밍 스타일을 가능하게하기 위해 많은 트레이드 오프를합니다. 시간이 지남에 따라 miniKanren은 더 많은 상징적 제약 조건을 추가하여 실제로 상징적 지향적 제약 논리 프로그래밍 언어가되었습니다. 많은 경우에 이러한 상징적 인 제약은 실제와 같은 여분의 논리 연산자를 사용하지 않도록 할 수 있도록 condu하고 project. 다른 경우에는 이러한 기호 제약이 충분하지 않습니다. 상징적 제약에 대한 더 나은 지원은 관계로 더 크고 복잡한 프로그램을 작성하는 방법에 대한 광범위한 질문과 함께 miniKanren 연구의 한 활동 영역입니다.

요컨대 miniKanren과 Prolog는 모두 흥미로운 기능, 구현 및 사용을 가지고 있으며 두 언어에서 아이디어를 배울 가치가 있다고 생각합니다. Mercury, Curry 및 Gödel과 같은 다른 매우 흥미로운 논리 프로그래밍 언어도 있으며, 각각은 논리 프로그래밍을 고유하게 사용합니다.

몇 가지 miniKanren 리소스로 끝낼 것입니다.

주요 miniKanren 웹 사이트 : http://minikanren.org/

Prolog와의 비교를 포함하여 관계형 프로그래밍 및 miniKanren에 대한 인터뷰 : http://www.infoq.com/interviews/byrd-relational-programming-minikanren

건배,

--의지


9
지금 당장 날아 갔다면 실례합니다. 저는 논리 및 제약 기반 프로그래밍에서 첫 번째 사고 실험을 시작했고 그것이 제가받는 답입니다. :) 사실, 당신이 당신의 대답에서 언급했듯이, 나는 강력한 의심 논리 계산이 Monad로 구현하기에 완벽한 후보였습니다. MonadPlus에 가깝고 동료 인 Friedman 의 문서와 참조 구현 이 실제로 있습니다! 그래서 나는 그것을 읽고 지금 그것을 가지고 놀고 있습니다. 그것에 대해 어떤 생각이 있습니까?
Profpatsch

4
microKanren 논문과 코드도 흥미 롭다고 생각합니다 : webyrd.net/scheme-2013/papers/HemannMuKanren2013.pdfgithub.com/jasonhemann/microKanren
William E. Byrd

5
또한 매주 일요일 오후 3시 (GMT -5 : 00)에 Google Hangouts에서 miniKanren uncourse를 조직합니다. 우리와 함께하고 싶다면 항상 내 @webyrd Twitter 계정의 링크를 트윗합니다. : 이전 기록 수다방은 있습니다 youtube.com/playlist?list=PLO4TbomOdn2cks2n5PvifialL8kQwt0aW
윌리엄 E. 버드

2
기본적으로 2005 년 논문에서와 같은 검색 모나드라고 생각합니다. 또한 Seres와 Spivey의 'Embedding Prolog in Haskell'참조 : spivey.oriel.ox.ac.uk/~mike/silvija/seres_haskell99.pdf
William E. Byrd

1
@ WilliamE.Byrd-멋진 답변입니다! 하나가 있다고 가정 할 때 C / C ++ 프로그램에 포함 할 수있는 최상의 miniKanren 구현은 무엇입니까? 또한 miniKanren은 Prolog의 생성 특성을 가지고 있습니까? 즉, 식에 변수를 비 접지 상태로 두는 기능과 코어 엔진은 프로그램에 의해 선언 된 현재 관계가 주어지면 비접촉 변수에 대해 가능한 모든 값을 생성합니까?
Robert Oschler 2015

4

잠정적 대답 :

AFAIK, "The Reasoned Schemer"는 Scheme-y 구문 및 함수형 프로그래밍 스타일로 기본 논리 프로그래밍을 도입하여 특히 부울 값 "#t에 상수 목표"#u "(실패) 및"#s "(성공)를 추가했습니다. "및"#f ". Prolog : 통합 및 역 추적 검색과 동일한 논리 프로그래밍 방식을 사용했습니다. 주말 동안 책꽂이에서 책을 가져올 시간이 있는지 확인하겠습니다. 수학의 분기는 제한된 형태의 1 차 논리 (이 경우 Horn 절과 Resolution Unfication)입니다. 참조 : Computational Logic : Memories of the Past and Challenges for the Future by John Alan Robinson and The early years of logic programming by Robert Kowalski for a cold start.


3
이 두 인용은 Kanren 또는 MiniKanren과 어떤 관련이 있습니까?
거짓

2
마지막 질문을보십시오 : "수학의 어떤 분야에서 왔으며 이론적 기초는 무엇입니까?"
Frank Shearar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.