Python을 사용한 AI – 논리 프로그래밍

이 장에서는 논리 프로그래밍과 이것이 인공 지능에서 어떻게 도움이되는지에 초점을 맞출 것입니다.

우리는 이미 논리가 올바른 추론의 원리에 대한 연구라는 것을 알고 있습니다. 또는 간단한 말로 논리는 무엇이 뒤에 오는지에 대한 연구입니다. 예를 들어 두 문장이 참이면 그로부터 세 번째 문장을 추론 할 수 있습니다.

개념

논리 프로그래밍은 논리와 프로그래밍이라는 두 단어의 조합입니다. 논리 프로그래밍은 형식 논리 시스템 내에서 프로그램 문에 의해 문제가 사실과 규칙으로 표현되는 프로그래밍 패러다임입니다. 객체 지향, 기능, 선언 및 절차 등과 같은 다른 프로그래밍 패러다임과 마찬가지로 프로그래밍에 접근하는 특별한 방법이기도합니다.

논리 프로그래밍으로 문제를 해결하는 방법

논리 프로그래밍은 문제를 해결하기 위해 사실과 규칙을 사용합니다. 이것이 논리 프로그래밍의 빌딩 블록이라고 불리는 이유입니다. 논리 프로그래밍의 모든 프로그램에 대해 목표를 지정해야합니다. 논리 프로그래밍에서 문제를 해결하는 방법을 이해하려면 빌딩 블록 인 사실과 규칙에 대해 알아야합니다.

사리

실제로 모든 논리 프로그램에는 주어진 목표를 달성 할 수 있도록 작업 할 사실이 필요합니다. 사실은 기본적으로 프로그램과 데이터에 대한 진정한 진술입니다. 예를 들어, 델리는 인도의 수도입니다.

규칙

실제로 규칙은 문제 영역에 대한 결론을 내릴 수있는 제약입니다. 다양한 사실을 표현하기 위해 기본적으로 논리 절로 작성된 규칙. 예를 들어, 우리가 어떤 게임을 만들고 있다면 모든 규칙을 정의해야합니다.

규칙은 논리 프로그래밍의 문제를 해결하는 데 매우 중요합니다. 규칙은 기본적으로 사실을 표현할 수있는 논리적 결론입니다. 다음은 규칙의 구문입니다-

A∶− B1, B2, ..., B n .

여기서 A는 머리이고 B1, B2, ... Bn은 몸입니다.

예를 들어-ancestor (X, Y) :-father (X, Y).

ancestor (X, Z) :-father (X, Y), ancestor (Y, Z).

이것은 X가 Y의 조상이고 Y가 Z의 조상이면 모든 X와 Y에 대해 읽을 수 있습니다. X는 Z의 조상입니다. 모든 X와 Y에 대해 X는 Z의 조상입니다. Y와 Y의 아버지는 Z의 조상입니다.

유용한 패키지 설치

Python에서 논리 프로그래밍을 시작하려면 다음 두 패키지를 설치해야합니다.

칸렌

비즈니스 로직을위한 코드를 만드는 방법을 단순화하는 방법을 제공합니다. 규칙과 사실의 관점에서 논리를 표현할 수 있습니다. 다음 명령은 kanren을 설치하는 데 도움이됩니다-

pip install kanren

심 파이

SymPy는 기호 수학을위한 Python 라이브러리입니다. 코드를 이해하고 쉽게 확장 할 수 있도록 코드를 최대한 단순하게 유지하면서 완전한 기능을 갖춘 컴퓨터 대수 시스템 (CAS)이되는 것을 목표로합니다. 다음 명령은 SymPy를 설치하는 데 도움이됩니다.

pip install sympy

논리 프로그래밍의 예

다음은 논리 프로그래밍으로 해결할 수있는 몇 가지 예입니다.

수학적 표현 일치

사실 우리는 매우 효과적인 방법으로 논리 프로그래밍을 사용하여 알려지지 않은 값을 찾을 수 있습니다. 다음 Python 코드는 수학적 표현을 일치시키는 데 도움이됩니다.

다음 패키지를 먼저 가져 오는 것을 고려하십시오.

from kanren import run, var, fact
from kanren.assoccomm import eq_assoccomm as eq
from kanren.assoccomm import commutative, associative

우리가 사용할 수학적 연산을 정의해야합니다.

add = 'add'
mul = 'mul'

덧셈과 곱셈은 모두 의사 소통 과정입니다. 따라서이를 지정해야하며 다음과 같이 수행 할 수 있습니다.

fact(commutative, mul)
fact(commutative, add)
fact(associative, mul)
fact(associative, add)

변수를 정의하는 것은 필수입니다. 이것은 다음과 같이 할 수 있습니다-

a, b = var('a'), var('b')

표현을 원래 패턴과 일치시켜야합니다. 기본적으로 (5 + a) * b −

Original_pattern = (mul, (add, 5, a), b)

원래 패턴과 일치하는 다음 두 가지 표현식이 있습니다.

exp1 = (mul, 2, (add, 3, 1))
exp2 = (add,5,(mul,8,1))

출력은 다음 명령으로 인쇄 할 수 있습니다-

print(run(0, (a,b), eq(original_pattern, exp1)))
print(run(0, (a,b), eq(original_pattern, exp2)))

