module Asignaciones where import ParseLib import Formula import List type VarAsignacion = Char data Valor = Verdadero | Falso | Indefinido deriving (Show, Eq) data Asignacion = LVariableProp LVar_prop | VariableAsignacion VarAsignacion | VariableCorregida VarAsignacion LVar_prop deriving Show data LVar_prop = Vacio | Nodo Valor Atomica LVar_prop deriving (Show, Eq) imprimirLVarprop :: LVar_prop -> String imprimirLVarprop lista = imprimirLVarprop' (ordenarLista (lVarprop2lista lista)) imprimirLVarprop' :: [(Valor,Atomica)] -> String imprimirLVarprop' [] = "" imprimirLVarprop' ((v,a):[]) = [a] ++ "=" ++ [(valor2v v)] imprimirLVarprop' ((v,a):xs) = [a] ++ "=" ++ [(valor2v v)] ++ ", " ++ (imprimirLVarprop' xs) lVarprop2lista :: LVar_prop -> [(Valor,Atomica)] lVarprop2lista Vacio = [] lVarprop2lista (Nodo v a sig) = (v,a):(lVarprop2lista sig) orden :: (Valor,Atomica) -> (Valor,Atomica) -> Ordering orden (_ , a1) (_ , a2) | a1 < a2 = LT | a1 == a2 = EQ | a1 > a2 = GT ordenarLista :: [(Valor,Atomica)] -> [(Valor,Atomica)] ordenarLista l = sortBy orden l valor2v :: Valor -> Char valor2v Verdadero = 'V' valor2v Falso = 'F' valor2str :: Valor -> String valor2str Verdadero = "Verdadero" valor2str Falso = "Falso" valor2str Indefinido = "Indefinido" obtenerValor :: LVar_prop -> Atomica -> Valor obtenerValor Vacio _ = Indefinido obtenerValor (Nodo valor atomica sig) at | atomica == at = valor | otherwise = obtenerValor sig at -- Asignacion es de tipo: VariableAsignacion obtenerVarAsign :: Asignacion -> VarAsignacion obtenerVarAsign (VariableAsignacion nombre) = nombre obtenerVarAsign (VariableCorregida nombre _) = nombre -- Asignacion es de tipo: LVariableProp o VariableCorregida obtenerVarProps :: Asignacion -> LVar_prop obtenerVarProps (LVariableProp lista) = lista obtenerVarProps (VariableCorregida _ lista) = lista esLVariableProp :: Asignacion -> Bool esLVariableProp (LVariableProp _) = True esLVariableProp _ = False esVariableAsignacion :: Asignacion -> Bool esVariableAsignacion (VariableAsignacion _) = True esVariableAsignacion _ = False esVariableCorregida :: Asignacion -> Bool esVariableCorregida (VariableCorregida _ _) = True esVariableCorregida _ = False {- Gramatica: asignacion := dos_listas_variables | variable_de_asignacion | variable_corregida dos_listas_variables := '{' lista_variables '|' lista_variables '}' lista_variables := Atomica | Atomica ',' lista_variables variable_de_asignacion := VarAsignacion variable_corregida := VarAsignacion '[' lista_variables_corregida ']' lista_variables_corregida := VarProp | VarProp ',' lista_variables_corregida VarProp := Atomica '=' Valor Valor := 'V' | 'F' -} corregirListaVariables :: LVar_prop -> LVar_prop -> LVar_prop corregirListaVariables lista Vacio = lista corregirListaVariables lista (Nodo v atomica sig) = corregirListaVariables (insertarListaVariables lista v atomica) sig insertarListaVariables :: LVar_prop -> Valor -> Atomica -> LVar_prop insertarListaVariables (Vacio) v nombre = Nodo v nombre Vacio insertarListaVariables (Nodo valor' nombre' sig) valor nombre | nombre == nombre' = Nodo valor nombre' sig | otherwise = Nodo valor' nombre' (insertarListaVariables sig valor nombre) -- def. de asignacion asignacion :: Parse Char Asignacion asignacion = (parse0Espacio >*> (dos_listas_variables `alt` variable_de_asignacion `alt` variable_corregida) >*> parse0Espacio )`build` mkAsign where mkAsign (_,(a,_)) = a -- Dos listas de variables dos_listas_variables :: Parse Char Asignacion dos_listas_variables = (token '{' >*> e >*> (lista_variables Verdadero) >*> e >*> token '|' >*> e >*> (lista_variables Falso) >*> e >*> token '}') `build` \(_,(_,(listaVerdadera,(_,(_,(_,(listaFalsa,(_,_)))))))) -> LVariableProp (mergeListavariables (filtrarRepetidos listaVerdadera) (filtrarRepetidos listaFalsa)) where e = parse0Espacio lista_variables :: Valor -> Parse Char LVar_prop lista_variables v = optional (parseVarProp >*> e >*> (parseVarPropAux v)) `build` mkParseVarPropOptional where mkParseVarPropOptional [] = Vacio mkParseVarPropOptional [(c,(_,lista))] = Nodo v c lista e = parse0Espacio parseVarPropAux :: Valor -> Parse Char LVar_prop parseVarPropAux v = list (e >*> token ',' >*> e >*> parseVarProp) `build` mkLVar where mkLVar [] = Vacio mkLVar ((_,(_,(_,c))):[]) = Nodo v c Vacio mkLVar ((_,(_,(_,c))):xs) = Nodo v c (mkLVar xs) e = parse0Espacio filtrarRepetidos :: LVar_prop -> LVar_prop filtrarRepetidos Vacio = Vacio filtrarRepetidos (Nodo valor atomica sig) | existeLVarProp atomica sig = filtrarRepetidos sig | otherwise = Nodo valor atomica (filtrarRepetidos sig) mergeListavariables :: LVar_prop -> LVar_prop -> LVar_prop mergeListavariables lista1 (Vacio) = lista1 mergeListavariables lista1 (Nodo valor nombre sigNodo) | existeLVarProp nombre lista1 = recursion | otherwise = Nodo valor nombre recursion where recursion = mergeListavariables lista1 sigNodo existeLVarProp :: VarAsignacion -> LVar_prop -> Bool existeLVarProp c Vacio = False existeLVarProp c (Nodo _ nombre sig) | nombre == c = True | otherwise = existeLVarProp c sig -- Variable de Asignacion variable_de_asignacion :: Parse Char Asignacion variable_de_asignacion = parseVariableAsignacion `build` \c -> VariableAsignacion c parseVariableAsignacion :: Parse Char Char parseVariableAsignacion = spot (\c -> c >= 'A' && c <= 'Z') -- Variable Corregida variable_corregida :: Parse Char Asignacion variable_corregida = (parseVariableAsignacion >*> e >*> token '[' >*> e >*> lista_variables_corregida >*> e >*> token ']') `build` \(varAsign,(_,(_,(_,(listaVar,(_,_)))))) -> VariableCorregida varAsign listaVar where e = parse0Espacio lista_variables_corregida :: Parse Char LVar_prop lista_variables_corregida = optional (parseAsignacionVarProp >*> e >*> parseAux) `build` mkListaVariableCorregida where mkListaVariableCorregida [] = Vacio mkListaVariableCorregida [((Nodo v n _),(_,lista))] = Nodo v n lista e = parse0Espacio parseAux :: Parse Char LVar_prop parseAux = list (e >*> token ',' >*> e >*> parseAsignacionVarProp) `build` mkLista where mkLista [] = Vacio mkLista ((_,(_,(_,(Nodo valor atomica _)))):xs) = Nodo valor atomica (mkLista xs) e = parse0Espacio parseAsignacionVarProp :: Parse Char LVar_prop parseAsignacionVarProp = (parseVarProp >*> e >*> token '=' >*> e >*> parseValor) `build` \(var,(_,(_,(_,valor)))) -> Nodo valor var Vacio where e = parse0Espacio parseValor :: Parse Char Valor parseValor = parseValorVerdadero `alt` parseValorFalso where parseValorVerdadero = token 'V' `build` \_ -> Verdadero parseValorFalso = token 'F' `build` \_ -> Falso parseVarProp :: Parse Char Char parseVarProp = spot (\c -> c >= 'a' && c <= 'z') ------------------ -- el parser tiene exito si se consume todo el string parseAsignacion :: String -> Maybe Asignacion parseAsignacion cs = devuelvoAsignacion (asignacion cs) devuelvoAsignacion :: [(Asignacion,String)] -> Maybe Asignacion devuelvoAsignacion (x:xs) | length (snd x) == 0 = Just (fst x) | otherwise = devuelvoAsignacion xs devuelvoAsignacion [] = Nothing