Acciones

R12 sol

De Lógica Matemática y fundamentos (2015-16)

-- Clausulas.hs
-- Cláusulas.
-- ---------------------------------------------------------------------

module Clausulas where

-- ---------------------------------------------------------------------
-- Librería suxiliares                                                --
-- ---------------------------------------------------------------------

import SintaxisSemantica
import FormasNormales
import Data.List

-- ---------------------------------------------------------------------
-- Cláusulas                                                          --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 1: Definir el tipo de datos Clausula como una lista de
-- literales. 
-- ---------------------------------------------------------------------

type Clausula = [Literal]

-- ---------------------------------------------------------------------
-- Ejercicio 2: Definir la función
--    clausula :: Prop -> Clausula
-- tal que (clausula f) es la clausula de la fórmula-clausal f. Por
-- ejemplo, 
--    clausula p                                 ==>  [p]
--    clausula (no p)                            ==>  [no p]
--    clausula (((no p) \/ r) \/ ((no p) \/ q))  ==>  [q,r,no p]
-- ---------------------------------------------------------------------

clausula :: Prop -> Clausula
clausula f 
    | literal f     = [f]
clausula (Disj f g) = sort ((clausula f) `union` (clausula g))

-- ---------------------------------------------------------------------
-- Ejercicio 3: Definir la función
--    clausulasFNC :: Prop -> [Clausula]
-- tal que (clausulasFNC f) es el conjunto de clausulas de la fórmula en
-- forma normal conjuntiva f. Por ejmplo,
--    clausulasFNC (p /\ ((no q) \/ r))
--    ==> [[p],[r, no q]]
--    clausulasFNC (((no p) \/ q) /\ ((no p) \/ (no r)))
--    ==> [[q, no p],[no p,no r]]
-- ---------------------------------------------------------------------

clausulasFNC :: Prop -> [Clausula]
clausulasFNC (Conj f g) = 
    (clausulasFNC f) `union`  (clausulasFNC g) 
clausulasFNC f =
    [clausula f]

-- ---------------------------------------------------------------------
-- Ejercicio 4: Definir la función
--    clausulas :: Prop -> [Clausula]
-- tal que (clausulas f) es un conjunto de clausulas equivalente a
-- f. Por ejemplo,
--    clausulas (p /\ (q --> r))       
--    ==> [[p],[r,no q]]
--    clausulas (no (p /\ (q --> r)))  
--    ==> [[q,no p],[no p,no r]]
--    clausulas (no(p <--> r))         
--    ==> [[p,r],[p,no p],[r,no r],[no p,no r]]
-- ---------------------------------------------------------------------

clausulas :: Prop -> [Clausula]
clausulas f =
    clausulasFNC (formaNormalConjuntiva f)

-- ---------------------------------------------------------------------
-- Clausulas de un conjunto de fórmulas                               --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 5: Definir la función
--    clausulasConjunto :: [Prop] -> [Clausula]
-- tal que (clausulasConjunto s) es un conjunto de clausulas equivalente
-- a s. Por ejemplo,
--    clausulasConjunto [p --> q, q --> r]   ==>  [[q,no p],[r,no q]]
--    clausulasConjunto [p --> q, q <--> p]  ==>  [[q,no p],[p,no q]]
-- ---------------------------------------------------------------------

clausulasConjunto :: [Prop] -> [Clausula]
clausulasConjunto s =
    unionGeneral [clausulas f | f <- s]

-- ---------------------------------------------------------------------
-- Simbolos proposicionales de una clausula                           --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 6: Definir la función
--    simbolosProposicionalesClausula :: Clausula -> [Prop]
-- tal que (simbolosProposicionalesClausula c) es el conjunto de los
-- simbolos proposicionales de c. Por ejemplo,
--    simbolosProposicionalesClausula [p, q, no p]  ==>  [p,q]
-- ---------------------------------------------------------------------

simbolosProposicionalesClausula :: Clausula -> [Prop]
simbolosProposicionalesClausula = simbolosPropConj

-- ---------------------------------------------------------------------
-- Simbolos proposicionales de un conjunto de clausulas               --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 7: Definir la función
--    simbolosProposicionalesConjuntoClausula :: [Clausula] -> [Prop]
-- tal que (simbolosProposicionalesConjuntoClausula s) es el conjunto de los
-- simbolos proposicionales de s. Por ejemplo,
--    simbolosProposicionalesConjuntoClausula [[p, q],[no q, r]]
--    ==> [p,q,r]
-- ---------------------------------------------------------------------

