#!/usr/bin/env python # coding: utf-8 # ## Artificial Intelligence, Lab 4 # # Propositional logic, Conjunctive Normal Forms, resolution, Horn clauses, forward and backward chaining # ### Exercise I. # # Recall that an implication $\alpha \Rightarrow \beta$ is valid if # # (R&N) which of the following propositions are correct? # # - False $\vDash$ True # - True $\vDash$ False # - $(A\wedge B)\vDash (A\Leftrightarrow B)$ # - $A \Leftrightarrow B \vDash A \vee B$ # - $A \Leftrightarrow B \vDash \lnot A \vee B$ # - $(A\wedge B) \Rightarrow C\vDash (A\Rightarrow C)\vee (B\Rightarrow C)$ # - $(C\wedge (\lnot A\wedge \lnot B))\equiv ((A\Rightarrow C)\wedge (B\Rightarrow C))$ # - $(A\vee B)\wedge (\lnot C\vee \lnot D\vee E)\vDash (A\vee B)$ # - $(A\vee B)\wedge (\lnot C\vee \lnot D\vee E)\vDash (A\vee B)\wedge (\lnot D\vee E)$ # # Recall that # # for any sentences $\alpha$ and $\beta$, we write $\alpha\vDash \beta$ if and only if the sentence $\alpha\Rightarrow \beta$ is valid (true in every row from the truth table). Moreover, $\alpha \vDash \beta$ if and only if the sentence $\alpha\wedge \lnot \beta$ is unsatisfiable. Recall that a sentence is satisfiable if it is true in some model. Consequently $\alpha$ is satisfiable iff $\lnot \alpha$ is not valid. # # Finally, any two sentences are equivalent if and only if $\alpha \vDash \beta$ and $\beta \vDash \alpha$. # ### Exercise II, Propositional connectives # # At the end of this exercise, you should have a way to store and decompose logical expressions. # #### Exercise II.1. # # We will encode symbols as strings starting with an uppercase letter such as 'A', 'Aa' or 'Bonjour'. When decomposing a propositional expression into its components, we will need a function that tells us whenever we have reached such symbol, called 'literal' and not an expression (with underlying connectives). Complete the function 'is_symbol' below which should check whether a given object is a literal or not. # In[ ]: def is_symbol(exp): '''the function should return True if the expression stored in exp is a literal (single symbol), i.e. if exp is a string that starts with an upper case letter''' if # complete the clause return True else: return False # #### Exercise II.2. # # Conjunctions and disjunctions. Complete the code below by providing for each object, a function strRepresentation that displays the proposition as a string. Use recursion in order to unfold the whole proposition. Test your function by encoding by displaying a couple of propostions. we will use the symbols '&' '|' and '=>' as well as '<=>' to display ther espective logical connectives # In[ ]: class LogicalOr: '''class ''' def __init__(self, arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 def strRepresentation(): '''complete''' class LogicalAnd: def __init__(self,arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 def strRepresentation(): '''complete''' # #### Exercise II.3. # # Extend the two classes above and include the implication, equivalence and the negation # In[ ]: class LogicalNot: def __init__(self, arg1): self.arg1 = arg1 def strRepresentation(): '''complete''' class LogicalEquivalence: def __init__(self,arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 def strRepresentation(): class LogicalImplication: def __init__(self, arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 def strRepresentation(): '''complete''' class LogicalEquivalence: def __init__(self,arg1, arg2): self.arg1 = arg1 self.arg2 = arg2 def strRepresentation(): '''complete''' # ### Exercise III. Conjunctive Normal Forms. # # By relying on the objects defined above, turn a general expression from propositional logic into a conjunctive normal form (CNF). Recall that the precedence rule are encoded by the order in wich the Propositional objects are built. We rely on the following rules # # - $\Leftrightarrow$ Elimination. replace $\alpha \Rightarrow \beta $ with $(\alpha\Rightarrow \beta )\wedge (\beta \Rightarrow \alpha)$ # - $\Rightarrow$ Elimination. Replace $\alpha \Rightarrow \beta $ with $\not \alpha \vee \beta$ # - Distribbution of $\lnot$: iteratively apply any of the following three steps # # - $\lnot(\lnot \alpha ) \equiv \alpha$ (double negation elimination) # - $\lnot(\alpha\wedge \beta) \equiv (\lnot \alpha \vee \lnot \beta) $ (De Morgan) # - $\lnot(\alpha \vee \beta) \equiv (\lnot \alpha \wedge \lnot\beta )$ # # - Distribution of $\vee$ over $\wedge$. $(\alpha\vee (\beta \wedge \gamma))\equiv ((\alpha \vee \beta)\wedge(\alpha \vee \gamma))$ # In[ ]: def to_Conjunctive_NormalForm(proposition): '''The function should return the CNF for the given proposition''' return propositionCNF # ### Exercise IV. Resolution rules # # Recall that the general resolution rule takes as premises two disjunctions and return a disjunction. I.e. # # $$\frac{\ell_1\vee \ldots \vee \ell_k, \quad m_1\vee \ldots m_n}{\ell_1\vee \ldots \ell_{i-1}\vee \ell_{i+1}\vee \ldots \ell_k\vee m_1\vee m_{j-1}\vee m_{j+1}\vee \ldots m_n}$$ # # # #### Exercise IV.1. Resolution function # # complete the function CNFresolution below which takes two disjunctions as premises and return all the propositions that can be derived from those clauses through validation. # # Apply your resolution algorithm to the Wumpus example where KB is represented by the proposition $(B_{1,1}\Leftrightarrow (P_{1,2}\vee P_{2,1}))\wedge \lnot B_{1,1}$ and we want to prove that $KB\vDash \lnot P_{1,2}$ # # In[ ]: ### def resolution(clause1, clause2): '''the function should return ''' return proposition # #### Exercise IV.4. Resolution algorithm. # # Code the resolution algorithm below. recall that this algorithm iterates on the following steps: # # # # # Start by trying the algorithm with simple KB such as single simple propositions. # In[ ]: def resolutionAlgorithm(KB, proposition): '''The algorithm should return true if the sentence stored in Proposition is entailed by the knowledge base KB''' return conclusion # #### Exercise IV.3. Propositional 2CNF # # A propositional 2-CNF expression is a conjunction of clauses, each containing _exactly_ two literals. As an example, consider the 2-CNF below: # # $$(A\vee B)\wedge (\lnot A\vee C)\wedge (\lnot B\vee D)\wedge (\lnot C\vee G)\wedge (\lnot D\vee G)$$ # # Use your resolution algorithm to show that the knowledge base $KB$ represented by the single 2-CNF above entails the literal $G$. # ### Exercise V. Horn clauses and Forward chaining. # A Horn clause is a disjunction of literals with at most one positive literal. As an example # # such clauses are particulary interesting because a clause of the form $(\lnot A\vee \lnot B\vee C)$ can always be writte as $(A\wedge B)\Rightarrow C$. # # Given a set of Horn clauses, we can determine whether the set entails a particular literal by using the Forward or Backward chaining algorithms which run in linear time in the size of the knowledge base. # # # # # Code this algorithm below and test it on the KB give by # # - $P\Rightarrow Q$ # - $L \wedge M \Rightarrow P$ # - $B\wedge L \Rightarrow M$ # - $A\wedge P\Rightarrow L$ # - $A\wedge B\Rightarrow L$ # - $A$ # - $B$ # In[ ]: def ForwardChainingPL(KB, proposition): '''the function should determine the value of the literal stored in proposition from the set of Horn clauses stored in the knowledge base KB''' return conclusion