Artificial-intelligence-with-python-logic-programming

提供:Dev Guides
移動先:案内検索

PythonとAI –ロジックプログラミング

この章では、ロジックプログラミングと、それが人工知能でどのように役立つかに焦点を当てます。

論理は正しい推論の原則の研究であること、または簡単な言葉で言えば、何が何の後に来るかを研究することであることはすでに知っています。 たとえば、2つのステートメントが真であれば、3番目のステートメントを推測できます。

概念

ロジックプログラミングは、ロジックとプログラミングの2つの単語の組み合わせです。 ロジックプログラミングは、問題がプログラムステートメントによって事実とルールとして表現されるプログラミングパラダイムですが、形式的なロジックのシステム内で行われます。 オブジェクト指向、関数型、宣言型、手続き型などの他のプログラミングパラダイムと同様に、プログラミングにアプローチするための特定の方法でもあります。

論理プログラミングで問題を解決する方法

ロジックプログラミングでは、事実とルールを使用して問題を解決します。 それが彼らが論理プログラミングの構成要素と呼ばれる理由です。 ロジックプログラミングでは、プログラムごとに目標を指定する必要があります。 ロジックプログラミングで問題を解決する方法を理解するには、ビルディングブロックについて知っておく必要があります-事実と規則-

事実

実際、すべてのロジックプログラムは、指定された目標を達成するために動作するファクトを必要とします。 事実は、基本的にプログラムとデータに関する真の声明です。 たとえば、デリーはインドの首都です。

規則

実際、ルールは問題領域について結論を出すことを可能にする制約です。 基本的に、さまざまな事実を表す論理句として記述されたルール。 たとえば、ゲームを構築する場合、すべてのルールを定義する必要があります。

ロジックプログラミングの問題を解決するには、ルールが非常に重要です。 ルールは基本的に、事実を表現できる論理的な結論です。 ルールの構文は次のとおりです-

A∶− B1、B2、…​、B〜n〜。

ここで、Aは頭で、B1、B2、…​ Bnは体です。

たとえば、-ancestor(X、Y):-father(X、Y)。

祖先(X、Z):-父(X、Y)、祖先(Y、Z)。

これは、XがYの父であり、YがZの祖先であり、XがZの祖先である場合、XおよびYごとに読み取ることができます。 XがYの父であり、YがZの祖先である場合、XおよびYごとに、XはZの祖先です。

便利なパッケージをインストールする

Pythonでロジックプログラミングを開始するには、次の2つのパッケージをインストールする必要があります-

かんれん

ビジネスロジックのコードを作成する方法を簡素化する方法を提供します。 これにより、ルールと事実の観点からロジックを表現できます。 次のコマンドは、あなたがkanrenをインストールするのに役立ちます-

pip install kanren

SymPy

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)

元のパターンと一致する次の2つの式があります-

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))
()

最初の出力は、 a および b の値を表しています。 最初の式は元のパターンと一致し、 ab の値を返しましたが、2番目の式は元のパターンと一致しなかったため、何も返されませんでした。

素数の確認

論理プログラミングの助けを借りて、数のリストから素数を見つけることができ、素数を生成することもできます。 下記の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パズル、ゼブラパズル、数独、Nクイーンなど、多くの問題を解決するために使用できます。 ここでは、次のような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.

Pythonの助けを借りて、*誰がシマウマを所有しているのか*という質問のために解決しています。

必要なパッケージをインポートしましょう-

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

次に、2つの関数を定義する必要があります-* 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.