"프롤로그"는 프로그래밍 언어 또는 인공 지능의 기초입니다. 논리 프로그래밍. 프롤로그 언어의 기본 프롤로그는 어디에 사용됩니까?

그는 왜 놀라운가요? 나는 수십 가지 언어를 알고 있으며 또 다른 새로운 언어를 배우는 것은 문제가 되지 않으며 더 이상 필요하지 않다고 생각합니다.

프롤로그가 독특하네요. 선언적 프로그래밍 패러다임을 나타내는 유일한 언어입니다. 수백 가지의 서로 다른 구현을 가진 언어이지만 여전히 Prolog라고 불리며 이름에 접두사와 접미사만 추가합니다. 20년 넘게 큰 변화가 일어나지 않은 살아있는 언어입니다. 이것은 아마도 실제 프로그래밍에 적용할 수 없을 정도로 널리 사용되는 유일한 프로그래밍 언어일 것입니다. 왜 프롤로그인가?

프롤로그는 본질적으로 독특하며 행복한 우연(세계의 신비한 구조)으로 인해 등장했습니다. 옛날 옛적에 60년대에 자동 정리 증명 이론이 매우 빠르게 발전하고 있었고, 로빈슨은 유한한 시간 내에 모든 참 정리(공리에서 파생)를 증명할 수 있는 해결 알고리즘을 제안했습니다. 모두 다 아는). 나중에 밝혀졌듯이 이것은 일반적인 문제에 대한 최선의 해결책이며 제한된 수의 연산으로 정리를 증명하는 것은 불가능합니다. 간단히 말해서, 이 알고리즘은 (일반적으로 무한) 그래프의 너비 우선 순회입니다. 당연히 알고리즘 작동의 예측 가능성은 사실상 0과 같으므로 프로그래밍 언어에는 절대 적합하지 않습니다. 그리고 그 순간 Kalmarow는 문제가 훌륭하게 좁아지는 것을 발견했습니다. 덕분에 일부 정리의 증명은 프로그램의 절차적 실행처럼 보였습니다. 증명 가능한 정리의 종류가 상당히 넓고 프로그래밍 가능한 문제의 종류에 매우 잘 적용된다는 점은 주목할 가치가 있습니다. 이것이 1972년에 프롤로그가 탄생한 방법입니다.

이 기사에서 나는 일반적인 논리적 문제를 해결하기 위한 도구로서 Prolog에 대해 이야기하려고 합니다. 이 주제는 이미 Prolog 구문을 알고 있고 이를 내부적으로 이해하고 싶은 사람들뿐만 아니라 언어 구문을 전혀 모르지만 추가 시간을 들이지 않고 "열정"을 이해하고 싶은 사람들에게 흥미로울 것입니다. 구문 구조를 학습합니다.


프롤로그의 주요 특징은 읽기는 쉽지만 쓰기가 매우 어려울 수 있다는 점입니다. 이는 모든 주류 언어와 근본적으로 다르며, 쓰기가 더욱 쉬워지고 한 단계 더 나아가 태블릿에 쓸 수 있다는 것입니다. Google+의 친구처럼 모듈을 작업하면 코드 자체의 품질이 이로 인해 크게 저하된다는 것을 우리 모두 알고 있습니다. 모든 라인이 명확한 것 같지만, 힌두스탄어로 말하는 것처럼 시스템이 어떻게 작동하는지 개발자도 이해할 수 없습니다. 프롤로그 교육에 관한 모든 책에서 사실, 관계, 쿼리에 대한 이야기를 시작하면서 동일한 실수를 저지르고 사람이 전문가 시스템 또는 데이터베이스로서 언어에 대한 태도를 발전시키는 것 같습니다. 프로그램을 올바르게 읽는 방법과 수십 개의 프로그램을 그런 식으로 읽는 방법을 배우는 것이 훨씬 더 중요합니다 :)

프롤로그 프로그램을 올바르게 읽는 방법

언어에는 특수 기호와 키워드가 거의 없고 자연어로 쉽게 번역되므로 프로그램 읽기가 매우 쉽습니다. 프로그래머의 가장 큰 실수는 프로그램이 어떻게 작동하는지 즉시 상상하고 프로그램이 설명하는 내용을 읽지 않기를 원한다는 것입니다. 따라서 프로그래머보다 평범한 사람의 흐려지지 않은 두뇌를 훈련하는 것이 훨씬 쉬운 것 같습니다.
개념
언어에는 2가지 개념이 있다 술어(조건) 및 사물(이들은 또한 변수이자 용어이기도 합니다). 술어예를 들어 녹색 물체나 소수와 같은 특정 조건을 표현하려면 해당 조건에 입력 매개변수가 있는 것이 당연합니다. 예를 들어 green_object(객체), prime_number(숫자). 술어의 매개변수 수에 따라 술어의 개수가 결정됩니다. 사물- 용어, 상수 및 변수입니다. 상수- 숫자와 문자열입니다. 변수- 알려지지 않은 개체, 아마도 찾고 있는 개체를 표현하고 다음과 같은 줄로 지정됩니다. 편지. 지금은 용어를 그대로 두고 가장 간단한 프로그램을 고려해 보겠습니다.
프로그램
프로그램은 다음과 같은 형식의 규칙 집합입니다. 조건1과 조건2 그리고...이면 조건은 참입니다.공식적으로 이들 규칙은 AND를 통해 결합되지만, Prolog에는 논리적 부정이 없고, 접속사에는 단 하나의 술어(조건)만 존재할 수 있으므로 모순을 얻는 것은 불가능하다.

A:- B_1, B_2. % 규칙은 다음과 같습니다. B_1 및 B_2이면 A
홀수_프라임(숫자) :- 소수(숫자), 홀수(숫자).
% "숫자"가 소수이고 홀수이면 "숫자"는 홀수_소수입니다.

