KI mit Python - Logikprogrammierung
In diesem Kapitel konzentrieren wir uns auf die Logikprogrammierung und wie sie in der künstlichen Intelligenz hilft.
Wir wissen bereits, dass Logik das Studium von Prinzipien des richtigen Denkens ist oder in einfachen Worten das Studium dessen, was nach was kommt. Wenn zum Beispiel zwei Aussagen wahr sind, können wir daraus jede dritte Aussage ableiten.
Konzept
Logikprogrammierung ist die Kombination von zwei Wörtern, Logik und Programmierung. Logikprogrammierung ist ein Programmierparadigma, bei dem die Probleme durch Programmanweisungen als Fakten und Regeln ausgedrückt werden, jedoch innerhalb eines Systems formaler Logik. Genau wie andere Programmierparadigmen wie objektorientiert, funktional, deklarativ und prozedural usw. ist es auch eine besondere Art, sich der Programmierung zu nähern.
So lösen Sie Probleme mit der Logikprogrammierung
Die Logikprogrammierung verwendet Fakten und Regeln zur Lösung des Problems. Deshalb werden sie als Bausteine der Logikprogrammierung bezeichnet. Für jedes Programm in der Logikprogrammierung muss ein Ziel angegeben werden. Um zu verstehen, wie ein Problem in der Logikprogrammierung gelöst werden kann, müssen wir die Bausteine kennen - Fakten und Regeln -
Fakten
Tatsächlich benötigt jedes Logikprogramm Fakten, mit denen es arbeiten kann, um das vorgegebene Ziel zu erreichen. Fakten sind im Grunde wahre Aussagen über das Programm und die Daten. Zum Beispiel ist Delhi die Hauptstadt von Indien.
Regeln
Tatsächlich sind Regeln die Einschränkungen, die es uns ermöglichen, Schlussfolgerungen über die Problemdomäne zu ziehen. Regeln, die im Grunde genommen als logische Klauseln geschrieben sind, um verschiedene Tatsachen auszudrücken. Wenn wir beispielsweise ein Spiel erstellen, müssen alle Regeln definiert werden.
Regeln sind sehr wichtig, um Probleme in der Logikprogrammierung zu lösen. Regeln sind grundsätzlich logische Schlussfolgerungen, die die Fakten ausdrücken können. Es folgt die Syntax der Regel -
A∶− B1, B2, ..., B n .
Hier ist A der Kopf und B1, B2, ... Bn ist der Körper.
Zum Beispiel - Vorfahr (X, Y): - Vater (X, Y).
Vorfahr (X, Z): - Vater (X, Y), Vorfahr (Y, Z).
Dies kann so gelesen werden, dass für jedes X und Y, wenn X der Vater von Y ist und Y ein Vorfahr von Z ist, X der Vorfahr von Z ist. Für jedes X und Y ist X der Vorfahr von Z, wenn X ist der Vater von Y und Y ist ein Vorfahr von Z.
Nützliche Pakete installieren
Um die Logikprogrammierung in Python zu starten, müssen wir die folgenden zwei Pakete installieren:
Kanren
Dies bietet uns eine Möglichkeit, die Art und Weise zu vereinfachen, in der wir Code für die Geschäftslogik erstellt haben. Es lässt uns die Logik in Bezug auf Regeln und Fakten ausdrücken. Der folgende Befehl hilft Ihnen bei der Installation von kanren -
pip install kanren
SymPy
SymPy ist eine Python-Bibliothek für symbolische Mathematik. Ziel ist es, ein voll ausgestattetes Computeralgebra-System (CAS) zu werden und gleichzeitig den Code so einfach wie möglich zu halten, um verständlich und leicht erweiterbar zu sein. Der folgende Befehl hilft Ihnen bei der Installation von SymPy -
pip install sympy
Beispiele für die Logikprogrammierung
Es folgen einige Beispiele, die durch logische Programmierung gelöst werden können -
Übereinstimmende mathematische Ausdrücke
Tatsächlich können wir die unbekannten Werte finden, indem wir die Logikprogrammierung auf sehr effektive Weise verwenden. Der folgende Python-Code hilft Ihnen beim Abgleichen eines mathematischen Ausdrucks:
Erwägen Sie zunächst den Import der folgenden Pakete:
from kanren import run, var, fact
from kanren.assoccomm import eq_assoccomm as eq
from kanren.assoccomm import commutative, associative
Wir müssen die mathematischen Operationen definieren, die wir verwenden werden -
add = 'add'
mul = 'mul'
Sowohl Addition als auch Multiplikation sind Kommunikationsprozesse. Daher müssen wir es spezifizieren und dies kann wie folgt erfolgen:
fact(commutative, mul)
fact(commutative, add)
fact(associative, mul)
fact(associative, add)
Es ist obligatorisch, Variablen zu definieren. Dies kann wie folgt erfolgen:
a, b = var('a'), var('b')
Wir müssen den Ausdruck mit dem ursprünglichen Muster abgleichen. Wir haben das folgende ursprüngliche Muster, das im Grunde (5 + a) * b - ist.
Original_pattern = (mul, (add, 5, a), b)
Wir haben die folgenden zwei Ausdrücke, die mit dem ursprünglichen Muster übereinstimmen -
exp1 = (mul, 2, (add, 3, 1))
exp2 = (add,5,(mul,8,1))
Die Ausgabe kann mit dem folgenden Befehl gedruckt werden:
print(run(0, (a,b), eq(original_pattern, exp1)))
print(run(0, (a,b), eq(original_pattern, exp2)))
Nach dem Ausführen dieses Codes erhalten wir die folgende Ausgabe:
((3,2))
()
Die erste Ausgabe repräsentiert die Werte für a und b. Der erste Ausdruck stimmte mit dem ursprünglichen Muster überein und gab die Werte für zurücka und b Der zweite Ausdruck stimmte jedoch nicht mit dem ursprünglichen Muster überein, daher wurde nichts zurückgegeben.
Nach Primzahlen suchen
Mit Hilfe der Logikprogrammierung können wir die Primzahlen aus einer Liste von Zahlen finden und auch Primzahlen erzeugen. Der unten angegebene Python-Code findet die Primzahl aus einer Liste von Zahlen und generiert auch die ersten 10 Primzahlen.
Betrachten wir zunächst den Import der folgenden Pakete:
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
Nun definieren wir eine Funktion namens prime_check, die die Primzahlen basierend auf den angegebenen Zahlen als Daten überprüft.
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
Jetzt müssen wir eine Variable deklarieren, die verwendet wird -
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))))
Die Ausgabe des obigen Codes lautet wie folgt:
{19, 23, 29, 41}
(2, 3, 5, 7, 11, 13, 17, 19, 23, 29)
Rätsel lösen
Die Logikprogrammierung kann verwendet werden, um viele Probleme wie 8-Puzzles, Zebra-Puzzles, Sudoku, N-Queen usw. zu lösen. Hier nehmen wir ein Beispiel für eine Variante des Zebra-Puzzles, die wie folgt lautet:
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.
Wir lösen es für die Frage who owns zebra mit Hilfe von Python.
Lassen Sie uns die notwendigen Pakete importieren -
from kanren import *
from kanren.core import lall
import time
Nun müssen wir zwei Funktionen definieren - left() und next() zu überprüfen, wessen Haus übrig ist oder neben wem das Haus -
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)])
Nun werden wir ein variables Haus wie folgt deklarieren:
houses = var()
Wir müssen die Regeln mit Hilfe von lall package wie folgt definieren.
Es gibt 5 Häuser -
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)
)
Führen Sie nun den Solver mit den vorhergehenden Einschränkungen aus -
solutions = run(0, houses, rules_zebraproblem)
Mit Hilfe des folgenden Codes können wir die Ausgabe aus dem Solver extrahieren -
output_zebra = [house for house in solutions[0] if 'zebra' in house][0][0]
Der folgende Code hilft beim Drucken der Lösung:
print ('\n'+ output_zebra + 'owns zebra.')
Die Ausgabe des obigen Codes wäre wie folgt:
German owns zebra.