lsystem-1.2: src/SistemaL.ag
PRAGMA genlinepragmas
imports{
import Data.List
}
DATA SistemaL
| SistemaL nombre : String
alfabeto : Alfabeto
inicio : Inicio
producciones : Producciones
DATA Simbolo
| Simbolo String
TYPE Alfabeto = [Simbolo]
TYPE Inicio = [Simbolo]
TYPE Producciones = [Produccion]
TYPE Produccion = (Simbolo, Succesor)
TYPE Succesor = [Simbolo]
DERIVING *: Show
DERIVING Simbolo: Eq
-- construimos el alfabeto de un sistema l
ATTR Alfabeto [|alf: {[String]}|]
SEM SistemaL
| SistemaL alfabeto.alf = []
SEM Alfabeto
| Cons loc.verificar = elem @hd.simb @lhs.alf
tl.alf = if @loc.verificar
then @lhs.alf
else @hd.simb : @lhs.alf
lhs.alf = @tl.alf
| Nil lhs.alf = @lhs.alf
-- compartimos el alfabeto a la estructura
ATTR Inicio Producciones Produccion Succesor [alfabeto: {[String]} ||]
SEM SistemaL
| SistemaL inicio.alfabeto = @alfabeto.alf
producciones.alfabeto = @alfabeto.alf
-- subimos el simbolo
ATTR Produccion Simbolo [|| simb: String ]
SEM Simbolo
| Simbolo lhs.simb = @string
-- construyendo el resultado
ATTR SistemaL [|| resultado: {Either [String] SistemaL}]
SEM SistemaL
| SistemaL lhs.resultado = if null @loc.errores
then let producciones = addIdentProds @producciones.prods @alfabeto.alf
in Right (SistemaL @nombre @alfabeto.self @inicio.self producciones)
else Left @loc.errores
ATTR Alfabeto Inicio Produccion Succesor Simbolo [|| self: SELF]
ATTR Producciones [|prods: {Producciones}|]
SEM Producciones
| Cons loc.verificar = myElem @hd.simb @lhs.prods
tl.prods = if @loc.verificar
then @lhs.prods
else @hd.self : @lhs.prods
lhs.prods = @tl.prods
SEM SistemaL
| SistemaL producciones.prods = []
{
addIdentProds prods alfa
= let prods' = map (\(Simbolo e,_) -> e) prods
resto = alfa \\ prods'
iprods = map (\e -> (Simbolo e, [Simbolo e])) resto
in prods ++ iprods
myElem _ [] = False
myElem e1 ((Simbolo e2,_):xs) = if e1 == e2
then True
else myElem e1 xs
}
-- Errores
ATTR Alfabeto Inicio Producciones Produccion Succesor [|| errores: {[String]}]
SEM SistemaL
| SistemaL loc.errores
= let inicioErr = if null @inicio.self
then "La lista de simbolos de inicio no puede ser vacia" : @inicio.errores
else @inicio.errores
errores = map (\err -> @nombre ++ ": " ++ err) (@alfabeto.errores ++ inicioErr ++ @producciones.errores)
in errores
SEM Alfabeto
| Cons lhs.errores = if @loc.verificar
then ("El simbolo: '" ++ @hd.simb ++ "' esta repetido mas de una ves en el alfabeto.") : @tl.errores
else @tl.errores
| Nil lhs.errores = []
SEM Inicio
| Cons lhs.errores = if elem @hd.simb @lhs.alfabeto
then @tl.errores
else ("El simbolo de inicio: '" ++ @hd.simb ++ "' no se encuentra en el alfabeto.") : @tl.errores
| Nil lhs.errores = []
SEM Producciones
| Cons lhs.errores = if @loc.verificar
then let error = "La produccion con el simb. izq.:'"
++ @hd.simb
++ "' esta repetida mas de una ves en la lista de producciones."
in (error : @hd.errores) ++ @tl.errores
else @hd.errores ++ @tl.errores
| Nil lhs.errores = []
SEM Produccion
| Tuple lhs.errores = if elem @x1.simb @lhs.alfabeto
then @x2.errores
else ("El simbolo de la produccion (izq): '" ++ @x1.simb ++ "' no se encuentra en el alfabeto.") : @x2.errores
SEM Succesor
| Cons lhs.errores = if elem @hd.simb @lhs.alfabeto
then @tl.errores
else ("El simbolo de la produccion (der): '" ++ @hd.simb ++ "' no se encuentra en el alfabeto.") : @tl.errores
| Nil lhs.errores = []
{
ejemplo1 = SistemaL "Koch" alfaK initK prodK
alfaK = [Simbolo "F", Simbolo "f", Simbolo "+", Simbolo "-"]
initK = [Simbolo "F", Simbolo "a"]
prodK = [ (Simbolo "F", [Simbolo "F", Simbolo "g"])
, (Simbolo "F", [])
]
ejemplo2 = SistemaL "Koch" alfaK2 initK2 prodK2
alfaK2 = [Simbolo "F", Simbolo "f", Simbolo "+", Simbolo "-"]
initK2 = [Simbolo "F", Simbolo "f"]
prodK2 = [ (Simbolo "F", [Simbolo "F", Simbolo "+"])
, (Simbolo "f", [])
]
getNombre (SistemaL nm _ _ _) = nm
testSistemaL :: SistemaL -> Either [String] SistemaL
testSistemaL = sem_SistemaL
}