보시다시피 변수 이름에는 범위가 있습니다. 이것이 규칙입니다. 수학적으로 올바른 규칙은 다음과 같습니다. 모든 변수 - "숫자"에 대해 소수이고 홀수이면 prime_odd입니다. 마찬가지로 다음과 같이 바꿔 표현할 수 있습니다. 홀수와 소수인 "숫자"가 있으면 홀수_소수입니다. 그러므로 변수 이름이 매우 중요합니다! 왼쪽(이전:-)에서 Number를 Number2로 바꾸면 규칙의 의미가 변경됩니다. Number2와 Number에 대해 Number가 소수이고 홀수이면 Number2는 단순 홀수입니다. 모든 숫자는 prime_odd라는 것이 밝혀졌습니다! 이것은 Prolog에서 가장 흔한 오류입니다.

A:- B_1, B_2. % 규칙은 다음과 같습니다. B_1 및 B_2인 경우 A 홀수_소수(수) :- 소수(수), 홀수(수). % "숫자"가 소수이고 홀수이면 "숫자"는 홀수_소수입니다.

예 - 완전수
완벽한 숫자(N) :- 숫자(N), sum_of_divisors_without_number(N, SumofDivisors), (Sum_ofDivisors, H)와 같습니다. 완벽한 숫자(1). 같음(객체, 객체). sum_of_divisors_without_number(1, 1). sum_of_divisors_without_number(숫자, 합계) :- number_previous(숫자, 이전), sum_of_divisors_of_number_to_number(숫자, 합계, 이전). sum_of_number_divisors_to_number(숫자, 1, 1). sum_of_number_divisors_to_number(숫자, 합계, 제수) :- Divided_by(숫자, 제수), number_previous(제수, 이전), sum_of_number_divisors_to_number(숫자, SumPrev, 이전), add(SumPrev, Divisor, Sum). sum_of_number_divisors_to_number(숫자, 합계, 제수) :- not_divisible_by(숫자, 제수), number_previous(제수, 이전), sum_of_number_divisors_to_number(숫자, 합계, 이전).

먼저, 규칙이 의미하는 바를 공식적으로 읽어보겠습니다.

  1. "H"가 숫자이고 "H" 및 "SumDivisors"의 경우 sum_divisors_without_number 조건이 충족됩니다. 즉, SumDivisors는 숫자 "H"의 약수의 합이고 "H"는 "SumDivisors"와 같습니다. , 그러면 "H"는 완전수입니다.
  2. 1은 완전수이다. 규칙에는 조건이 없을 수 있으며, 이 경우 조건을 사실이라고 합니다.
  3. 모든 객체 "O"는 "O"와 같습니다. 원칙적으로 표준 술어 "="가 있지만 이를 자신의 것으로 완전히 대체할 수 있습니다.
  4. sum_of_divisors_without_the 숫자 1이 1과 같다는 사실.
  5. 이전 숫자 "Number"까지 제수 "Number"의 합이 "Sum"과 같은 경우 이는 sum_of_divisors_without_number입니다. 이런 식으로 X는 X로 나누어지기 때문에 X의 약수의 합은 Y보다 작거나 같다고 표현되므로 Y = X - 1이 됩니다.
  6. 다음으로, 3개의 술어는 Y(Divisor)보다 작거나 같은 제수 수의 합을 결정합니다. 첫 번째 경우 Y는 1과 같고, 두 번째 경우 Number는 Y로 나눌 수 있으며, sum_of_divisors(X, Y) = sum_of_divisors(X, Y- 1) + Y , 세 번째 경우 숫자는 Y로 나누어지지 않으며, sum_of_divisors(X, Y) = sum_of_divisors(X, Y-1)입니다.
프로그램은 일련의 정의와 같습니다.
"정의"를 기반으로 이러한 규칙을 읽는 두 번째 방법이 있습니다. 덜 수학적이고 더 자연스러운 방법입니다. Prolog에서 왼쪽(then 부분)의 모든 규칙에는 본질적으로 이 조건의 "정의"인 하나의 조건만 포함되어 있음을 알 수 있습니다.
예를 들어 첫 번째 규칙은 완전수의 정의입니다. "H"가 숫자이고 "H"의 약수의 합이 "H"와 같을 때 "H"는 완전수입니다. 동일한 술어는 "or" 조건을 사용하여 이름별로 그룹화됩니다. 즉, 정의에 다음을 추가할 수 있습니다. "H"는 ..일 때 완전수이거나 "H"가 1일 때입니다.

이 읽기 방법은 술어를 동질적인 그룹으로 결합할 수 있고 해석기가 술어를 풀기 위해 어떤 순서로 술어를 풀는지 이해하는 데 도움이 되므로 널리 사용됩니다.
어떤 진술의 진실성을 확인하십시오. 예를 들어, 술어에 단일 정의가 없으면 이를 사용하여 진술의 진실성을 증명하는 것이 불가능하다는 것이 분명합니다. 예 1번에서 "divided by"라는 술어에는 정의가 없습니다.

흥미로운 사실은 Prolog에는 루프, 변수 할당, 유형 선언이 없으며 용어와 클리핑도 기억하면 언어가 알고리즘적으로 완성된다는 것입니다.