simbolosProposicionalesConjuntoClausula :: [Clausula] -> [Prop]
simbolosProposicionalesConjuntoClausula s =
    unionGeneral [simbolosProposicionalesClausula c | c <- s]

-- ---------------------------------------------------------------------
-- Interpretaciones de una clausula                                   --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 8: Definir la función
--    interpretacionesClausula :: Clausula -> [Interpretación]
-- tal que (interpretacionesClausula c) es el conjunto de
-- interpretaciones de c. Por ejemplo,
--    interpretacionesClausula [p, q, no p]  ==>  [[p,q],[p],[q],[]]
--    interpretacionesClausula []            ==>  [[]]
-- ---------------------------------------------------------------------

interpretacionesClausula :: Clausula -> [Interpretación]
interpretacionesClausula c =
    subconjuntos (simbolosProposicionalesClausula c)

-- ---------------------------------------------------------------------
-- Interpretaciones de un conjunto de clausulas                       --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 9: Definir la función
--    interpretacionesConjuntoClausula :: [Clausula] -> [Interpretación]
-- tal que (interpretacionesConjuntoClausula s) es el conjunto de
-- interpretaciones de s. Por ejemplo,
--    interpretacionesConjuntoClausula [[p, no q],[no p, q]]
--    ==> [[p,q],[p],[q],[]]
--    interpretacionesConjuntoClausula []
--    ==> [[]]
-- ---------------------------------------------------------------------

interpretacionesConjuntoClausula :: [Clausula] -> [Interpretación]
interpretacionesConjuntoClausula c =
    subconjuntos (simbolosProposicionalesConjuntoClausula c)

-- ---------------------------------------------------------------------
-- Modelos de clausulas                                               --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 10: Definir la función
--    esModeloLiteral :: Interpretación -> Literal -> Bool
-- tal que (esModeloLiteral i l) se verifica si i es modelo de l. Por
-- ejemplo, 
--    esModeloLiteral [p,r] p       ==>  True
--    esModeloLiteral [p,r] q       ==>  False
--    esModeloLiteral [p,r] (no p)  ==>  False
--    esModeloLiteral [p,r] (no q)  ==>  True
-- ---------------------------------------------------------------------

esModeloLiteral :: Interpretación -> Literal -> Bool
esModeloLiteral i (Atom s)       = elem (Atom s) i
esModeloLiteral i (Neg (Atom s)) = notElem (Atom s) i

-- ---------------------------------------------------------------------
-- Ejercicio 11: Definir la función
--    esModeloClausula :: Interpretación -> Clausula -> Bool
-- tal que (esModeloClausula i c) se verifica si i es modelo de c . Por
-- ejemplo, 
--    esModeloClausula [p,r] [p, q]     ==>  True
--    esModeloClausula [r] [p, no q]    ==>  True
--    esModeloClausula [q,r] [p, no q]  ==>  False
--    esModeloClausula [q,r] []         ==>  False
-- ---------------------------------------------------------------------

esModeloClausula :: Interpretación -> Clausula -> Bool
esModeloClausula i c =
    or [esModeloLiteral i l | l <- c]

-- ---------------------------------------------------------------------
-- Ejercicio 12: Definir la función
--    modelosClausula :: Clausula -> [Interpretación]
-- tal que (modelosClausula c) es la lista de los modelos de c. Por
-- ejemplo, 
--    modelosClausula [no p, q]  ==>  [[p,q],[q],[]]
--    modelosClausula [no p, p]  ==>  [[p],[]]
--    modelosClausula []         ==>  []
-- ---------------------------------------------------------------------

modelosClausula :: Clausula -> [Interpretación]
modelosClausula c =
    [i | i <- interpretacionesClausula c,
         esModeloClausula i c]

-- ---------------------------------------------------------------------
-- Modelos de conjuntos de clausulas                                  --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 13: Definir la función
--    esModeloConjuntoClausulas :: Interpretación -> [Clausula] -> Bool
-- tal que (esModeloConjuntoClausulas i c) se verifica si i es modelo de
-- c. Por ejemplo,
--    esModeloConjuntoClausulas [p,r] [[p, no q], [r]]  ==>  True
--    esModeloConjuntoClausulas [p] [[p, no q], [r]]    ==>  False
--    esModeloConjuntoClausulas [p] []                  ==>  True
-- ---------------------------------------------------------------------

