AI z Pythonem - programowanie logiczne
W tym rozdziale skupimy się na programowaniu logicznym i tym, jak pomaga w sztucznej inteligencji.
Wiemy już, że logika to nauka o zasadach prawidłowego rozumowania lub w prostych słowach to badanie tego, co następuje po czym. Na przykład, jeśli dwa stwierdzenia są prawdziwe, możemy z nich wywnioskować dowolne trzecie stwierdzenie.
Pojęcie
Programowanie logiczne to połączenie dwóch słów, logiki i programowania. Programowanie logiczne to paradygmat programowania, w którym problemy są wyrażane jako fakty i reguły przez instrukcje programu, ale w ramach systemu logiki formalnej. Podobnie jak inne paradygmaty programowania, takie jak obiektowe, funkcjonalne, deklaratywne i proceduralne itp., Jest to również szczególny sposób podejścia do programowania.
Jak rozwiązywać problemy z programowaniem logicznym
Programowanie logiczne wykorzystuje fakty i reguły do rozwiązania problemu. Dlatego nazywa się je elementami składowymi programowania w logice. Dla każdego programu w programowaniu logicznym należy określić cel. Aby zrozumieć, jak można rozwiązać problem w programowaniu logicznym, musimy wiedzieć o elementach konstrukcyjnych - Fakty i zasady -
Fakty
Właściwie każdy program logiczny potrzebuje faktów do pracy, aby mógł osiągnąć wyznaczony cel. W zasadzie fakty są prawdziwymi stwierdzeniami na temat programu i danych. Na przykład Delhi jest stolicą Indii.
Zasady
W rzeczywistości reguły są ograniczeniami, które pozwalają nam wyciągać wnioski dotyczące dziedziny problemowej. Reguły zasadniczo napisane jako logiczne klauzule wyrażające różne fakty. Na przykład, jeśli budujemy jakąkolwiek grę, wszystkie reguły muszą być zdefiniowane.
Reguły są bardzo ważne, aby rozwiązać każdy problem w programowaniu logicznym. Zasady są w zasadzie logicznym wnioskiem, który może wyrażać fakty. Poniżej znajduje się składnia reguły -
A∶− B1, B2, ..., B n .
Tutaj A to głowa, a B1, B2, ... Bn to ciało.
Na przykład - przodek (X, Y): - ojciec (X, Y).
przodek (X, Z): - ojciec (X, Y), przodek (Y, Z).
Można to odczytać w ten sposób, że dla każdego X i Y, jeśli X jest ojcem Y, a Y jest przodkiem Z, X jest przodkiem Z. Dla każdego X i Y, X jest przodkiem Z, jeśli X jest ojciec Y i Y jest przodkiem Z.
Instalowanie przydatnych pakietów
Aby rozpocząć programowanie logiczne w Pythonie, musimy zainstalować następujące dwa pakiety -
Kanren
Daje nam sposób na uproszczenie sposobu, w jaki tworzymy kod dla logiki biznesowej. Pozwala nam wyrazić logikę w kategoriach reguł i faktów. Następujące polecenie pomoże ci zainstalować kanren -
pip install kanren
SymPy
SymPy to biblioteka Pythona do matematyki symbolicznej. Ma na celu stać się w pełni funkcjonalnym systemem algebry komputerowej (CAS), zachowując kod tak prosty, jak to tylko możliwe, aby był zrozumiały i łatwo rozszerzalny. Następujące polecenie pomoże Ci zainstalować SymPy -
pip install sympy
Przykłady programowania logicznego
Poniżej znajduje się kilka przykładów, które można rozwiązać za pomocą programowania logicznego -
Dopasowywanie wyrażeń matematycznych
Właściwie możemy znaleźć nieznane wartości za pomocą programowania logicznego w bardzo efektywny sposób. Poniższy kod w Pythonie pomoże ci dopasować wyrażenie matematyczne -
Rozważ najpierw zaimportowanie następujących pakietów -
from kanren import run, var, fact
from kanren.assoccomm import eq_assoccomm as eq
from kanren.assoccomm import commutative, associative
Musimy zdefiniować operacje matematyczne, których będziemy używać -
add = 'add'
mul = 'mul'
Zarówno dodawanie, jak i mnożenie są procesami komunikacyjnymi. Dlatego musimy to określić i można to zrobić w następujący sposób -
fact(commutative, mul)
fact(commutative, add)
fact(associative, mul)
fact(associative, add)
Definiowanie zmiennych jest obowiązkowe; można to zrobić w następujący sposób -
a, b = var('a'), var('b')
Musimy dopasować wyrażenie do oryginalnego wzorca. Mamy następujący oryginalny wzór, który jest w zasadzie (5 + a) * b -
Original_pattern = (mul, (add, 5, a), b)
Mamy następujące dwa wyrażenia pasujące do oryginalnego wzorca -
exp1 = (mul, 2, (add, 3, 1))
exp2 = (add,5,(mul,8,1))
Dane wyjściowe można wydrukować za pomocą następującego polecenia -
print(run(0, (a,b), eq(original_pattern, exp1)))
print(run(0, (a,b), eq(original_pattern, exp2)))
Po uruchomieniu tego kodu otrzymamy następujące dane wyjściowe -
((3,2))
()
Pierwsze wyjście przedstawia wartości a i b. Pierwsze wyrażenie pasowało do oryginalnego wzorca i zwróciło wartościa i b ale drugie wyrażenie nie pasowało do oryginalnego wzorca, dlatego nic nie zostało zwrócone.
Sprawdzanie liczb pierwszych
Za pomocą programowania logicznego możemy znaleźć liczby pierwsze z listy liczb, a także wygenerować liczby pierwsze. Podany poniżej kod Pythona znajdzie liczbę pierwszą z listy liczb, a także wygeneruje pierwsze 10 liczb pierwszych.
Rozważmy najpierw zaimportowanie następujących pakietów -
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
Teraz zdefiniujemy funkcję o nazwie prime_check, która sprawdzi liczby pierwsze na podstawie podanych liczb jako danych.
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
Teraz musimy zadeklarować zmienną, która będzie używana -
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))))
Wynik powyższego kodu będzie następujący -
{19, 23, 29, 41}
(2, 3, 5, 7, 11, 13, 17, 19, 23, 29)
Rozwiazywac zagadki
Programowanie logiczne może być używane do rozwiązywania wielu problemów, takich jak puzzle 8, puzzle Zebra, Sudoku, N-queen, itp. Tutaj bierzemy przykład wariantu układanki Zebra, który jest następujący -
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.
Rozwiązujemy to na pytanie who owns zebra z pomocą Pythona.
Zaimportujmy niezbędne pakiety -
from kanren import *
from kanren.core import lall
import time
Teraz musimy zdefiniować dwie funkcje - left() i next() aby sprawdzić, czyj dom jest pozostawiony lub obok czyjego domu -
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)])
Teraz zadeklarujemy zmienny dom w następujący sposób -
houses = var()
Musimy zdefiniować zasady za pomocą pakietu lall w następujący sposób.
Jest 5 domów -
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)
)
Teraz uruchom solvera z powyższymi ograniczeniami -
solutions = run(0, houses, rules_zebraproblem)
Za pomocą następującego kodu możemy wyodrębnić dane wyjściowe z solwera -
output_zebra = [house for house in solutions[0] if 'zebra' in house][0][0]
Poniższy kod pomoże wydrukować rozwiązanie -
print ('\n'+ output_zebra + 'owns zebra.')
Wynik powyższego kodu byłby następujący -
German owns zebra.