Acciones

Diferencia entre revisiones de «R2a sol»

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

 
Línea 1: Línea 1:
 
<source lang="haskell">
 
<source lang="haskell">
 
 
-- SintaxisSemanticaProp.hs
 
-- SintaxisSemanticaProp.hs
 
-- Lógica proposicional: Sintaxis y semántica
 
-- Lógica proposicional: Sintaxis y semántica
Línea 26: Línea 25:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
type SímboloProposicional = String
+
type SimboloProposicional = String
  
data Prop = Atom SímboloProposicional
+
data Prop = Atom SimboloProposicional
 
           | Neg Prop  
 
           | Neg Prop  
 
           | Conj Prop Prop  
 
           | Conj Prop Prop  
Línea 94: Línea 93:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 5: Definir la función
 
-- Ejercicio 5: Definir la función
--    símbolosPropFórm :: Prop -> [Prop]
+
--    simbolosPropForm :: Prop -> [Prop]
-- tal que (símbolosPropFórm f) es el conjunto formado por todos los
+
-- tal que (simbolosPropForm f) es el conjunto formado por todos los
 
-- símbolos proposicionales que aparecen en f. Por ejemplo,
 
-- símbolos proposicionales que aparecen en f. Por ejemplo,
--    símbolosPropFórm (p /\ q --> p)  ==> [p,q]
+
--    simbolosPropForm (p /\ q --> p)  ==> [p,q]
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
símbolosPropFórm :: Prop -> [Prop]
+
simbolosPropForm :: Prop -> [Prop]
símbolosPropFórm (Atom f)  = [(Atom f)]
+
simbolosPropForm (Atom f)  = [(Atom f)]
símbolosPropFórm (Neg f)    = símbolosPropFórm f
+
simbolosPropForm (Neg f)    = simbolosPropForm f
símbolosPropFórm (Conj f g) = símbolosPropFórm f `union` símbolosPropFórm g
+
simbolosPropForm (Conj f g) = simbolosPropForm f `union` simbolosPropForm g
símbolosPropFórm (Disj f g) = símbolosPropFórm f `union` símbolosPropFórm g
+
simbolosPropForm (Disj f g) = simbolosPropForm f `union` simbolosPropForm g
símbolosPropFórm (Impl f g) = símbolosPropFórm f `union` símbolosPropFórm g
+
simbolosPropForm (Impl f g) = simbolosPropForm f `union` simbolosPropForm g
símbolosPropFórm (Equi f g) = símbolosPropFórm f `union` símbolosPropFórm g
+
simbolosPropForm (Equi f g) = simbolosPropForm f `union` simbolosPropForm g
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 117: Línea 116:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
type Interpretación = [Prop]
+
type Interpretacion = [Prop]
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 125: Línea 124:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 7: Definir la función
 
-- Ejercicio 7: Definir la función
--    significado :: Prop -> Interpretación -> Bool
+
--    significado :: Prop -> Interpretacion -> Bool
 
-- tal que (significado f i) es el significado de f en i. Por ejemplo,
 
-- tal que (significado f i) es el significado de f en i. Por ejemplo,
 
--    significado ((p \/ q) /\ ((no q) \/ r)) [r]    ==>  False
 
--    significado ((p \/ q) /\ ((no q) \/ r)) [r]    ==>  False
Línea 131: Línea 130:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
significado :: Prop -> Interpretación -> Bool
+
significado :: Prop -> Interpretacion -> Bool
 
significado (Atom f)  i = (Atom f) `elem` i
 
significado (Atom f)  i = (Atom f) `elem` i
 
significado (Neg f)    i = not (significado f i)
 
significado (Neg f)    i = not (significado f i)
Línea 158: Línea 157:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 9: Definir la función
 
-- Ejercicio 9: Definir la función
--    interpretacionesFórm :: Prop -> [Interpretación]
+
--    interpretacionesForm :: Prop -> [Interpretacion]
-- tal que (interpretacionesFórm f) es la lista de todas las
+
-- tal que (interpretacionesForm f) es la lista de todas las
 
-- interpretaciones de f. Por ejemplo,  
 