온천탕
온천탕개체의 명명된 컬렉션으로 재귀적으로 정의됩니다. 용어 = "이름"(객체, 객체, ...), 예 person("이름", "성"), "+"(1, 2), person(주소("주소"), surname("성"),phone("전화")). 용어를 수학적 개념으로 간주하면 해당 용어는 함수, 더 정확하게는 functor입니다. 즉 "+"(1, 2)는 1+2와 동일한 객체가 있음을 의미합니다. 이는 1+2 = 3이라는 의미가 전혀 아닙니다; Prolog에서 이 표현은 모듈로 2의 나머지 그룹에서 3이 전혀 존재하지 않는 것처럼 참이 아닙니다. 다시 말하지만, 수학적 관점에서 볼 때 변수는 For All이라는 단어로 연결되며, 명령문에 해당 단어가 있으면 이 목적을 위해 용어(펑터)가 사용됩니다. 모든 숫자에는 계승 숫자가 있습니다: 계승(X, 사실(X)).

프로그래밍 관점에서 용어는 훨씬 더 간단하게 설명될 수 있습니다. 용어는 속성 집합을 가진 개체이고 속성은 다른 용어나 상수 또는 변수(즉, 정의되지 않음)일 수 있습니다. 가장 큰 차이점은 Prolog의 모든 객체는 변경할 수 없다는 것입니다. 즉, 해당 객체의 속성을 변경할 수 없지만 변수라는 특별한 상태가 있다는 것입니다.

예 - 정수 산술
nat(0). nat(숫자(숫자)) :- nat(숫자). 더하기(0, 숫자, 숫자). plus(숫자(N1), N2, 숫자(Res)) :- plus(N1, N2, Res). 곱하기(0, 숫자, 0). 곱하기(숫자(Ch1), Ch2, Res2) :- 곱하기(Ch1, Ch2, Res), 더하기(Res, Ch2, Res2).
  1. 속성 nat(자연수)의 정의. 0은 자연수이고, 그 수가 자연수이면 역시 자연수인 대상수(Number)가 있습니다. 수학적으로 "숫자"라는 용어는 +1 함수를 표현합니다. 프로그래밍 관점에서 "숫자"는 재귀적 데이터 구조이며 해당 요소는 다음과 같습니다: 숫자(0), 숫자(숫자(0)), 숫자(숫자 (숫자(0))).
  2. 플러스 비율은 0 + 숫자 = 숫자입니다. Ch1 + Ch2 = Res이면 (Ch1+1) + Ch2 = (Res+1)입니다.
  3. 곱하는 비율은 0 * Number = 0입니다. Ch1 * Ch2 = Res이고 Res + Ch2 = Res2이면 (Ch1+1) * Ch2 = Res2입니다.
분명히 이러한 진술은 일반 산술에 적용되지만 왜 숫자 + 0 = 숫자와 같은 명백한 진술을 포함하지 않았습니까? 대답은 간단합니다. 어떤 정의에서든 중복성은 매우 나쁩니다. 예, 이는 일종의 조기 최적화인 계산에 도움이 될 수 있지만 부작용은 정의의 모순, 명령문의 모호한 출력 및 인터프리터의 루핑이 될 수 있습니다.

Prolog가 술어를 이해하는 방법과 진술을 증명하는 방법

물론 읽기 프로그램은 프롤로그 스타일에 대한 느낌을 얻는 데 도움이 되지만 이러한 정의가 왜, 어떻게 사용될 수 있는지는 명확하지 않습니다. 위에 제시된 예제는 진입점이 충분하지 않기 때문에 완전한 프로그램이라고 할 수 없습니다. Prolog의 진입점은 SQL 데이터베이스에 대한 쿼리와 유사하거나 함수형 프로그래밍에서 기본 함수를 호출하는 것과 유사한 쿼리입니다. 쿼리의 예: nat(Number) - 자연수 찾기, plus(0, 0, Result) - Result 변수에 0과 0을 더한 결과 찾기, nat(0) - 0이 자연수인지 확인 등 .

물론 쿼리 결과를 논리적으로 예측하는 것은 어렵지 않지만 프로그램이 이를 어떻게 얻었는지 이해하는 것은 매우 중요합니다. 결국 Prolog는 블랙박스가 아니라 프로그래밍 언어이고, SQL 계획이 작성되고 쿼리가 서로 다른 데이터베이스에서 다르게 실행될 수 있는 데이터베이스와 달리 Prolog는 매우 구체적인 실행 순서를 가지고 있습니다. 사실 우리는 데이터베이스에서 테이블의 데이터를 기반으로 어떤 대답을 얻고 싶은지 완전히 알고 있습니다. 불행히도 프로그램의 프롤로그를 보면 어떤 진술이 논리적으로 추론 가능한지 말하기가 매우 어렵기 때문에 훨씬 쉽습니다. Prolog 해석기가 어떻게 작동하는지 이해합니다.

요청 예시를 살펴보겠습니다. 더하기(0, 0, 결과) :
1. 우리는 규칙 중 하나의 왼쪽 부분과 이 요청의 일치(일종의 패턴 일치, 해결)를 찾습니다. 이 쿼리의 경우 plus(0, Number, Number)입니다. 모든 쿼리 인수를 규칙과 하나씩 연관시켜 0 = 0, 0 = 숫자, 결과 = 숫자를 얻습니다. 이 방정식에는 2개의 변수(숫자 및 결과)가 포함되어 있으며 이를 해결하면 숫자 = 결과 = 0이 됩니다. 이 규칙에는 조건이 없으므로 질문에 대한 답을 받았습니다. 답변: 예, 결과 = 0입니다.

요구 nat(숫자) :
1. 대응 관계로 방정식을 풀어서 규칙인 nat(0) 규칙과 첫 번째 일치하는 항목을 찾습니다. 즉, 해결 방법을 찾아 Number = 0을 얻습니다. 답: yes 및 Number = 0입니다.

