天天看點

人工智能邏輯程式設計(python)

在本章中,我們将重點介紹邏輯程式設計以及它在人工智能中的作用。

我們已經知道邏輯是對正确推理原則的研究,或者簡單地說就是研究什麼是什麼。 例如,如果兩個陳述是真的,那麼我們可以從中推斷出任何第三個陳述。

概念

邏輯程式設計是兩個字,邏輯和程式設計的組合。 邏輯程式設計是一種程式設計模式,其中問題通過程式語句表達為事實和規則,但在形式邏輯系統中。 就像面向對象,函數式,聲明式和程式式等其他程式設計模式一樣,它也是程式設計方法的一種特殊方式。

如何用邏輯程式設計解決問題

邏輯程式設計使用事實和規則來解決問題。 這就是為什麼他們被稱為邏輯程式設計的基石。 在邏輯程式設計中需要為每個程式指定一個目标。要了解在邏輯程式設計中如何解決問題,我們需要了解建構塊 - 事實和規則 -

事實

實際上,每個邏輯程式都需要事實來處理,以達到既定目标。 事實上基本上是關于計劃和資料的真實陳述。 例如,北京是中國的首都。

規則

實際上,規則是允許我們對問題域做出結論的限制條件。 規則基本上寫成邏輯條款來表達各種事實。 例如,如果建構遊戲,那麼必須定義所有規則。

規則對于解決邏輯程式設計中的任何問題都非常重要。 規則基本上是可以表達事實的合乎邏輯的結論。 以下是規則的文法 -

1

​A∶− B1,B2,...,Bn.​

在這裡,A是頭部,B1,B2,… Bn是主體。

例如 - ​

​ancestor(X,Y): - father(X,Y)​

​。

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

對于每一個​

​X​

​和​

​Y​

​,如果​

​X​

​是​

​Y​

​的父親,​

​Y​

​Z​

​的祖先,那麼​

​X​

​Z​

​的祖先。對于每個​

​X​

​Y​

​,​

​X​

​Z​

​的祖先,如果​

​X​

​是 ​

​Y​

​Y​

​的父親是​

​Z​

​的祖先。

安裝必需的包

為了在Python中開始邏輯程式設計,需要安裝以下兩個包 -

Kanren

它為我們提供了一種簡化業務邏輯編寫代碼的方式。 它讓我們用規則和事實來表達邏輯。 以下指令來安裝​

​kanren​

​ -

​pip install kanren​

SymPy

SymPy是符号數學的Python庫。 它旨在成為一個全功能的計算機代數系統(CAS),同時保持代碼盡可能簡單,以便易于了解和擴充。 以下指令是用來安裝SymPy -

​pip install sympy​

邏輯程式設計的例子

以下是一些可以通過邏輯程式設計解決的例子 -

比對數學表達式

實際上,我們可以通過使用邏輯程式設計以非常有效的方式找到未知值。 以下Python代碼用于比對數學表達式 -

考慮先導入下列軟體包 -

2

3

​from kanren import run, var, fact​

​from kanren.assoccomm import eq_assoccomm ​

​​

​as​

​ ​

​eq​

​from kanren.assoccomm import commutative, associative​

需要定義要使用的數學運算 -

​add = ​

​'add'​

​mul = ​

​'mul'​

加法和乘法都是互動程序。 是以,我們需要指定它,這可以按照以下方式完成 -

4

​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​

​的函數,它将根據給定的數字檢查素數作為資料。

5

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

解決難題

參考 :http://www.zyiz.net/tutorial/detail-7864.html

邏輯程式設計可用于解決許多問題,如8拼圖,斑馬拼圖,數獨,N皇後等。在這裡,舉例說明斑馬拼圖的變體如下 -

6

7

8

9

10

11

12

13

14

15

16

​有五間房子。​

​英國人住在紅房子裡。​

​瑞典人有一隻狗。​

​丹麥人喝茶。​

​綠房子在白房子的左邊。​

​他們在綠房子裡喝咖啡。​

​吸Pall Mall的人有鳥。​

​吸Dunhill在的人黃色房子裡。​

​在中間的房子裡,他們喝牛奶。​

​挪威人住在第一宮。​

​那個抽Blend的男人住在貓屋旁邊的房子裡。​

​在他們有一匹馬的房子旁邊的房子裡,他們吸Dunhill煙。​

​抽Blue Master的人喝啤酒。​

​德國人吸Prince煙。​

​挪威人住在藍房子旁邊。​

​他們在房子旁邊的房子裡喝水,在那裡吸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)])​

現在,聲明一個變量:​

​houses​

​,如下 -

​houses = var()​

需要在​

​lall​

​包的幫助下定義規則如下。

有​

​5​

​間房子 -

17

18

19

20

21

22

23

24

25

​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.​

作者:沐雪