-- interpretaciones de f. Por ejemplo,  
--    interpretacionesFórm (p /\ q --> p)  ==>  [[p,q],[p],[q],[]]
+
--    interpretacionesForm (p /\ q --> p)  ==>  [[p,q],[p],[q],[]]
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
interpretacionesFórm :: Prop -> [Interpretación]
+
interpretacionesForm :: Prop -> [Interpretacion]
interpretacionesFórm f = subconjuntos (símbolosPropFórm f)
+
interpretacionesForm f = subconjuntos (simbolosPropForm f)
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 173: Línea 172:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 10: Definir la función
 
-- Ejercicio 10: Definir la función
--    esModeloFórmula :: Interpretación -> Prop -> Bool
+
--    esModeloFormula :: Interpretacion -> Prop -> Bool
-- tal que (esModeloFórmula i f) se verifica si i es un modelo de f. Por
+
-- tal que (esModeloFormula i f) se verifica si i es un modelo de f. Por
 
-- ejemplo,  
 
-- ejemplo,  
--    esModeloFórmula [r]  ((p \/ q) /\ ((no q) \/ r))    ==>  False
+
--    esModeloFormula [r]  ((p \/ q) /\ ((no q) \/ r))    ==>  False
--    esModeloFórmula [p,r] ((p \/ q) /\ ((no q) \/ r))    ==>  True
+
--    esModeloFormula [p,r] ((p \/ q) /\ ((no q) \/ r))    ==>  True
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
esModeloFórmula :: Interpretación -> Prop -> Bool
+
esModeloFormula :: Interpretacion -> Prop -> Bool
esModeloFórmula i f = significado f i
+
esModeloFormula i f = significado f i
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 11: Definir la función
 
-- Ejercicio 11: Definir la función
--    modelosFórmula :: Prop -> [Interpretación]
+
--    modelosFormula :: Prop -> [Interpretacion]
-- tal que (modelosFórmula f) es la lista de todas las interpretaciones
+
-- tal que (modelosFormula f) es la lista de todas las interpretaciones
 
-- de f que son modelo de F. Por ejemplo,
 
-- de f que son modelo de F. Por ejemplo,
--    modelosFórmula ((p \/ q) /\ ((no q) \/ r))  
+
--    modelosFormula ((p \/ q) /\ ((no q) \/ r))  
 
--    ==> [[p,q,r],[p,r],[p],[q,r]]
 
--    ==> [[p,q,r],[p,r],[p],[q,r]]
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
modelosFórmula :: Prop -> [Interpretación]
+
modelosFormula :: Prop -> [Interpretacion]
modelosFórmula f =
+
modelosFormula f =
     [i | i <- interpretacionesFórm f,
+
     [i | i <- interpretacionesForm f,
         esModeloFórmula i f]
+
         esModeloFormula i f]
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 203: Línea 202:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 12: Definir la función
 
-- Ejercicio 12: Definir la función
--    esVálida :: Prop -> Bool
+
--    esValida :: Prop -> Bool
-- tal que (esVálida f) se verifica si f es válida. Por ejemplo,
+
-- tal que (esValida f) se verifica si f es válida. Por ejemplo,
--    esVálida (p --> p)                ==>  True
+
--    esValida (p --> p)                ==>  True
--    esVálida (p --> q)                ==>  False
+
--    esValida (p --> q)                ==>  False
--    esVálida ((p --> q) \/ (q --> p))  ==>  True
+
--    esValida ((p --> q) \/ (q --> p))  ==>  True
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
esVálida :: Prop -> Bool
+
esValida :: Prop -> Bool
esVálida f =  
+
esValida f =  
     modelosFórmula f == interpretacionesFórm f
+
     modelosFormula f == interpretacionesForm f
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 225: Línea 224:
 
esInsatisfacible :: Prop -> Bool
 
esInsatisfacible :: Prop -> Bool
 
esInsatisfacible f =
 
esInsatisfacible f =
     modelosFórmula f == []
+
     modelosFormula f == []
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 238: Línea 237:
 
esSatisfacible :: Prop -> Bool
 
esSatisfacible :: Prop -> Bool
 
esSatisfacible f =
 
esSatisfacible f =
     modelosFórmula f /= []
+
     modelosFormula f /= []
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 246: Línea 245:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 15: Definir la función
 