요구 plus(결과, 0, 숫자(0)) :
1. 플러스(0, 숫자, 숫자) 규칙을 사용하여 해결책을 찾습니다. 결과 = 0, 0 = 숫자, 숫자(0) = 숫자이지만 (!) 숫자 = 0 = 숫자(0) - 0은 불가능하므로 불가능합니다. 같은 숫자(0). 따라서 우리는 다음과 같은 규칙에 따라 해결책을 찾고 있습니다.
2. plus(number(N1), Ch2, number(Res)) 규칙을 사용하여 분해능을 찾으면 number(N1) = Result, Ch2 = 0, number(Res) = number(0)이므로 Res = 0이 됩니다. 이 규칙에는 분해능(변수 값)의 결과, plus(Ch1, Ch2, Res) -> plus(Ch1, 0, 0)를 고려하여 확인해야 하는 조건이 있습니다. 스택에 있는 변수의 값을 기억하고 새로운 요청을 생성합니다. 더하기(H1, 0, 0)
삼*. plus(Х1, 0, 0) 쿼리를 풀면 plus(0, Number, Number)로 해결 방법을 찾고 Х1 = 0 및 Number = 0을 얻습니다.
4. 스택을 따라 이전 변수 Result = number(N1) = number(0)으로 돌아갑니다. 정답은 (0)번에서 찾았습니다. 따라서 프롤로그 기계는 이제 방정식 X + 0 = 1을 풀었습니다.

Prolog 언어로 규칙을 유능하게 컴파일하는 것은 매우 어려운 일이지만, 컴팩트하게 구성하면 직접적인 답변과 솔루션뿐만 아니라 역방향 답변도 얻을 수 있습니다.

예시 요청 플러스(숫자, 숫자, 숫자) : 대답은 '예'입니다. 숫자 = 0입니다.

예시 요청 더하기(0, 0, 0) : 대답은 '아니오'입니다. 첫 번째 시도에서 모든 해결 방법이 충족되지 않습니다.

예시 요청 plus(숫자, 숫자, 숫자(숫자)) : 대답은 '예'입니다. 숫자 = 1입니다. 방정식 X + X = X + 1을 풉니다.

곱하기(숫자, 숫자(0), 숫자(0))에 대해 출력해 보십시오. 이렇게 하려면 변수를 스택에 2번 푸시하고 새 쿼리를 계산해야 합니다. Prolog 기계의 본질은 첫 번째 결과를 버릴 수 있다는 것입니다. 그런 다음 Prolog는 이전 상태로 돌아가서 계산을 계속합니다. 예를 들어 요청 nat(숫자) , 먼저 첫 번째 규칙을 적용하여 0을 출력하고, 두 번째 규칙 + 첫 번째 규칙을 적용하여 숫자(0)를 출력합니다. 반복하여 모든 자연수의 무한 수열을 얻을 수 있습니다. 또 다른 예, 요청 plus(숫자, 숫자(0), 숫자2) , 방정식 X + 1 = Y에 대한 모든 해 쌍의 시퀀스를 생성합니다.

결론

불행하게도 주제의 적당한 크기로 인해 프롤로그의 복잡한 논리적 문제 해결이라는 주요 주제에 접근할 수 없었으며, 이를 해결하기 위한 전략도 없었습니다. Prolog 코드의 큰 덩어리는 초보자뿐만 아니라 숙련된 프로그래머에게도 겁을 줄 수 있습니다. 이 기사의 목적은 Prolog 프로그램이 간단하게 자연어로 읽기, 그리고 간단한 인터프리터에 의해 실행됨.
Prolog의 주요 특징은 복잡한 논리적 문제를 해결하는 블랙박스나 라이브러리가 아니라는 점이며, Mathematica에 대수 방정식을 입력하면 솔루션이 생성되지만 수행되는 단계의 순서는 알 수 없습니다. 프롤로그는 일반적인 논리적 문제(논리적 "or" 및 "부정"이 없음)를 해결할 수 없습니다. 그렇지 않으면 해당 출력은 선형 해결로서 비결정적입니다. 프롤로그는 단순한 해석기와 정리 증명 기계 사이의 황금 평균입니다. 어떤 방향으로든 이동하면 속성 중 하나가 손실됩니다.

다음 기사에서는 정렬 문제가 해결되는 방법, 수혈 순서, Miss Manners 및 기타 잘 알려진 논리적 문제에 대해 이야기하고 싶습니다. 만족스럽지 못한 분들을 위해 드리고 싶은 말씀은 다음 작업 (상금을 가장 먼저 해결한 사람):
술어 작성, 이는 3으로 시작하는 무한한 자연수 시퀀스를 생성합니다. 이는 Prolog의 표준 숫자여야 하며 is 술어를 사용하여 작업이 수행됩니다. X는 3 + 1 => X=4입니다.

수천 년 동안 인류는 지식을 축적하고, 처리하고, 전달해 왔습니다. 이러한 목적을 위해 말하기, 쓰기, 우편, 전신, 전화 등 새로운 수단이 지속적으로 발명되고 기존 수단이 개선되고 있습니다. 컴퓨터의 출현은 지식 처리 기술에서 중요한 역할을 했습니다.

1981년 10월, 일본 통상산업성은 연구 기관인 차세대 컴퓨터 기술 연구소(Institute for New Generation Computer Technology Research Center)의 창설을 발표했습니다. 이 프로젝트의 목표는 지식 기반 정보 처리 시스템을 만드는 것이었습니다. 이러한 시스템은 자연어를 사용하여 사용자와 소통할 수 있기 때문에 관리가 용이할 것으로 예상되었습니다. 이러한 시스템은 스스로 학습하고, 메모리에 축적된 지식을 사용하여 다양한 문제를 해결하고, 사용자에게 전문적인 조언을 제공하며, 사용자가 컴퓨터 공학 전문가일 필요는 없었습니다. 5세대 컴퓨터는 TV, 녹음기, 청소기 등 일반 가전제품처럼 누구나 쉽게 사용할 수 있을 것으로 예상됐다. 일본 프로젝트 직후 미국과 유럽 프로젝트가 시작되었습니다.