esModeloConjuntoClausulas :: Interpretación -> [Clausula] -> Bool
esModeloConjuntoClausulas i s =
    and [esModeloClausula i c | c <- s]

-- ---------------------------------------------------------------------
-- Ejercicio 14: Definir la función
--    modelosConjuntoClausulas :: [Clausula] -> [Interpretación]
-- tal que (modelosConjuntoClausulas s) es la lista de los modelos de
-- s. Por ejemplo, 
--    modelosConjuntoClausulas [[no p, q], [no q, p]]    
--    ==> [[p,q],[]]
--    modelosConjuntoClausulas [[no p, q], [p], [no q]]  
--    ==> []
--    modelosConjuntoClausulas [[p, no p, q]]            
--    ==> [[p,q],[p],[q],[]]
-- ---------------------------------------------------------------------

modelosConjuntoClausulas :: [Clausula] -> [Interpretación]
modelosConjuntoClausulas s =
    [i | i <- interpretacionesConjuntoClausula s,
         esModeloConjuntoClausulas i s] 

-- ---------------------------------------------------------------------
-- Clausulas válidas, satisfacibles e insatisfacibles                 --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 15: Definir la función
--    esClausulaValida :: Clausula -> Bool
-- tal que (esClausulaValida c) se verifica si la clausula c es
-- válida. Por ejemplo, 
--    esClausulaValida [p, q, no p]  ==>  True
--    esClausulaValida [p, q, no r]  ==>  False
--    esClausulaValida []            ==>  False
-- ---------------------------------------------------------------------

esClausulaValida :: Clausula -> Bool
esClausulaValida c =
    [l | l <- c, elem (complementario l) c] /= [] 

esClausulaValida1 :: Clausula -> Bool
esClausulaValida1 c =
    or [elem (complementario l) c | l <- c]


-- Definición alternativa:
esClausulaValida2 :: Clausula -> Bool
esClausulaValida2 c =
    and [esModeloClausula i c | i <- interpretacionesClausula c]

-- ---------------------------------------------------------------------
-- Ejercicio 16: Definir la función
--    esClausulaInsatisfacible :: Clausula -> Bool
-- tal que (esClausulaInsatisfacible c) se verifica si la clausula c es
-- insatisfacible. Por ejemplo, 
--    esClausulaInsatisfacible [p, q, no p]  ==>  False
--    esClausulaInsatisfacible [p, q, no r]  ==>  False
--    esClausulaInsatisfacible []            ==>  True
-- ---------------------------------------------------------------------

esClausulaInsatisfacible :: Clausula -> Bool
esClausulaInsatisfacible c =
    null c

-- Definición alternativa:
esClausulaInsatisfacible1 :: Clausula -> Bool
esClausulaInsatisfacible1 c =
    and [not (esModeloClausula i c) | i <- interpretacionesClausula c]

-- ---------------------------------------------------------------------
-- Ejercicio 17: Definir la función
--    esClausulaSatisfacible :: Clausula -> Bool
-- tal que (esClausulaSatisfacible c) se verifica si la clausula c es
-- satisfacible. Por ejemplo, 
--    esClausulaSatisfacible [p, q, no p]  ==>  True
--    esClausulaSatisfacible [p, q, no r]  ==>  True
--    esClausulaSatisfacible []  ==>  False
-- ---------------------------------------------------------------------

esClausulaSatisfacible :: Clausula -> Bool
esClausulaSatisfacible c =
    not (null c)

-- Definición alternativa:
esClausulaSatisfacible1 :: Clausula -> Bool
esClausulaSatisfacible1 c =
    or [esModeloClausula i c | i <- interpretacionesClausula c]

-- ---------------------------------------------------------------------
-- Conjuntos válidos, consistentes e inconsistentes de clausulas      --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 18: Definir la función
--    esConjuntoValidoDeClausulas :: [Clausula] -> Bool
-- tal que (esConjuntoValidoDeClausulas s) se verifica si el conjunto de
-- clausulas s es válido. Por ejemplo,
--    esConjuntoValidoDeClausulas [[no p, q], [no q, p]]  ==>  False
--    esConjuntoValidoDeClausulas [[no p, p], [no q, q]]  ==>  True
--    esConjuntoValidoDeClausulas []                      ==>  True
-- ---------------------------------------------------------------------

esConjuntoValidoDeClausulas :: [Clausula] -> Bool
esConjuntoValidoDeClausulas s =
    and [esClausulaValida c | c <- s]