-- Ejercicio 15: Definir la función
--    uniónGeneral :: Eq a => [[a]] -> [a]
+
--    unionGeneral :: Eq a => [[a]] -> [a]
-- tal que (uniónGeneral x) es la unión de los conjuntos de la lista de
+
-- tal que (unionGeneral x) es la unión de los conjuntos de la lista de
 
-- conjuntos x. Por ejemplo,
 
-- conjuntos x. Por ejemplo,
--    uniónGeneral []                ==>  []
+
--    unionGeneral []                ==>  []
--    uniónGeneral [[1]]              ==>  [1]
+
--    unionGeneral [[1]]              ==>  [1]
--    uniónGeneral [[1],[1,2],[2,3]]  ==>  [1,2,3]
+
--    unionGeneral [[1],[1,2],[2,3]]  ==>  [1,2,3]
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
uniónGeneral :: Eq a => [[a]] -> [a]
+
unionGeneral :: Eq a => [[a]] -> [a]
uniónGeneral []    = []
+
unionGeneral []    = []
uniónGeneral (xs:xss) = xs `union` uniónGeneral xss  
+
unionGeneral (xs:xss) = xs `union` unionGeneral xss  
  
 
uniónG :: Eq a => [[a]] -> [a]
 
uniónG :: Eq a => [[a]] -> [a]
Línea 272: Línea 271:
 
símbolosPropConj :: [Prop] -> [Prop]
 
símbolosPropConj :: [Prop] -> [Prop]
 
símbolosPropConj s
 
símbolosPropConj s
     = uniónGeneral [símbolosPropFórm f | f <- s]
+
     = unionGeneral [simbolosPropForm f | f <- s]
  
 
símbolosPropConj2 :: [Prop] -> [Prop]
 
símbolosPropConj2 :: [Prop] -> [Prop]
símbolosPropConj2 = uniónG . map símbolosPropFórm
+
símbolosPropConj2 = uniónG . map simbolosPropForm
  
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
Línea 283: Línea 282:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 17: Definir la función
 
-- Ejercicio 17: Definir la función
--    interpretacionesConjunto :: [Prop] -> [Interpretación]
+
--    interpretacionesConjunto :: [Prop] -> [Interpretacion]
 
-- tal que (interpretacionesConjunto s) es la lista de las
 
-- tal que (interpretacionesConjunto s) es la lista de las
 
-- interpretaciones de s. Por ejemplo,
 
-- interpretaciones de s. Por ejemplo,
Línea 290: Línea 289:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
interpretacionesConjunto :: [Prop] -> [Interpretación]
+
interpretacionesConjunto :: [Prop] -> [Interpretacion]
 
interpretacionesConjunto s =
 
interpretacionesConjunto s =
 
     subconjuntos (símbolosPropConj s)
 
     subconjuntos (símbolosPropConj s)
Línea 300: Línea 299:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
 
-- Ejercicio 18: Definir la función
 
-- Ejercicio 18: Definir la función
--    esModeloConjunto :: Interpretación -> [Prop] -> Bool
+
--    esModeloConjunto :: Interpretacion -> [Prop] -> Bool
 
-- tal que (esModeloConjunto i s) se verifica si i es modelo de s. Por
 
-- tal que (esModeloConjunto i s) se verifica si i es modelo de s. Por
 
-- ejemplo,  
 
-- ejemplo,  
Línea 309: Línea 308:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
esModeloConjunto :: Interpretación -> [Prop] -> Bool
+
esModeloConjunto :: Interpretacion -> [Prop] -> Bool
 
esModeloConjunto i s =
 
esModeloConjunto i s =
     and [esModeloFórmula i f | f <- s]
+
     and [esModeloFormula i f | f <- s]
  
esModeloConjunto2 :: Interpretación -> [Prop] -> Bool
+
esModeloConjunto2 :: Interpretacion -> [Prop] -> Bool
esModeloConjunto2 i s = all (esModeloFórmula i) s
+
esModeloConjunto2 i s = all (esModeloFormula i) s
  
 
-- --------------------g-------------------------------------------------
 
-- --------------------g-------------------------------------------------
 
-- Ejercicio 19: Definir la función
 
-- Ejercicio 19: Definir la función
--    modelosConjunto :: [Prop] -> [Interpretación]
+
--    modelosConjunto :: [Prop] -> [Interpretacion]
 