이러한 시스템의 출현은 지식 기반과 전문가 시스템을 사용하여 기술을 변화시킬 수 있습니다. 5세대 컴퓨터로의 질적 전환의 핵심은 데이터 처리에서 지식 처리로의 전환이었다. 일본인은 인간의 사고를 컴퓨터 작동 원리에 맞추는 것이 아니라 컴퓨터의 폰 노이만 아키텍처에서 벗어나 컴퓨터 작동을 사람이 생각하는 방식에 더 가깝게 만들 수 있기를 바랐습니다. 1991년에는 5세대 컴퓨터의 첫 번째 프로토타입을 만들 계획이었습니다.

이제 설정된 목표가 완전히 달성되지 않았다는 것이 분명해졌지만, 이 프로젝트는 인공 지능 분야의 새로운 연구 개발을 위한 원동력이 되었으며 논리 프로그래밍에 대한 관심이 폭발적으로 증가했습니다. 전통적인 폰 노이만 아키텍처는 효율적인 구현에 적합하지 않았기 때문에 특수 논리 프로그래밍 컴퓨터 PSI 및 PIM이 만들어졌습니다.

5세대 컴퓨터 프로젝트를 위한 소프트웨어 개발의 주요 방법론으로 다음이 선택되었습니다. 논리 프로그래밍, 그 대표적인 언어가 Prolog 언어입니다. 현재 Prolog는 일본과 유럽에서 가장 인기 있는 인공 지능 언어로 남아 있는 것 같습니다(미국에서는 전통적으로 또 다른 인공 지능 언어인 함수형 프로그래밍 언어인 Lisp가 더 널리 사용됩니다).

"Prolog"라는 언어의 이름은 다음 단어에서 유래되었습니다. 논리 프로그래밍(프랑스어로 PROgrammation en LOGique, 영어로 PROgramming in LOGic).

프롤로그는 다음과 같은 수학적 논리 분야를 기반으로 합니다. 술어 계산. 보다 정확하게는 그 기초는 정리를 증명하는 절차입니다. 해결방법을 위한 경적 조항. 다음 강의에서는 이 주제를 다루겠습니다.

Prolog 언어의 출현과 발전의 역사에서 다음 단계를 구분할 수 있습니다.

1965년 Journal of the ACM 12호에 게재된 "A machine Oriented logic based on the 해결 원리"라는 논문에서 J. Robinson은 1차 술어 미적분학에서 정리 증명을 자동으로 찾는 방법을 제시했습니다. " 해결의 원리". 이 작품은 번역으로 읽을 수 있습니다. Robinson J. 기계 지향 논리 결의의 원칙// 사이버네틱 컬렉션. - Vol. 7 (1970). 실제로 이 방법에 대한 아이디어는 아직 컴퓨터가 없던 1931년에 Herbrand에 의해 제안되었습니다(Herbrand, “Une methode de Demon”, This, Paris, 1931). 로빈슨은 이 방법을 자동 컴퓨터 사용에 적합하도록 수정했으며, 또한 그의 방법의 기초를 형성하는 효과적인 통합 알고리즘을 개발했습니다.

1973년 알랭 콜메로(Alain Colmeroe)가 이끄는 "인공지능 그룹"은 마르세유 대학에서 정리를 증명하기 위한 프로그램을 만들었습니다. 이 프로그램은 자연어 텍스트 처리 시스템을 구축하는 데 사용되었습니다. 정리 증명 프로그램은 Prolog(Programmation en Logique에서 유래)라고 불렸습니다. 프롤로그의 프로토타입으로 사용되었습니다. 전설에 따르면 이 이름의 저자는 Alan Colmeroe의 아내였습니다. 이 프로그램은 Fortran으로 작성되었으며 다소 느리게 실행되었습니다.

Robert Kowalski의 작업은 논리 프로그래밍 개발에 매우 ​​중요했습니다. 술어 논리어떻게 프로그래밍 언어"(Kowalski R. Predicate Logic as 프로그래밍 언어. IFIP Congress, 1974)에서 그는 효율성을 달성하려면 집합 사용으로 제한해야 함을 보여주었습니다. 경적 조항. 그건 그렇고, Kowalski와 Colmeroe는 한 여름 동안 함께 일한 것으로 알려져 있습니다.

1976년에 Kowalski는 동료인 Maarten van Emden과 함께 논리 프로그램 텍스트를 읽는 두 가지 접근 방식, 즉 절차적 접근 방식과 선언적 접근 방식을 제안했습니다. 이러한 접근법은 세 번째 강의에서 논의될 것입니다.

1977년 에딘버러에서 Warren과 Pereira는 DEC-10 컴퓨터를 위한 매우 효율적인 Prolog 컴파일러를 만들었으며, 이는 Prolog의 후속 구현을 위한 프로토타입 역할을 했습니다. 재미있게,

상태 공간 그래프를 활용하여 문제를 해결하는 방법에 대해 강의합니다. 상태 공간은 상태 집합(그래프 정점, 상태에서 상태로의 전환 집합), 그래프 호, 초기 상태 집합 및 최종 상태 집합의 형태로 설명됩니다. 문제에 대한 해결책은 초기 상태와 최종 상태를 연결하는 상태 공간 그래프의 경로로 표시됩니다. 문제의 상태 공간이 작으면 깊이 우선 탐색을 사용하여 모든 최적의 솔루션을 찾습니다. 상태 공간이 큰 문제에서는 너비 우선 탐색을 통해 하나의 최적 솔루션만 계산됩니다. 범용 솔버는 문제에 적용됩니다. 서로 다른 작업의 상태는 서로 다른 도메인에 속할 수 있습니다. 찾은 최상의 솔루션을 기억하기 위해 "변수 변수" varM이 사용됩니다. 컴파일러 자체는 필요한 유형을 찾습니다. Visual Prolog 버전 7.5는 아직 게시되지 않았습니다. 2014년 출간 예정이지만 정확한 날짜는 아직 알려지지 않았다. 이제 Visual Prolog 7.4가 모든 사람에게 제공됩니다.