-- Definición alternativa:
esConjuntoValidoDeClausulas1 :: [Clausula] -> Bool
esConjuntoValidoDeClausulas1 s =
    modelosConjuntoClausulas s == interpretacionesConjuntoClausula s

-- ---------------------------------------------------------------------
-- Ejercicio 19: Definir la función
--    esConjuntoConsistenteDeClausulas :: [Clausula] -> Bool
-- tal que (esConjuntoConsistenteDeClausulas s) se verifica si el
-- conjunto de clausulas s es consistente. Por ejemplo,
--    esConjuntoConsistenteDeClausulas [[no p, q], [no q, p]]  ==>  True
--    esConjuntoConsistenteDeClausulas [[no p, p], [no q, q]]  ==>  True
--    esConjuntoConsistenteDeClausulas []                      ==>  True
-- ---------------------------------------------------------------------

esConjuntoConsistenteDeClausulas :: [Clausula] -> Bool
esConjuntoConsistenteDeClausulas s =
    not (null (modelosConjuntoClausulas s))

-- ---------------------------------------------------------------------
-- Ejercicio 20: Definir la función
--    esConjuntoInconsistenteDeClausulas :: [Clausula] -> Bool
-- tal que (esConjuntoInconsistenteDeClausulas s) se verifica si el
-- conjunto de clausulas s es consistente. Por ejemplo,
--    esConjuntoInconsistenteDeClausulas [[no p,q],[no q,p]]  ==>  False
--    esConjuntoInconsistenteDeClausulas [[no p],[p]]         ==>  True
-- ---------------------------------------------------------------------

esConjuntoInconsistenteDeClausulas :: [Clausula] -> Bool
esConjuntoInconsistenteDeClausulas s =
    null (modelosConjuntoClausulas s)

-- ---------------------------------------------------------------------
-- Validez de fórmulas mediante clausulas                             --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 21: Definir la función
--    esValidaPorClausulas :: Prop -> Bool
-- tal que (esValidaPorClausulas f) se verifica si el conjunto de
-- clausulas de f es válido. Por ejemplo,
--    esValidaPorClausulas (p --> q)                 ==>  False
--    esValidaPorClausulas (p --> p)                 ==>  True
--    esValidaPorClausulas ((p --> q) \/ (q --> p))  ==>  True
-- ---------------------------------------------------------------------

esValidaPorClausulas :: Prop -> Bool
esValidaPorClausulas f =
    esConjuntoValidoDeClausulas (clausulas f)

-- ---------------------------------------------------------------------
-- Consecuencia mediante clausulas                                    --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 22: Definir la función
--    esConsecuenciaEntreClausulas :: [Clausula] -> [Clausula] -> Bool
-- tal que (esConsecuenciaEntreClausulas s1 s2) se verifica si todos los
-- modelos de s1 son modelos de s2. Por ejemplo,
--    esConsecuenciaEntreClausulas [[no p,q],[no q,r]] [[no p,r]]  
--    ==> True
--    esConsecuenciaEntreClausulas [[p]] [[p],[q]]                 
--    ==> False
-- ---------------------------------------------------------------------

esConsecuenciaEntreClausulas :: [Clausula] -> [Clausula] -> Bool
esConsecuenciaEntreClausulas s1 s2 =
    null [i | i <- interpretacionesConjuntoClausula (s1++s2)
            , esModeloConjuntoClausulas i s1
            , not ((esModeloConjuntoClausulas i s2))]

-- ---------------------------------------------------------------------
-- Ejercicio 23: Definir la función
--    esConsecuenciaPorClausulas1 :: [Prop] -> Prop -> Bool
-- tal que (esConsecuenciaPorClausulas s f) se verifica si las clausulas
-- de f son consecuencias de las de s. Por ejemplo,
--    esConsecuenciaPorClausulas [(p --> q), (q --> r)] (p --> r)
--    ==> True
--    esConsecuenciaPorClausulas [p] (p /\ q)
--    ==> False
-- ---------------------------------------------------------------------

esConsecuenciaPorClausulas :: [Prop] -> Prop -> Bool
esConsecuenciaPorClausulas s f =
    esConsecuenciaEntreClausulas (clausulasConjunto s) (clausulas f)

-- Definición alternativa:
esConsecuenciaPorClausulas1 :: [Prop] -> Prop -> Bool
esConsecuenciaPorClausulas1 s f =
    esConjuntoInconsistenteDeClausulas (clausulasConjunto ((Neg f):s))