-- tal que (modelosConjunto s) es la lista de modelos del conjunto
 
-- tal que (modelosConjunto s) es la lista de modelos del conjunto
 
-- s. Por ejemplo,
 
-- s. Por ejemplo,
Línea 327: Línea 326:
 
-- ---------------------------------------------------------------------
 
-- ---------------------------------------------------------------------
  
modelosConjunto :: [Prop] -> [Interpretación]
+
modelosConjunto :: [Prop] -> [Interpretacion]
 
modelosConjunto s =
 
modelosConjunto s =
 
     [i | i <- interpretacionesConjunto s,
 
     [i | i <- interpretacionesConjunto s,
Línea 383: Línea 382:
 
     null [i | i <- interpretacionesConjunto (f:s),
 
     null [i | i <- interpretacionesConjunto (f:s),
 
               esModeloConjunto i s,
 
               esModeloConjunto i s,
               not (esModeloFórmula i f)]
+
               not (esModeloFormula i f)]
  
 
esConsecuencia2 :: [Prop] -> Prop -> Bool
 
esConsecuencia2 :: [Prop] -> Prop -> Bool
 
esConsecuencia2 s f =
 
esConsecuencia2 s f =
     and [esModeloFórmula i f | i <- interpretacionesConjunto (f:s),
+
     and [esModeloFormula i f | i <- interpretacionesConjunto (f:s),
 
                               esModeloConjunto i s]
 
                               esModeloConjunto i s]
 +
 +
  
 
</source>
 
</source>

Revisión actual del 13:48 21 abr 2016

-- SintaxisSemanticaProp.hs
-- Lógica proposicional: Sintaxis y semántica
-- ---------------------------------------------------------------------

module SintaxisSemantica where

-- ---------------------------------------------------------------------
-- Librerías auxiliares                                               --
-- ---------------------------------------------------------------------

import Data.List 

-- ---------------------------------------------------------------------
-- Gramática de fórmulas prosicionales                                --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 1: Definir los siguientes tipos de datos:
-- * SímboloProposicional para representar los símbolos de proposiciones
-- * Prop para representar las fórmulas proposicionales usando los
--   constructores Atom, Neg, Conj, Disj, Impl y Equi para las fórmulas
--   atómicas, negaciones, conjunciones, implicaciones y equivalencias,
--   respectivamente.  
-- ---------------------------------------------------------------------

type SimboloProposicional = String

data Prop = Atom SimboloProposicional
          | Neg Prop 
          | Conj Prop Prop 
          | Disj Prop Prop 
          | Impl Prop Prop 
          | Equi Prop Prop 
          deriving (Eq,Ord)

instance Show Prop where
    show (Atom p)   = p
    show (Neg p)    = "no " ++ show p
    show (Conj p q) = "(" ++ show p ++ " /\\ " ++ show q ++ ")"
    show (Disj p q) = "(" ++ show p ++ " \\/ " ++ show q ++ ")"
    show (Impl p q) = "(" ++ show p ++ " --> " ++ show q ++ ")"
    show (Equi p q) = "(" ++ show p ++ " <--> " ++ show q ++ ")"

-- ---------------------------------------------------------------------
-- Ejercicio 2: Definir las siguientes fórmulas proposicionales
-- atómicas: p, p1, p2, q, r, s, t y u.
-- ---------------------------------------------------------------------

p, p1, p2, q, r, s, t, u :: Prop
p  = Atom "p"
p1 = Atom "p1"
p2 = Atom "p2"
q  = Atom "q"
r  = Atom "r"
s  = Atom "s"
t  = Atom "t"
u  = Atom "u"

-- ---------------------------------------------------------------------
-- Ejercicio 3: Definir la función
--    no :: Prop -> Prop
-- tal que (no f) es la negación de f.
-- ---------------------------------------------------------------------

no :: Prop -> Prop
no = Neg

-- ---------------------------------------------------------------------
-- Ejercicio 4: Definir los siguientes operadores
--    (/\), (\/), (-->), (<-->) :: Prop -> Prop -> Prop
-- tales que
--    f /\ g      es la conjunción de f y g
--    f \/ g      es la disyunción de f y g
--    f --> g     es la implicación de f a g
--    f <--> g    es la equivalencia entre f y g
-- ---------------------------------------------------------------------

infixr 5 \/
infixr 4 /\
infixr 3 -->
infixr 2 <-->
(/\), (\/), (-->), (<-->) :: Prop -> Prop -> Prop
(/\)   = Conj
(\/)   = Disj
(-->)  = Impl
(<-->) = Equi

-- ---------------------------------------------------------------------
-- Símbolos proposicionales de una fórmula                            --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 5: Definir la función
--    simbolosPropForm :: Prop -> [Prop]
-- tal que (simbolosPropForm f) es el conjunto formado por todos los
-- símbolos proposicionales que aparecen en f. Por ejemplo,
--    simbolosPropForm (p /\ q --> p)  ==> [p,q]
-- ---------------------------------------------------------------------

simbolosPropForm :: Prop -> [Prop]
simbolosPropForm (Atom f)   = [(Atom f)]
simbolosPropForm (Neg f)    = simbolosPropForm f
simbolosPropForm (Conj f g) = simbolosPropForm f `union` simbolosPropForm g
simbolosPropForm (Disj f g) = simbolosPropForm f `union` simbolosPropForm g
simbolosPropForm (Impl f g) = simbolosPropForm f `union` simbolosPropForm g
simbolosPropForm (Equi f g) = simbolosPropForm f `union` simbolosPropForm g

-- ---------------------------------------------------------------------
-- Interpretaciones                                                   --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 6: Definir el tipo de datos Interpretación para
-- representar las interpretaciones como listas de fórmulas atómicas.
-- ---------------------------------------------------------------------

type Interpretacion = [Prop]

-- ---------------------------------------------------------------------
-- Significado de una fórmula en una interpretación                   --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 7: Definir la función
--    significado :: Prop -> Interpretacion -> Bool
-- tal que (significado f i) es el significado de f en i. Por ejemplo,
--    significado ((p \/ q) /\ ((no q) \/ r)) [r]    ==>  False
--    significado ((p \/ q) /\ ((no q) \/ r)) [p,r]  ==>  True
-- ---------------------------------------------------------------------

significado :: Prop -> Interpretacion -> Bool
significado (Atom f)   i = (Atom f) `elem` i
significado (Neg f)    i = not (significado f i)
significado (Conj f g) i = (significado f i) && (significado g i)
significado (Disj f g) i = (significado f i) || (significado g i)
significado (Impl f g) i = significado (Disj (Neg f) g) i
significado (Equi f g) i = significado (Conj (Impl f g) (Impl g f)) i

-- ---------------------------------------------------------------------
-- Interpretaciones de una fórmula                                    --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 8: Definir la función
--    subconjuntos :: [a] -> [[a]]
-- tal que (subconjuntos x) es la lista de los subconjuntos de x. Por
-- ejmplo, 
--    subconjuntos "abc"  ==>  ["abc","ab","ac","a","bc","b","c",""]
-- ---------------------------------------------------------------------

subconjuntos :: [a] -> [[a]]
subconjuntos []     = [[]]
subconjuntos (x:xs) = [x:ys | ys <- xss] ++ xss
                      where xss = subconjuntos xs

-- ---------------------------------------------------------------------
-- Ejercicio 9: Definir la función
--    interpretacionesForm :: Prop -> [Interpretacion]
-- tal que (interpretacionesForm f) es la lista de todas las
-- interpretaciones de f. Por ejemplo, 
--    interpretacionesForm (p /\ q --> p)  ==>  [[p,q],[p],[q],[]]
-- ---------------------------------------------------------------------

interpretacionesForm :: Prop -> [Interpretacion]
interpretacionesForm f = subconjuntos (simbolosPropForm f)

-- ---------------------------------------------------------------------
-- Modelos de fórmulas                                                --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 10: Definir la función
--    esModeloFormula :: Interpretacion -> Prop -> Bool
-- tal que (esModeloFormula i f) se verifica si i es un modelo de f. Por
-- ejemplo, 
--    esModeloFormula [r]   ((p \/ q) /\ ((no q) \/ r))    ==>  False
--    esModeloFormula [p,r] ((p \/ q) /\ ((no q) \/ r))    ==>  True
-- ---------------------------------------------------------------------

esModeloFormula :: Interpretacion -> Prop -> Bool
esModeloFormula i f = significado f i

-- ---------------------------------------------------------------------
-- Ejercicio 11: Definir la función
--    modelosFormula :: Prop -> [Interpretacion]
-- tal que (modelosFormula f) es la lista de todas las interpretaciones
-- de f que son modelo de F. Por ejemplo,
--    modelosFormula ((p \/ q) /\ ((no q) \/ r)) 
--    ==> [[p,q,r],[p,r],[p],[q,r]]
-- ---------------------------------------------------------------------

modelosFormula :: Prop -> [Interpretacion]
modelosFormula f =
    [i | i <- interpretacionesForm f,
         esModeloFormula i f]

-- ---------------------------------------------------------------------
-- Fórmulas válidas, satisfacibles e insatisfacibles                  --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 12: Definir la función
--    esValida :: Prop -> Bool
-- tal que (esValida f) se verifica si f es válida. Por ejemplo,
--    esValida (p --> p)                 ==>  True
--    esValida (p --> q)                 ==>  False
--    esValida ((p --> q) \/ (q --> p))  ==>  True
-- ---------------------------------------------------------------------

esValida :: Prop -> Bool
esValida f = 
    modelosFormula f == interpretacionesForm f

-- ---------------------------------------------------------------------
-- Ejercicio 13: Definir la función
--    esInsatisfacible :: Prop -> Bool
-- tal que (esInsatisfacible f) se verifica si f es insatisfacible. Por
-- ejemplo, 
--    esInsatisfacible (p /\ (no p))             ==>  True
--    esInsatisfacible ((p --> q) /\ (q --> r))  ==>  False
-- ---------------------------------------------------------------------

esInsatisfacible :: Prop -> Bool
esInsatisfacible f =
    modelosFormula f == []

-- ---------------------------------------------------------------------
-- Ejercicio 14: Definir la función
--    esSatisfacible :: Prop -> Bool
-- tal que (esSatisfacible f) se verifica si f es satisfacible. Por
-- ejemplo, 
--    esSatisfacible (p /\ (no p))             ==>  False
--    esSatisfacible ((p --> q) /\ (q --> r))  ==>  True
-- ---------------------------------------------------------------------

esSatisfacible :: Prop -> Bool
esSatisfacible f =
    modelosFormula f /= []

-- ---------------------------------------------------------------------
-- Símbolos proposicionales de un conjunto de fórmulas                --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 15: Definir la función
--    unionGeneral :: Eq a => [[a]] -> [a]
-- tal que (unionGeneral x) es la unión de los conjuntos de la lista de
-- conjuntos x. Por ejemplo,
--    unionGeneral []                 ==>  []
--    unionGeneral [[1]]              ==>  [1]
--    unionGeneral [[1],[1,2],[2,3]]  ==>  [1,2,3]
-- ---------------------------------------------------------------------

unionGeneral :: Eq a => [[a]] -> [a]
unionGeneral []     = []
unionGeneral (xs:xss) = xs `union` unionGeneral xss 

uniónG :: Eq a => [[a]] -> [a]
uniónG = foldl union []


-- ---------------------------------------------------------------------
-- Ejercicio 16: Definir la función
--    símbolosPropConj :: [Prop] -> [Prop]
-- tal que (símbolosPropConj s) es el conjunto de los símbolos
-- proposiciones de s. Por ejemplo,
--    símbolosPropConj [p /\ q --> r, p --> s]  ==>  [p,q,r,s]
-- ---------------------------------------------------------------------

símbolosPropConj :: [Prop] -> [Prop]
símbolosPropConj s
    = unionGeneral [simbolosPropForm f | f <- s]

símbolosPropConj2 :: [Prop] -> [Prop]
símbolosPropConj2 = uniónG . map simbolosPropForm

-- ---------------------------------------------------------------------
-- Interpretaciones de un conjunto de fórmulas                        --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 17: Definir la función
--    interpretacionesConjunto :: [Prop] -> [Interpretacion]
-- tal que (interpretacionesConjunto s) es la lista de las
-- interpretaciones de s. Por ejemplo,
--    interpretacionesConjunto [p --> q, q --> r]
--    ==> [[p,q,r],[p,q],[p,r],[p],[q,r],[q],[r],[]]
-- ---------------------------------------------------------------------

interpretacionesConjunto :: [Prop] -> [Interpretacion]
interpretacionesConjunto s =
    subconjuntos (símbolosPropConj s)

-- ---------------------------------------------------------------------
-- Modelos de conjuntos de fórmulas                                   --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 18: Definir la función
--    esModeloConjunto :: Interpretacion -> [Prop] -> Bool
-- tal que (esModeloConjunto i s) se verifica si i es modelo de s. Por
-- ejemplo, 
--    esModeloConjunto [p,r] [(p \/ q) /\ ((no q) \/ r), q --> r]
--    ==> True
--    esModeloConjunto [p,r] [(p \/ q) /\ ((no q) \/ r), r --> q]
--    ==> False
-- ---------------------------------------------------------------------

esModeloConjunto :: Interpretacion -> [Prop] -> Bool
esModeloConjunto i s =
    and [esModeloFormula i f | f <- s]

esModeloConjunto2 :: Interpretacion -> [Prop] -> Bool
esModeloConjunto2 i s = all (esModeloFormula i) s

-- --------------------g-------------------------------------------------
-- Ejercicio 19: Definir la función
--    modelosConjunto :: [Prop] -> [Interpretacion]
-- tal que (modelosConjunto s) es la lista de modelos del conjunto
-- s. Por ejemplo,
--    modelosConjunto [(p \/ q) /\ ((no q) \/ r), q --> r]
--    ==> [[p,q,r],[p,r],[p],[q,r]]
--    modelosConjunto [(p \/ q) /\ ((no q) \/ r), r --> q]
--    ==> [[p,q,r],[p],[q,r]]
-- ---------------------------------------------------------------------

modelosConjunto :: [Prop] -> [Interpretacion]
modelosConjunto s =
    [i | i <- interpretacionesConjunto s,
         esModeloConjunto i s]

-- ---------------------------------------------------------------------
-- Conjuntos consistentes e inconsistentes de fórmulas                --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 20: Definir la función
--    esConsistente :: [Prop] -> Bool
-- tal que (esConsistente s) se verifica si s es consistente. Por
-- ejemplo, 
--    esConsistente [(p \/ q) /\ ((no q) \/ r), p --> r]        
--    ==> True
--    esConsistente [(p \/ q) /\ ((no q) \/ r), p --> r, no r]  
--    ==> False
-- ---------------------------------------------------------------------

esConsistente :: [Prop] -> Bool
esConsistente s =
    modelosConjunto s /= []

-- ---------------------------------------------------------------------
-- Ejercicio 21: Definir la función
--    esInconsistente :: [Prop] -> Bool
-- tal que (esInconsistente s) se verifica si s es inconsistente. Por
-- ejemplo, 
--    esInconsistente [(p \/ q) /\ ((no q) \/ r), p --> r]        
--    ==> False
--    esInconsistente [(p \/ q) /\ ((no q) \/ r), p --> r, no r]  
--    ==> True
-- ---------------------------------------------------------------------

esInconsistente :: [Prop] -> Bool
esInconsistente s =
    modelosConjunto s == []

-- ---------------------------------------------------------------------
-- Consecuencia lógica                                                --
-- ---------------------------------------------------------------------

-- ---------------------------------------------------------------------
-- Ejercicio 22: Definir la función
--    esConsecuencia :: [Prop] -> Prop -> Bool
-- tal que (esConsecuencia s f) se verifica si f es consecuencia de
-- s. Por ejemplo,
--    esConsecuencia [p --> q, q --> r] (p --> r)  ==>  True
--    esConsecuencia [p] (p /\ q)                  ==>  False
-- ---------------------------------------------------------------------

esConsecuencia :: [Prop] -> Prop -> Bool
esConsecuencia s f =
    null [i | i <- interpretacionesConjunto (f:s),
              esModeloConjunto i s,
              not (esModeloFormula i f)]

esConsecuencia2 :: [Prop] -> Prop -> Bool
esConsecuencia2 s f =
    and [esModeloFormula i f | i <- interpretacionesConjunto (f:s),
                               esModeloConjunto i s]