프롤로그의 등장은 논리, 수학, 프로그래밍의 발전에 따른 것이었습니다. 후자가 가장 중요한 역할을했습니다. 논리와 수학 전문가들은 프로그래밍을 '올바른 길'로 옮기려고 시도했지만 정보 기술의 발전은 완전히 다른 결과를 보여주었습니다.

실용적인 명령형 프로그래밍이 더 유망한 것으로 나타났습니다. 프롤로그는 프로그래밍 언어로는 성공했지만 인공지능의 기반이 되지는 못했다.

고전 프로그래밍과 논리

사람은 논리적이고 합리적으로 어려운 결정을 내립니다. 사람은 거의 생각하지 않고 현명하게 행동합니다. 정보 수집, 분석 및 복잡한 계산이 필요한 결정을 고려하지 않으면 모든 결과는 빠르고 정확하며 합리적입니다.

이 사실은 항상 의사 결정 도구를 만드는 것이 단순한 문제라고 생각하는 환상적인 이유를 제공했습니다. 프롤로그의 등장과 함께 인공지능의 문제는 기술의 문제인 것처럼 보였고, 호모 사피엔스는 로봇공학의 세 가지 법칙을 내놓았다. 그러나 인공 지능은 유령으로 남아 있었고 로봇 공학의 세 가지 법칙은 동화에서 나온 것으로 밝혀졌습니다. "이렇게 하세요. 뭔지 모르겠습니다."

고전적인 의미의 프로그래밍("절차적", "명령형" 또는 "기능적"이라는 용어가 자주 사용됨)은 수많은 프로그래밍 언어가 존재했던 80~90년대의 "어려운 시대"를 발전시켜 성공적으로 극복했습니다.

'파스칼'과 '시'의 시위 투쟁은 오랫동안 지속되어 잔혹했지만 중립적이고 조용하게 끝났다. 남은 것은 좋은 프로그래밍 언어에 대한 아이디어와 이를 성공적으로 구현한 몇 가지 방법입니다.

프로그래밍 언어로서의 프롤로그가 발전하지 않았다는 뜻은 아닙니다. 그러나 그는 자신이 밝힌 목표를 달성하지 못했습니다. 오늘날 우리는 다음과 같이 말할 수 있을 뿐만 아니라 정당화할 수도 있습니다. "프롤로그"는 다음을 위한 학문적 언어입니다.

  • 학습 목표;
  • 술어 논리;
  • 수학;
  • 좁은 적용.

이 주장이 반박될 수 있을지 의문이다. 인공지능은 널리 사용될 뿐만 아니라 사회 구조와 세계의 모습을 근본적으로 바꾸는 매우 심각한 사건이다.

인공 지능을 위한 Prolog 언어 프로그래밍은 발생하지 않았습니다. 40년이 넘는 언어 역사 동안 대중의 의식과 관련된 근본적으로 새로운 사건은 단 하나도 없었으며 이는 그 반대를 나타냅니다.

객관적인 현실은 이것이다: 살아남는 것은 가장 강한 것이 아니라 오히려 수요가 있고 관련성이 있는 것입니다.

프롤로그(Prolog)는 선언적 프로그래밍 언어이다.

사실과 규칙을 설명하는 도구를 갖는 것은 좋지만 요점은 무엇입니까? 사실과 규칙은 일반 데이터베이스에 완벽하게 들어맞습니다. 자격을 갖춘 클래식 프로그래머는 사용자에게 대화형 대화를 제공하고 사용자는 문제를 해결합니다.

필요한 경우 프로그래머는 대화를 다듬고 사용자는 사실과 규칙의 데이터베이스를 보완합니다. 이미 해결되고 해결 가능한 수많은 문제를 구현하기 위한 완벽하게 작동하고 수십 년 동안 테스트된 옵션입니다.

Prolog 프로그래밍 언어 구현에서 사실과 규칙을 선언적으로 표현하는 것은 관례이며, 지적 상태에서 현실을 공식화하려는 시도입니다. 기존 프로그래밍은 지성을 건드리지 않습니다. 고전 프로그래밍은 데이터의 설명과 처리라는 위치에 만족합니다. 여기에는 많은 문제가 있지만 효과가 있는 훌륭한 솔루션도 많이 있습니다.

프로그래밍 언어로서의 "프롤로그"는 사실입니다.

  • 어머니(마리아, 나타샤); - 마리아(Maria) - 나타샤의 어머니
  • 아빠 (Evgeniy, Marina); - Evgeniy는 Marina의 아빠입니다.

여기서 한 가지 사실이 즉시 드러납니다. "Maria"와 "Marina"는 서로 다른 이름입니다. 다음 사실을 추가하는 것을 방해하는 것은 없습니다.

  • 아빠 (유진, 마리아); - Evgeniy는 Maria의 아빠입니다.

다음 설명은 규칙에 생명을 불어넣습니다.

  • 상위(x,y)<- папа (x, y);
  • 상위(x,y)<- мама (x, y);

그러나 그들은 아빠가 마리나의 아버지이고 마리나가 마리아의 어머니라고 결론을 내리는 것을 허용하지 않습니다. 이 문제는 해결될 수 있습니다. 규칙을 하나 더 추가하고 사실을 하나 더 추가하면 됩니다. 하지만 실제 상황에서는 이러한 조치 중 얼마나 많은 조치를 취해야 할까요?

