AI with Python - Logic Programming



In this section, we will focus logic programming and how it helps in Artificial Intelligence.

We already realize that logic is the study of principles of correct reasoning or in simple words it is the study of what comes after what. For example, if two statements are true then we can infer any third explanation from it.

Concept

Logic Programming is the combination of two words, logic and programming. Logic Programming is a programming paradigm in which the issues are expressed as facts and rules by program statements but within a system of formal logic. Just like other programming paradigms like object oriented, functional, declarative, and procedural, etc., it is additionally a particular way to approach programming.

How to Solve Problems with Logic Programming

Logic Programming utilizes facts and rules for solving the issue. That is why they are called the building blocks of Logic Programming. A goal needs to be specified for every program in logic programming. To see how a problem can be solved in logic programming, we need to know about the building blocks − Facts and Rules −

Facts

Actually, every logic program needs facts to work with so that it can accomplish the given goal. Facts basically are true statements about the program and data. For example, Delhi is the capital of India.

Rules

Actually, rules are the constraints which permit us to make conclusions about the problem domain. Rules essentially written as logical clauses to express different facts. For example, if we are building any game then all the rules must be characterized.

Rules are very important to solve any issue in Logic Programming. Rules are basically logical conclusion which can express the facts. Following is the syntax of rule −

A:- B1,B2,...,Bn.

Here, A is the head and B1, B2, ... Bn is the body.

For example − ancestor(X,Y) :- father(X,Y).

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

This can be read as, for every X and Y, if X is the father of Y and Y is an ancestor of Z, X is the ancestor of Z. For every X and Y, X is the ancestor of Z, if X is the father of Y and Y is an ancestor of Z.

Installing Useful Packages

For starting logic programming in Python, we need to install the following two packages −

Kanren

It gives us a way to simplify the way we made code for business logic. It lets us express the logic in terms of rules and facts. The following command will help you install kanren −

pip install kanren

SymPy

SymPy is a Python library for symbolic mathematics. It aims to become a full-featured computer algebra system (CAS) while keeping the code as simple as possible in order to be comprehensible and easily extensible. The following command will assist you install SymPy −

pip install sympy

Examples of Logic Programming

Followings are some examples which can be solved by logic programming −

Matching mathematical expressions

Actually we can find the unknown values by utilizing logic programming in a very effective way. The following Python code will assist you match a mathematical expression −

Consider importing the following packages first −

from kanren import run, var, fact
from kanren.assoccomm import eq_assoccomm as eq
from kanren.assoccomm import commutative, associative

We have to characterize the mathematical operations which we are going to use −

add = 'add'
mul = 'mul'

Both addition and multiplication are communicative processes. Subsequently, we have to specify it and this can be done as follows −

fact(commutative, mul)
fact(commutative, add)
fact(associative, mul)
fact(associative, add)

It is mandatory to define variables; this can be done as follows −

a, b = var('a'), var('b')

We need to match the expression with the original pattern. We have the following original pattern, which is fundamentally (5+a)*b −

Original_pattern = (mul, (add, 5, a), b)

We have the following two expressions to match with the original pattern −

exp1 = (mul, 2, (add, 3, 1))
exp2 = (add,5,(mul,8,1))

Outcomes can be printed with the following command −

print(run(0, (a,b), eq(original_pattern, exp1)))
print(run(0, (a,b), eq(original_pattern, exp2)))

After running this code, we will get the following outcome −

((3,2))
()

The first output represents the values for a and b. The first expression matched the original pattern and returned the values for a and b but the second expression didn't match the original pattern hence nothing has been returned.

Checking for Prime Numbers

With the assistance of logic programming, we can find the prime numbers from a list of numbers and can also generate prime numbers. The Python code given below will find the prime number from a list of numbers and will also generate the first 10 prime numbers.

Let us first think about importing the following packages −

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

Now, we will define a function called prime_check which will check the prime numbers based on the given numbers as data.

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

Now, we need to declare a variable which will be used −

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

The output of the above code will be as following −

{19, 23, 29, 41}
(2, 3, 5, 7, 11, 13, 17, 19, 23, 29)

Solving Puzzles

Logic programming can be utilized to solve many problems like 8-puzzles, Zebra puzzle, Sudoku, N-queen, etc. Here we are taking an example of a variant of Zebra puzzle which is as per the following −

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.

We are solving it for the question who owns zebra with the help of Python.

Let us import the necessary packages −

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

Now, we need to characterize two functions − left() and next() to check whose house is left or next to who’s house −

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

Now, we will declare a variable house as follows −

houses = var()

We need to define the rules with the help of lall package as follows.

There are 5 houses −

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

Now, run the solver with the preceding constraints −

solutions = run(0, houses, rules_zebraproblem)

With the help of the following code, we can extract the outcomes from the solver −

output_zebra = [house for house in solutions[0] if 'zebra' in house][0][0]

The following code will help print the solution −

print ('\n'+ output_zebra + 'owns zebra.')

The output of the above code would be as follows −

German owns zebra.




Input your Topic Name and press Enter.