이 코드를 실행하면 다음과 같은 결과가 나옵니다.

((3,2))
()

첫 번째 출력은 다음에 대한 값을 나타냅니다. ab. 첫 번째 표현식은 원래 패턴과 일치하고 다음에 대한 값을 반환했습니다.ab 그러나 두 번째 표현식은 원래 패턴과 일치하지 않으므로 아무것도 반환되지 않습니다.

소수 확인

논리 프로그래밍의 도움으로 숫자 목록에서 소수를 찾을 수 있고 소수를 생성 할 수도 있습니다. 아래 주어진 Python 코드는 숫자 목록에서 소수를 찾고 처음 10 개의 소수도 생성합니다.

먼저 다음 패키지를 가져 오는 것을 고려해 보겠습니다.

from kanren import isvar, run, membero
from kanren.core import success, fail, goaleval, condeseq, eq, var
from sympy.ntheory.generate import prime, isprime
import itertools as it

이제 주어진 숫자를 데이터로 기반으로 소수를 검사하는 prime_check라는 함수를 정의합니다.

def prime_check(x):
if isvar(x):
   return condeseq([(eq,x,p)] for p in map(prime, it.count(1)))
else:
   return success if isprime(x) else fail

이제 사용할 변수를 선언해야합니다.

x = var()
print((set(run(0,x,(membero,x,(12,14,15,19,20,21,22,23,29,30,41,44,52,62,65,85)),
(prime_check,x)))))
print((run(10,x,prime_check(x))))

위 코드의 출력은 다음과 같습니다.

{19, 23, 29, 41}
(2, 3, 5, 7, 11, 13, 17, 19, 23, 29)

퍼즐 풀기

논리 프로그래밍은 8- 퍼즐, Zebra 퍼즐, 스도쿠, N-queen 등과 같은 많은 문제를 해결하는 데 사용할 수 있습니다. 여기에서는 다음과 같은 Zebra 퍼즐 변형의 예를 들어 보겠습니다.

There are five houses.
The English man lives in the red house.
The Swede has a dog.
The Dane drinks tea.
The green house is immediately to the left of the white house.
They drink coffee in the green house.
The man who smokes Pall Mall has birds.
In the yellow house they smoke Dunhill.
In the middle house they drink milk.
The Norwegian lives in the first house.
The man who smokes Blend lives in the house next to the house with cats.
In a house next to the house where they have a horse, they smoke Dunhill.
The man who smokes Blue Master drinks beer.
The German smokes Prince.
The Norwegian lives next to the blue house.
They drink water in a house next to the house where they smoke Blend.

우리는 문제를 해결하고 있습니다 who owns zebra Python의 도움으로.

필요한 패키지를 가져 오겠습니다.

from kanren import *
from kanren.core import lall
import time

이제 두 가지 함수를 정의해야합니다. left()next() 누가 집이 남았는지 옆에 있는지 확인하려면-

def left(q, p, list):
   return membero((q,p), zip(list, list[1:]))
def next(q, p, list):
   return conde([left(q, p, list)], [left(p, q, list)])

이제 다음과 같이 가변 하우스를 선언합니다.

houses = var()

다음과 같이 lall 패키지의 도움으로 규칙을 정의해야합니다.

5 개의 집이 있습니다-

rules_zebraproblem = lall(
   (eq, (var(), var(), var(), var(), var()), houses),

   (membero,('Englishman', var(), var(), var(), 'red'), houses),
   (membero,('Swede', var(), var(), 'dog', var()), houses),
   (membero,('Dane', var(), 'tea', var(), var()), houses),
   (left,(var(), var(), var(), var(), 'green'),
   (var(), var(), var(), var(), 'white'), houses),
   (membero,(var(), var(), 'coffee', var(), 'green'), houses),
   (membero,(var(), 'Pall Mall', var(), 'birds', var()), houses),
   (membero,(var(), 'Dunhill', var(), var(), 'yellow'), houses),
   (eq,(var(), var(), (var(), var(), 'milk', var(), var()), var(), var()), houses),
   (eq,(('Norwegian', var(), var(), var(), var()), var(), var(), var(), var()), houses),
   (next,(var(), 'Blend', var(), var(), var()),
   (var(), var(), var(), 'cats', var()), houses),
   (next,(var(), 'Dunhill', var(), var(), var()),
   (var(), var(), var(), 'horse', var()), houses),
   (membero,(var(), 'Blue Master', 'beer', var(), var()), houses),
   (membero,('German', 'Prince', var(), var(), var()), houses),
   (next,('Norwegian', var(), var(), var(), var()),
   (var(), var(), var(), var(), 'blue'), houses),
   (next,(var(), 'Blend', var(), var(), var()),
   (var(), var(), 'water', var(), var()), houses),
   (membero,(var(), var(), var(), 'zebra', var()), houses)
)

이제 이전 제약 조건으로 솔버를 실행하십시오.

solutions = run(0, houses, rules_zebraproblem)

다음 코드를 사용하여 솔버에서 출력을 추출 할 수 있습니다.

output_zebra = [house for house in solutions[0] if 'zebra' in house][0][0]

다음 코드는 솔루션을 인쇄하는 데 도움이됩니다.

print ('\n'+ output_zebra + 'owns zebra.')

위 코드의 출력은 다음과 같습니다.

German owns zebra.