Introduction We humans gather knowledge from our surrounding environment since the day we came into this earth. Using our five senses we...
Introduction
We humans gather knowledge from our surrounding environment since the day we came into this earth. Using our five senses we collect information and based on that information we make decisions to perform tasks. Now how can machines do this? How can we design machines in a way that they can acquire knowledge in themselves? In this report that’s what we will find out.
This report is a part of the Artificial Intelligence course Lab-work under the supervision
of Nuruzzaman Faruqui, Lecturer of City University, Bangladesh. This course
offers students various up-to-date AI topics. Students get to explore the real
applicable approaches through AI. From this course, the student acquires better
knowledge of the functionality of AI and how AI is making our daily life
easier. This is the best Artificial Intelligence course in Bangladesh.
Problem statement
Similar to the human’s learning concept we can use AI to give the knowledge to make an intelligent system. In this case, we use the term Knowledge
Representation. Now, Knowledge representation is a way to feed information to a
Knowledge-based agent. An agent can be only intelligent when it is
knowledge-based. With that, another term pops up i.e., Knowledge representation
and reasoning. By reasoning it means, by using existing knowledge agent
performs operations to provide predictions or draw conclusions. In this report, we
will build a knowledge-based for an agent to give real-world information. And
based on that, we will infer possible outcomes. We can build knowledge-based by
using propositional logic. Now, generally we humans use sentences to collect
information. The machine can not be fed directly with human language. That’s where
propositional logic comes to the rescue. It helps to make sentences in a way that
AI can store knowledge and infer new information.
We will
not go into details of propositional logic. Basic logical connectives we have
learned in discrete mathematics are applied to make a knowledge-base. Such as, Not
(¬), And (∧), Or (∨), Implication (→), Bidirectional (↔).
Another logical connective you may or may not be familiar that is Entailment (⊨). What it
means is, if a ⊨ b, then in any world where a is true, b is also true.
To
understand how we can build a knowledge-based agent and its operation, consider
the following example: -
1.
If it didn’t rain, Harry visited Hagrid today.
2. Harry
visited Hagrid or Dumbledore today, but not both.
3.
Harry visited Dumbledore today.
So, we
will use the above sentences to make a knowledge-base and make an intelligent
system that will tell us, did it rain today? Or, did Harry visit Hagrid today?
Code Explanation
Let’s see
how we can use propositional logic as a translation machine to make sentences
understandable for our AI agent. We have used python to make logical
connectives.
import
itertools
class Sentence():
def
evaluate(self, model):
"""Evaluates the logical
sentence."""
raise Exception("nothing to evaluate")
def
formula(self):
"""Returns string formula
representing logical sentence."""
return ""
def
symbols(self):
"""Returns a set of all symbols in
the logical sentence."""
return set()
@classmethod
def
validate(cls, sentence):
if not isinstance(sentence,
Sentence):
raise TypeError("must be a logical
sentence")
@classmethod
def
parenthesize(cls, s):
"""Parenthesizes an expression if
not already parenthesized."""
def balanced(s):
"""Checks if a
string has balanced parentheses."""
count = 0
for c in s:
if c == "(":
count += 1
elif c == ")":
if count <= 0:
return False
count -= 1
return count == 0
if not len(s) or s.isalpha() or (
s[0] == "(" and s[-1] == ")" and balanced(s[1:-1])
):
return s
else:
return f"({s})"
class Symbol(Sentence):
def
__init__(self, name):
self.name = name
def
__eq__(self, other):
return isinstance(other, Symbol) and self.name == other.name
def
__hash__(self):
return hash(("symbol", self.name))
def
__repr__(self):
return self.name
def
evaluate(self, model):
try:
return bool(model[self.name])
except KeyError:
raise EvaluationException(f"variable {self.name} not in model")
def
formula(self):
return self.name
def
symbols(self):
return {self.name}
class Not(Sentence):
def
__init__(self, operand):
Sentence.validate(operand)
self.operand = operand
def
__eq__(self, other):
return isinstance(other, Not) and
self.operand == other.operand
def
__hash__(self):
return hash(("not", hash(self.operand)))
def
__repr__(self):
return f"Not({self.operand})"
def
evaluate(self, model):
return not self.operand.evaluate(model)
def
formula(self):
return "¬" +
Sentence.parenthesize(self.operand.formula())
def
symbols(self):
return self.operand.symbols()
class And(Sentence):
def
__init__(self, *conjuncts):
for conjunct in
conjuncts:
Sentence.validate(conjunct)
self.conjuncts = list(conjuncts)
def
__eq__(self, other):
return isinstance(other, And) and
self.conjuncts == other.conjuncts
def
__hash__(self):
return hash(
("and", tuple(hash(conjunct) for conjunct in self.conjuncts))
)
def
__repr__(self):
conjunctions = ", ".join(
[str(conjunct) for conjunct in self.conjuncts]
)
return f"And({conjunctions})"
def
add(self, conjunct):
Sentence.validate(conjunct)
self.conjuncts.append(conjunct)
def
evaluate(self, model):
return all(conjunct.evaluate(model) for conjunct in
self.conjuncts)
def
formula(self):
if len(self.conjuncts) == 1:
return self.conjuncts[0].formula()
return "
∧ ".join([Sentence.parenthesize(conjunct.formula())
for conjunct in self.conjuncts])
def
symbols(self):
return set.union(*[conjunct.symbols() for conjunct in
self.conjuncts])
class Or(Sentence):
def
__init__(self, *disjuncts):
for disjunct in
disjuncts:
Sentence.validate(disjunct)
self.disjuncts = list(disjuncts)
def
__eq__(self, other):
return isinstance(other, Or) and
self.disjuncts == other.disjuncts
def
__hash__(self):
return hash(
("or", tuple(hash(disjunct) for disjunct in self.disjuncts))
)
def
__repr__(self):
disjuncts = ", ".join([str(disjunct) for disjunct in self.disjuncts])
return f"Or({disjuncts})"
def
evaluate(self, model):
return any(disjunct.evaluate(model) for disjunct in
self.disjuncts)
def
formula(self):
if len(self.disjuncts) == 1:
return self.disjuncts[0].formula()
return "
∨ ".join([Sentence.parenthesize(disjunct.formula())
for disjunct in self.disjuncts])
def
symbols(self):
return set.union(*[disjunct.symbols() for disjunct in
self.disjuncts])
class Implication(Sentence):
def
__init__(self, antecedent, consequent):
Sentence.validate(antecedent)
Sentence.validate(consequent)
self.antecedent = antecedent
self.consequent = consequent
def
__eq__(self, other):
return (isinstance(other, Implication)
and self.antecedent ==
other.antecedent
and self.consequent ==
other.consequent)
def
__hash__(self):
return hash(("implies", hash(self.antecedent), hash(self.consequent)))
def
__repr__(self):
return f"Implication({self.antecedent}, {self.consequent})"
def
evaluate(self, model):
return ((not
self.antecedent.evaluate(model))
or
self.consequent.evaluate(model))
def
formula(self):
antecedent =
Sentence.parenthesize(self.antecedent.formula())
consequent =
Sentence.parenthesize(self.consequent.formula())
return f"{antecedent} => {consequent}"
def
symbols(self):
return set.union(self.antecedent.symbols(),
self.consequent.symbols())
class Biconditional(Sentence):
def
__init__(self, left, right):
Sentence.validate(left)
Sentence.validate(right)
self.left = left
self.right = right
def
__eq__(self, other):
return (isinstance(other, Biconditional)
and self.left == other.left
and self.right == other.right)
def
__hash__(self):
return hash(("biconditional", hash(self.left), hash(self.right)))
def
__repr__(self):
return f"Biconditional({self.left}, {self.right})"
def
evaluate(self, model):
return ((self.left.evaluate(model)
and self.right.evaluate(model))
or
(not self.left.evaluate(model)
and not self.right.evaluate(model)))
def
formula(self):
left =
Sentence.parenthesize(str(self.left))
right =
Sentence.parenthesize(str(self.right))
return f"{left} <=> {right}"
def
symbols(self):
return set.union(self.left.symbols(), self.right.symbols())
def model_check(knowledge,
query):
"""Checks if knowledge base entails
query."""
def
check_all(knowledge, query, symbols, model):
"""Checks if knowledge base entails
query, given a particular model."""
# If model has an
assignment for each symbol
if not symbols:
# If knowledge
base is true in model, then query must also be true
if knowledge.evaluate(model):
return query.evaluate(model)
return True
else:
# Choose one of
the remaining unused symbols
remaining = symbols.copy()
p = remaining.pop()
# Create a model
where the symbol is true
model_true = model.copy()
model_true[p] = True
# Create a model
where the symbol is false
model_false = model.copy()
model_false[p] = False
# Ensure
entailment holds in both models
return (check_all(knowledge, query,
remaining, model_true) and
check_all(knowledge,
query, remaining, model_false))
# Get all symbols
in both knowledge and query
symbols = set.union(knowledge.symbols(),
query.symbols())
# Check that
knowledge entails query
return
check_all(knowledge, query, symbols, dict())
Just like
we import libraries in Python we will import the above code to use all the
logical connectives.
Now let’s
see how we will make a knowledge-base:
'''
This code represents an explanation of how an AI can make decision of human language. The following sentences were
used in this code,
(1) If it didn't rain, Harry visited Hagrid today
(2) Harry visited Hagrid or Dumbledore today, but not both
(3) harry visited Dumbledore today
Based on this three information a knowledge base was built to come to solutions. That solutions are:
(1) Harry did not vist Hagrid today
(2)It rained today
'''
# "*" implies that all the variables and functions will be used from logic.py
from logic import *
# we are using symbol to translate our human language into propositional logic
rain = Symbol("rain")
hagrid = Symbol("hagrid")
dumbledore = Symbol("dumpledore")
# This just shows how to formulate sentences logically.
logical_sentence = And(rain, hagrid)
print(logical_sentence.formula()) # it prints(rain ∧ hagrid)
# implication means if this happens then this. So, here if Not(rain), then Hagrid
implication_logic = Implication(Not(rain), hagrid)
print(implication_logic.formula())
# Building knowledge base means adding all the possible information
knowledge_base = And(
Implication(Not(rain), hagrid),
Or(hagrid, dumbledore),
Not(And(hagrid, dumbledore)),
dumbledore
)
print(knowledge_base.formula()) # it just prints all the information in logical sentence
print(model_check(knowledge_base, rain)) # it provides the solution by checking the knowledge base we built
The above code explained with comments.
Result
After executing the code, we get the following output-
Conclusion
Knowledge
representation is a must learning topic in AI. You can actually learn here how
to make a connection between humans and machines. Through machines how we can get
unknown information just like we come up with our human brain. We also used
discrete mathematics in knowledge representation. So, before you jump into this
topic make sure you understand logical connectives properly. Then you can
easily translate human languages in a way that a machine could understand.
As you can see, this course was
instructed that way, we go through the topic first, then apply what we learn
into a real-life problem. And solve it using python. I believe this is one of
the best ways if you are a beginner, just starting out in Artificial Intelligence.
Without any doubt, this course stands out as the best AI course in Bangladesh.


No comments