- Python人工智慧教程
- 首頁
- Python人工智慧——入門概念
- Python人工智慧——入門指南
- Python人工智慧——機器學習
- Python人工智慧——資料準備
- 監督學習:分類
- 監督學習:迴歸
- Python人工智慧——邏輯程式設計
- 無監督學習:聚類
- 自然語言處理
- Python人工智慧——NLTK包
- 時間序列資料分析
- Python人工智慧——語音識別
- Python人工智慧——啟發式搜尋
- Python人工智慧——遊戲
- Python人工智慧——神經網路
- 強化學習
- Python人工智慧——遺傳演算法
- Python人工智慧——計算機視覺
- Python人工智慧——深度學習
- Python人工智慧資源
- Python人工智慧——快速指南
- Python人工智慧——有用資源
- Python人工智慧——討論
Python人工智慧——邏輯程式設計
本章我們將重點介紹邏輯程式設計及其在人工智慧中的作用。
我們已經知道,邏輯是研究正確推理原則的學科,簡單來說,就是研究事物前後關係的學科。例如,如果兩個陳述為真,我們可以從中推斷出任何第三個陳述。
概念
邏輯程式設計是邏輯和程式設計兩個詞的組合。邏輯程式設計是一種程式設計正規化,其中問題透過程式語句以事實和規則的形式表達,但在形式邏輯系統內。就像其他程式設計正規化(如面向物件、函式式、宣告式和過程式等)一樣,它也是一種特定的程式設計方法。
如何用邏輯程式設計解決問題
邏輯程式設計使用事實和規則來解決問題。這就是為什麼它們被稱為邏輯程式設計的構建塊。邏輯程式設計中的每個程式都需要指定一個目標。要理解如何在邏輯程式設計中解決問題,我們需要了解構建塊——事實和規則——
事實
實際上,每個邏輯程式都需要事實來執行,以便實現既定目標。事實基本上是關於程式和資料的真實陳述。例如,德里是印度的首都。
規則
實際上,規則是可以讓我們對問題領域做出結論的約束。規則基本上寫成邏輯子句來表達各種事實。例如,如果我們正在構建任何遊戲,那麼必須定義所有規則。
規則對於解決邏輯程式設計中的任何問題都非常重要。規則基本上是能夠表達事實的邏輯結論。以下是規則的語法:
A∶− B1,B2,...,Bn。
這裡,A是頭部,B1, B2, ... Bn是主體。
例如:
ancestor(X,Y) :- father(X,Y).
ancestor(X,Z) :- father(X,Y), ancestor(Y,Z).
安裝有用的包
要在Python中開始邏輯程式設計,我們需要安裝以下兩個包:
Kanren
它為我們提供了一種簡化業務邏輯程式碼編寫方式的方法。它允許我們用規則和事實來表達邏輯。以下命令將幫助您安裝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)
我們有以下兩個表示式與原始模式匹配:
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的值。第一個表示式與原始模式匹配並返回了a和b的值,但第二個表示式與原始模式不匹配,因此沒有返回任何內容。
檢查素數
藉助邏輯程式設計,我們可以從數字列表中找到素數,也可以生成素數。下面給出的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皇后等。這裡我們以斑馬難題的一個變體為例,如下所示:
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
現在,我們需要定義兩個函式——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)])
現在,我們將宣告一個名為house的變數,如下所示:
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.