사실, 프로그래밍 언어로서의 "프롤로그"는 사실과 규칙을 선언하는 예이지만 고전 프로그래머의 의식에 익숙한 논리는 아닙니다. "프롤로그"는 술어 논리 언어로 자리매김하지만 특정 언어 구현 개발자의 예제와 샘플 설명을 통해서만 프로그래밍을 배울 수 있습니다.

프롤로그 가족

프랑스는 프롤로그의 발상지로 여겨지며, 1973년이 탄생 연도이다. 언어에 대한 관심은 주기적으로 갱신되었지만 부러워할 만큼 안정되면서 가라앉았습니다. 언어의 모토: “술어 논리는 기본입니다! 이것이 사고가 어떻게 작동하는지 설명하는 방법입니다.” - 이것이 모토로 남았습니다.

Prolog 프로그래밍 언어의 모든 구현은 술어 논리를 엄격하게 따랐지만 항상 절차적 프로그래밍의 고전적인 아이디어를 포함했습니다. 이 용어는 절차적, 기능적, 객체 지향적 등의 용어보다 형식적으로 사용되기 때문에 "명령적"이라고 말하는 것이 더 정확합니다.

모든 프로그래밍은 데이터와 데이터 처리에 관한 것입니다. 언어 구성은 해결되는 문제를 가능한 한 정확하게 설명해야 합니다. 이것이 바로 알려진 모든 Prolog 구현(Turbo Prolog, Win Prolog, SWI Prolog, GNU Prolog, Visual Prolog 및 기타)에 선언적 구성 외에도 일반적인 명령형 표현식이 포함되어 있는 이유입니다.

프롤로그 계열은 학술 및 연구 기관에서 개발되었으므로 개념적 의미에서 공통 언어로만 언급될 수 있다고 믿어집니다. 그럼에도 불구하고 "프롤로그"라는 개념이 살아 있고 발전하고 있다는 사실을 고려할 수 있습니다. 이 언어에는 범위가 있으며 특정 작업 범위에서 요구됩니다.

인공지능의 기초

인공 지능에 대한 관심은 결코 줄어들지 않았고 다음 기회가 생기면 그것에 대해 이야기하기 시작했지만 Prolog는 일반적인 고전 프로그래밍 언어보다 인공 지능과 더 관련이 없었습니다.

80년대 말에는 실제적이고 관련성이 높으며 인기 있는 지적 프로젝트인 "The Inventing Machine"이 있었습니다. 발명, 물리, 화학 및 기타 법칙에 대한 거대한 실제 지식 기반(데이터)을 공식화하기 위해 Prolog를 사용하려는 실제 시도가 있었습니다.

결과는 달성되지 않았고 프로그래밍 언어인 Prolog에는 진부한 명령 성격을 지닌 너무 많은 사실과 규칙을 작성해야 했습니다. 한편, 많은 성공적인 소프트웨어 제품이 일반 언어로 병렬로 구현되었습니다.

90년대 초, EU 컴퓨터에서 3세 미만 어린이의 행동을 시뮬레이션하는 실제 지적 시스템 프로젝트가 성공적으로 구현되었습니다! Prolog를 사용하는 옵션도 고려되지 않았습니다.

이 지적 시스템은 엄마와 아빠가 무엇인지, 마리아가 마리나와 어떻게 다른지 "파악"했을 뿐만 아니라, 이러한 문제에 대해 획득한 지식에서 공과 큐브의 차이점, 색상에 이르기까지 많은 노력 없이도 독립적으로 도약했습니다. 객체 및... (!) 초등 수학: 완전히 다른 문제를 해결하여 얻은 지식을 바탕으로 간단한 산술 연산이 그녀의 능력 범위 내에 있는 것으로 밝혀졌습니다.

인공지능의 영역을 장악한다는 점에서 클래식 프로그래밍이 프롤로그보다 앞서 있다고 말할 수는 없지만 실질적인 결과를 제공합니다.

작업으로서의 지능에 관해서는 분명히 여기서 문제는 언어가 아니라 구현 아이디어에 있습니다. 1991년 어셈블러가 지능형 상황 지능 시스템의 "기반이 될" 수 있다면 문제는 분명히 구현 언어가 아니라 아이디어에 있습니다.

프롤로그 프로그래밍 언어최고의 논리 프로그래밍 언어 중 하나입니다. 1970년대 알랭 콜메라우어(Alain Colmerauer)가 만들었습니다. 컴퓨터 화면에 지시사항으로 이루고자 하는 바를 세심하게 명시하기보다는, 논리를 표현할 수 있는 초보자용 프로그래밍 언어를 만들려는 시도였습니다.

프롤로그는 많은 인공 지능 프로그램에서 사용되지만 구문과 의미는 매우 간단하고 명확합니다(원래 목적은 컴퓨터에 문맹인 언어학자를 위한 도구를 제공하는 것이었습니다). Prolog라는 이름은 LOGIC PROGRAMMING의 약어이며 프로그래밍의 기본을 가르치는 데 널리 알려져 있습니다.

프롤로그는 술어 계산(보다 정확하게는 1차 술어 계산)을 기반으로 하지만 Horn의 공식에 국한됩니다. 프롤로그 프로그램은 정리를 첫 번째 근사치로 증명하는 데 효과적입니다. 조인, 테일 재귀 및 추적의 기본 개념입니다.

데이터 유형

Prolog는 일반적인 프로그래밍 언어에서 익숙한 방식으로 데이터 유형을 사용하지 않습니다. 데이터 유형 대신 프롤로그 어휘 요소에 관해 이야기할 수 있는데, 이는 인형 프로그래밍에서는 드문 일입니다.

상수 텍스트는 원자를 사용하여 입력됩니다. 원자는 소문자로 시작하는 일련의 문자, 숫자 및 밑줄입니다. 일반적으로 영숫자 원자가 아닌 경우 아포스트로피로 프레임을 지정해야 합니다(예: "+"는 원자, +는 연산자).

대부분의 Prolog 구현은 실수와 분수를 구별하지 않습니다.

변수

변수는 대문자로 시작하는 문자, 숫자, 밑줄로 구성된 문자열로 식별됩니다. Prolog 환경에서 변수는 (절차적 프로그래밍 언어와 달리) 할당할 수 있는 컨테이너가 아닙니다. 그 동작은 조인과 유사한 모델에 더 가깝습니다.

소위 익명 변수는 단일 밑줄(_)로 작성됩니다.

용어는 Prolog가 복잡한 데이터를 나타낼 수 있는 유일한 방법입니다. 이 용어는 펑터라고도 하는 헤드(원자여야 함)와 매개변수(유형에 국한되지 않음)로 구성됩니다. 소위 용어의 소수라고 불리는 매개변수의 수는 중요합니다. 용어는 머리글과 배열로 정의되며 일반적으로 functor/arity로 작성됩니다.
기울기

목록은 재귀적 구성(/2 "."라는 용어 사용)으로 정의되므로 독립형 데이터 유형이 아닙니다.

Atom - 빈 목록

프로그래머의 편의를 위해 목록은 다양한 방식으로 구성되고 삭제될 수 있습니다.

L이 목록이고 X가 요소이면 "." (X, L)은 목록의 구성원입니다. 컨텍스트 L의 내용이 뒤따르는 첫 번째 요소 X는 구문론적으로 다음과 같이 표현됩니다.

프로그래머의 편의를 위해 목록은 다양한 방식으로 작성 및 삭제될 수 있습니다.

품목 목록:
한 요소의 서문:
몇 가지 예비 요소:
용어 확장: "."(abc, "."(1, "."(f(x), "."(Y, "."(g(A,rst), )))))

문자열은 일반적으로 따옴표 안에 일련의 문자로 작성됩니다. 이는 종종 ASCII 문자 코드 목록으로 표시됩니다.

PROLOG 프로그래밍은 절차적 언어로 작업하는 것과 매우 다릅니다. Prolog에서는 사실과 규칙의 데이터베이스로 작업하고 데이터베이스 쿼리를 실행할 수 있습니다. 프롤로그의 기본 단위는 참이라고 정의된 술어이다. 술어는 헤드와 여러 인수로 구성됩니다. 예를 들어:

여기서 "cat"은 머리이고 "tom"은 인수입니다. 다음은 이 사실을 기반으로 Prolog 변환기를 사용하여 실행할 수 있는 몇 가지 예제 쿼리입니다.

고양이(톰).
예.

고양이(X).
X = 톰;
아니요.

술어는 일반적으로 프로그램이 세상에 대해 아는 사실을 표현하기 위해 정의됩니다. 대부분의 경우 술어를 사용하려면 특정 규칙이 필요합니다. 그러면 다음 중 Pat이 Sally의 아버지라는 것을 의미하는 것은 무엇입니까?

아버지(샐리,팻).
아버지(팻,샐리).

두 경우 모두 "father"는 머리이고 "sally"와 "pat"는 인수입니다. 그러나 첫 번째 경우에는 Sally가 인수 목록의 1위를 차지하고 Pat은 2위를 차지하며 그 반대의 경우도 마찬가지입니다. 첫 번째 경우는 동사 주어, 목적어 순서로 정의한 예인데, 두 번째 경우는 동사 목적어 주어 순서로 정의한 예입니다. Prolog는 영어를 이해하지 못하기 때문에 두 버전 모두 괜찮지만, 하나의 프로그램을 작성하면서 다음과 같은 것을 작성하는 것보다 컨벤션이라는 하나의 스타일을 고수하는 것이 좋은 프로그래밍 스타일로 간주됩니다.

아버지(팻,샐리). 아버지(제시카,제임스).

특정 술어는 언어에 내장되어 있으며 Prolog가 일상적인 활동(예: 그래픽을 사용한 입력/출력 및 운영 체제와의 기타 통신)의 고된 작업을 줄일 수 있도록 합니다. 예를 들어 쓰기 조건자는 다음과 같이 표시하는 데 사용할 수 있습니다.

쓰기("안녕하세요")

화면에 "Hello"라는 단어가 표시됩니다.

규칙

Prolog의 두 번째 유형의 명령문은 규칙입니다. 예제 규칙:

빛(켜짐) :-스위치(켜짐).

":-"는 "if"를 의미합니다. 이 규칙은 스위치(켜짐)가 true인 경우 조명(켜짐)이 true(켜짐)임을 의미합니다(그렇지 않으면 스위치가 켜져 있으면 빛이 있음). 규칙은 변수를 사용할 수도 있습니다. 변수는 대문자로 시작하고 상수는 소문자로 시작합니다. 예를 들어,

아버지(X,Y) :- 부모(X,Y),남성(Y).

이는 "누군가가 부모이고 그가 남자라면, 그 사람은 아버지이다"라는 뜻입니다. 원인과 결과의 순서가 반대일 수도 있으므로 이는 일반적인 논리와 모순되지 않습니다. 예를 들어 다음과 같이 여러 조건자를 결합하여 결과 섹션에 배치할 수 있습니다.

이는 여러 선언과 동일합니다.

기원 후. b:- 디. CD.

그러나 다음과 같은 지침이 있습니다.

이는 "c이면 a 또는 b"와 동일합니다. 이는 Horn의 공식에 따른 제한 때문입니다.