haskell中的OR和PAR语句用于WHILE语言

时间:2016-03-23 14:52:26

标签: haskell random while-loop

我正在尝试用Haskell编写来自我的编程理论主题的WHILE语言。 一开始就一直在递归地定义所有内容,因此代码正在流动。然后我们达到了语句,并且派生树出现了,即使我仍然可以将其转换为递归定义。直到我们进入OR和PAR语句。

OR语句的两个大步骤公理:(S1或S2)

  • 如果< S1,s> - > s'然后< S1或S2,s> - > s'的
  • 如果< S2,s> - > s'然后< S1或S2,s> - > s'的

OR语句的两个小步骤公理:
  - < S1或S2,s> => < S1,s>   - < S1或S2,s> => < S2,s>

其中S1和S2是语句和s,s'是函数Var - > INT

显然,实现此行为的一种好方法是随机化运行S1或S2时执行S1或S2中的哪一个。 幸运的是,我几个月前开始我的monad研究,已经达到了System.Random模块和State monad(monad变形金刚对我来说仍然不为人知),所以我可以想象一些方法(我不喜欢)

  • 从S1和S2获取一些“随机”种子,类似于(长度。显示),并将其传递给System.Random。但我知道,当S1和S2都修复时,这样做会导致从S1或S2中选择相同的语句。
  • 为OR和PAR语句定义新数据(类似于SpecialSTM),因此我可以更改我的函数类型(主要是semanticaSTM)以添加一些IO和真正的随机性。

那么,是否有一个解决方案允许我像​​现在一样保留类型,但在OR和PAR语句中得到一些合理的行为?

这是我的所有代码:

module WhileV4
  (
  -- La sintaxis:
    Bin(Cero, Uno) 
  , Entero(N1,N2)
  , AritVar(Avar)
  , BoolVar(Bvar)
  , Aexpr(A1,A2,Sum,Mult,Rest)
  , Bexpr(Verdadero,Falso,Iguales,Distintos,MayorOigual,MenorOigual,Mayor,Menor,NO,Y,O,Entonces,Sii)
  , Stm(AssA,AssB,Skip,Comp,Si,Mientras,Repetir)

  -- La semantica:
  , semanticaN
  , semanticaA
  , semanticaB
  , freeAV
  , freeAV'
  , freeBV
  , subsA
  , subsA'
  , subsB
  , newStateA
  , newStateB
  , semanticaSTM

  -- Otros:
  , mkEnt  -- para crear Enteros a partir de cadenas de 0s y 1s
  , (.:)   -- sinonimo infijo de Comp (otra opcion, usar la clase Monoid --> TO DO)
  , (>+)
  , (>*)
  , (>-)
  , (=:)   -- asignacion para variables aritmeticas, sinonimo infijo
  , (==:)  -- asignacion para variables booleanas, sinonimo infijo
  , (=.=)
  , (=/=)
  , (<.=)
  , (>.=)
  , factorial
  , euclides

  ) where

import Data.Char (digitToInt)
import qualified Data.Set as S

import Control.Applicative
import Data.Maybe



----------------------------------------------------------
-- TEMA 1
----------------------------------------------------------

-- Comparando con lo visto en clase:
--   Num ~ Entero , Var ~ AritVar , Aexp ~ Aexpr , Bexp ~ Bexpr , Stm ~ Stm
--     Los constructores de cada expresion tienen distinta notacion para evitar interferencias con Haskell.
--     Faltan las BoolVar (se dejan como ejercicio en clase).
--   N ~ semanticaN , State ~ Astate , A ~ semanticaA
--     Definiciones de "definicion composicional" e "induccion estructural".
--     Observacion sobre la semantica de (-a)
--     Ej 1.8: Demostrar que las ecuaciones para A definen una funcion total.
--     Visto en clase: N es funcion total
--   B ~ semanticaB
--     Ej 1.10: Demostrar que las ecuaciones para B definen una funcion total.
--     Ej 1.11: (a) Se extiende Bexp a Bexp'; extender la funcion semantica B (ya implementado)
--              (b) Demostrar que para cada b' en Bexp' existe b en Bexp tal que b' y b son equivalentes.
--   FV ~ freeAV
--     Lema 1: Sean s,s' en State tales que para todo x en FV(a), s x == s' x  =>  A[[a]]s == A[[a]]s'
--     Ej 1.13: Definir el conjunto de variables libres para una expresion booleana y demostrar un resultado similar al Lema 1.
--     ERROR: freeBV no es lo que pide el ejercicio 13 (pide freeAV')
--   substitucion ~ subsA  ,  actualizar estado ~ newStateA
--     Ej 1.14: Demostrar que A[[ a[y->a0] ]]s = A[[a]](s[y->A[[a0]]s]) para cualquier estado s.
--     Ej 1.15: Definir la substitucion de expresiones booleanas b[y->a0] y demostrar un resultado similar al del ejercicio anterior.



data Bin = Cero | Uno
  deriving Show

-- Para hacerlo como en clase: 
-- data Entero = N1 Bin | N2 Entero Bin
-- pero podria hacerlo con listas que total tambien son recursivas
-- newtype Entero = N [Bin]
-- pero me toca las narices la lista vacia asi que voy a hacerlo como en clase

data Entero = N1 Bin | N2 Entero Bin
  deriving Show



semanticaN :: Entero -> Int
semanticaN (N1 Cero)   = 0
semanticaN (N1 Uno)    = 1
semanticaN (N2 n Cero) = 2 * semanticaN n
semanticaN (N2 n Uno)  = (2 * semanticaN n) + 1



data AritVar = Avar String
  deriving (Eq, Ord, Show)

data BoolVar = Bvar String 
  deriving (Eq, Ord, Show)
-- el Ord lo necesito para hacer uniones de (Set AritVar) y (Set BoolVar)


data Aexpr = A1 Entero | A2 AritVar | Sum Aexpr Aexpr     | Mult Aexpr Aexpr      | Rest Aexpr Aexpr

data Bexpr = Verdadero | Falso      | Iguales Aexpr Aexpr | Distintos Aexpr Aexpr | MayorOigual Aexpr Aexpr | MenorOigual Aexpr Aexpr | Mayor Aexpr Aexpr  | Menor Aexpr Aexpr
                       | NO Bexpr   | Y Bexpr Bexpr       | O Bexpr Bexpr         | Entonces Bexpr Bexpr    | Sii Bexpr Bexpr         | B BoolVar         -- Bvar String

data Stm   = AssA AritVar Aexpr     | AssB BoolVar Bexpr  | Skip                  | Comp Stm Stm            | Si Bexpr Stm Stm        | Mientras Bexpr Stm | Repetir Stm Bexpr  
                                    | Abortar             | Asegurar Bexpr Stm    | Or Stm Stm              | Par Stm Stm 
                                    | Iniciar Dec 



semanticaA :: Aexpr -> (AritVar -> Int) -> Int
semanticaA (A1 ent) s     = semanticaN ent
semanticaA (A2 var) s     = s var
semanticaA (Sum a1 a2)  s = (semanticaA a1 s) + (semanticaA a2 s)
semanticaA (Mult a1 a2) s = (semanticaA a1 s) * (semanticaA a2 s)
semanticaA (Rest a1 a2) s = (semanticaA a1 s) - (semanticaA a2 s)



semanticaB :: Bexpr -> (AritVar -> Int) -> (BoolVar -> Bool) -> Bool
semanticaB Verdadero _ _ = True
semanticaB Falso     _ _ = False
semanticaB (Iguales a1 a2)     s _ =  (semanticaA a1 s) == semanticaA a2 s
semanticaB (Distintos a1 a2)   s _ =  (semanticaA a1 s) /= semanticaA a2 s
semanticaB (MayorOigual a1 a2) s _ =  (semanticaA a1 s) >= semanticaA a2 s
semanticaB (MenorOigual a1 a2) s _ =  (semanticaA a1 s) <= semanticaA a2 s
semanticaB (Mayor a1 a2)       s _ =  (semanticaA a1 s) > semanticaA a2 s
semanticaB (Menor a1 a2)       s _ =  (semanticaA a1 s) < semanticaA a2 s
semanticaB (B boolvar)       s1 s2 =  s2 boolvar
semanticaB (NO bexpr)        s1 s2 =  not (semanticaB bexpr s1 s2)
semanticaB (Y b1 b2)         s1 s2 =  (semanticaB b1 s1 s2) && (semanticaB b2 s1 s2)
semanticaB (O b1 b2)         s1 s2 =  (semanticaB b1 s1 s2) || (semanticaB b2 s1 s2)
semanticaB (Entonces b1 b2)  s1 s2 =  semanticaB (NO (b1 `Y` (NO b2))) s1 s2
semanticaB (Sii b1 b2)       s1 s2 =  (semanticaB b1 s1 s2) == (semanticaB b2 s1 s2)



freeAV :: Aexpr -> S.Set AritVar
freeAV (A1 _)       = S.empty
freeAV (A2 avar)    = S.singleton avar
freeAV (Sum a1 a2)  = (freeAV a1) `S.union` (freeAV a2)
freeAV (Mult a1 a2) = (freeAV a1) `S.union` (freeAV a2)
freeAV (Rest a1 a2) = (freeAV a1) `S.union` (freeAV a2)


freeAV' :: Bexpr -> S.Set AritVar
freeAV' Verdadero = S.empty
freeAV' Falso     = S.empty
freeAV' (Iguales a1 a2)     = (freeAV a1) `S.union` (freeAV a2)
freeAV' (Distintos a1 a2)   = (freeAV a1) `S.union` (freeAV a2)
freeAV' (MayorOigual a1 a2) = (freeAV a1) `S.union` (freeAV a2)
freeAV' (MenorOigual a1 a2) = (freeAV a1) `S.union` (freeAV a2)
freeAV' (Mayor a1 a2)       = (freeAV a1) `S.union` (freeAV a2)
freeAV' (Menor a1 a2)       = (freeAV a1) `S.union` (freeAV a2)
freeAV' (B boolvar)         = S.empty
freeAV' (NO bexpr)          = freeAV' bexpr
freeAV' (Y b1 b2)           = (freeAV' b1) `S.union` (freeAV' b2)
freeAV' (O b1 b2)           = (freeAV' b1) `S.union` (freeAV' b2)
freeAV' (Entonces b1 b2)    = (freeAV' b1) `S.union` (freeAV' b2)
freeAV' (Sii b1 b2)         = (freeAV' b1) `S.union` (freeAV' b2)


freeBV :: Bexpr -> S.Set BoolVar
freeBV Verdadero = S.empty
freeBV Falso     = S.empty
freeBV (Iguales a1 a2)     = S.empty
freeBV (Distintos a1 a2)   = S.empty
freeBV (MayorOigual a1 a2) = S.empty
freeBV (MenorOigual a1 a2) = S.empty
freeBV (Mayor a1 a2)       = S.empty
freeBV (Menor a1 a2)       = S.empty
freeBV (B boolvar)         = S.singleton boolvar
freeBV (NO bexpr)          = freeBV bexpr
freeBV (Y b1 b2)           = (freeBV b1) `S.union` (freeBV b2)
freeBV (O b1 b2)           = (freeBV b1) `S.union` (freeBV b2)
freeBV (Entonces b1 b2)    = (freeBV b1) `S.union` (freeBV b2)
freeBV (Sii b1 b2)         = (freeBV b1) `S.union` (freeBV b2)



subsA :: Aexpr -> AritVar -> Aexpr -> Aexpr
subsA (A1 ent) _ _     = (A1 ent)
subsA (A2 avar) v a    = if avar == v then a else (A2 avar)
subsA (Sum a1 a2)  v a = Sum (subsA a1 v a) (subsA a2 v a)
subsA (Mult a1 a2) v a = Mult (subsA a1 v a) (subsA a2 v a)
subsA (Rest a1 a2) v a = Rest (subsA a1 v a) (subsA a2 v a)


subsA' :: Bexpr -> AritVar -> Aexpr -> Bexpr
subsA' Verdadero _ _ = Verdadero
subsA' Falso     _ _ = Falso
subsA' (Iguales a1 a2)     v a = Iguales (subsA a1 v a) (subsA a2 v a)
subsA' (Distintos a1 a2)   v a = Distintos (subsA a1 v a) (subsA a2 v a)
subsA' (MayorOigual a1 a2) v a = MayorOigual (subsA a1 v a) (subsA a2 v a)
subsA' (MenorOigual a1 a2) v a = MenorOigual (subsA a1 v a) (subsA a2 v a)
subsA' (Mayor a1 a2)       v a = Mayor (subsA a1 v a) (subsA a2 v a)
subsA' (Menor a1 a2)       v a = Menor (subsA a1 v a) (subsA a2 v a)
subsA' (B boolvar)      v a = (B boolvar)
subsA' (NO bexpr)       v a = NO (subsA' bexpr v a)
subsA' (Y b1 b2)        v a = (subsA' b1 v a) `Y` (subsA' b2 v a)
subsA' (O b1 b2)        v a = (subsA' b1 v a) `O` (subsA' b2 v a)
subsA' (Entonces b1 b2) v a = (subsA' b1 v a) `Entonces` (subsA' b2 v a)
subsA' (Sii b1 b2)      v a = (subsA' b1 v a) `Sii` (subsA' b2 v a)


subsB :: Bexpr -> BoolVar -> Bexpr -> Bexpr
subsB Verdadero _ _ = Verdadero
subsB Falso     _ _ = Falso
subsB b@(Iguales a1 a2)     _ _ = b
subsB b@(Distintos a1 a2)   _ _ = b
subsB b@(MayorOigual a1 a2) _ _ = b
subsB b@(MenorOigual a1 a2) _ _ = b
subsB b@(Mayor a1 a2)       _ _ = b
subsB b@(Menor a1 a2)       _ _ = b
subsB (B boolvar)      v b = if boolvar == v then b else (B boolvar)
subsB (NO bexpr)       v b = NO (subsB bexpr v b)
subsB (Y b1 b2)        v b = (subsB b1 v b) `Y` (subsB b2 v b)
subsB (O b1 b2)        v b = (subsB b1 v b) `O` (subsB b2 v b)
subsB (Entonces b1 b2) v b = (subsB b1 v b) `Entonces` (subsB b2 v b)
subsB (Sii b1 b2)      v b = (subsB b1 v b) `Sii` (subsB b2 v b)


newStateA :: (AritVar -> Int) -> AritVar -> Int -> (AritVar -> Int)
newStateA s y n x = if x == y then n else (s x)


newStateB :: (BoolVar -> Bool) -> BoolVar -> Bool -> (BoolVar -> Bool)
newStateB s y b x = if x == y then b else (s x)



----------------------------------------------------------
-- TEMA 2
----------------------------------------------------------

-- Comparando con lo visto en clase:
--   configuracion ~ Config  ,  transicion ~ Transicion
--   Defs: La ejecucion de una sentencia S en un estado s:   (¬ terminar = ciclar)
--     termina sii existe un estado s' tal que <S,s> -> s'
--     cicla sii no existe ningun estado s' tal que <S,s> -> s'
--   Ej 2.4: Determinar si las sentencias terminan / ciclan (o no) siempre:
--     while ¬(x=1) do (y := y*x ; x := x-1)
--     while 1<=x do (y := y*x ; x := x-1)
--     while true do skip
--   Def: S1 equivale semanticamente a S2 sii para todo s en State, <S1,s> -> s' si y solo si <S2,s> -> s'
--   Lema 2: {while b do S} es semánticamente equivalente a {if b then (S; while b do S) else skip}
--   Ej 2.6:
--     Demostrar que (S1;S2);S3 y S1;(S2;S3) son semanticamente equivalentes
--     Demostrar que en general S1;S2 no es semanticamente equivalente a S2;S1
--   Ej 2.7: Extender el lenguaje While con la sentencia  repeat S until b
--     Demostrar que {repeat S until b} es semanticamente equivalente a {S; if b then skip else (repeat S until b)} 



type Astate = AritVar -> Int

type Bstate = BoolVar -> Bool

type Config  =  (Stm,Astate,Bstate)

type Transicion = Config -> (Astate,Bstate)


semanticaSTM :: Transicion 
semanticaSTM (AssA x a, s1, s2) = let n = semanticaA a s1 in (newStateA s1 x n , s2)
semanticaSTM (AssB x b, s1, s2) = let n = semanticaB b s1 s2 in (s1 ,newStateB s2 x n)
semanticaSTM (Skip, s1, s2)           = (s1,s2)
semanticaSTM (Comp stm1 stm2, s1, s2) = let (s1' , s2') = semanticaSTM (stm1,s1,s2) in semanticaSTM (stm2,s1',s2')
semanticaSTM (Si b stm1 stm2, s1, s2) = if semanticaB b s1 s2 then semanticaSTM (stm1,s1,s2) else semanticaSTM (stm2,s1,s2)
semanticaSTM (Mientras b stm, s1, s2) = if semanticaB b s1 s2 then aux else (s1,s2)
  where aux =  let (s1' , s2') = semanticaSTM (stm,s1,s2) in semanticaSTM (Mientras b stm, s1', s2')
semanticaSTM (Repetir stm b,  s1, s2) = if semanticaB b s1 s2 then semanticaSTM (stm,s1,s2) else aux
  where aux = let (s1' , s2') = semanticaSTM (stm,s1,s2) in semanticaSTM (Repetir stm b , s1', s2')
semanticaSTM (Abortar ,       s1, s2) = error "La ejecucion del programa ha sido interrumpida por Abortar"
semanticaSTM (Asegurar b stm, s1, s2) = if (semanticaB b s1 s2) then semanticaSTM (stm,s1,s2) else error ("La ejecucion del programa ha sido interrumpida porque no se puede asegurar la condicion " ++ show b)
-- semanticaSTM (Or stm1 stm2 , s1, s2) = ???
-- semanticaSTM (Par stm1 stm2, s1, s2) = ???





----------------------------------------------------------
-- TEMA 3
----------------------------------------------------------


data Dec = DvA (String,Aexpr) Dec | DvB (String,Bexpr) Dec | NoMasVariables




----------------------------------------------------------
-- COSAS EXTRA
----------------------------------------------------------

-- Sinonimos infijos:

(.:) :: Stm -> Stm -> Stm
stm1 .: stm2 = Comp stm1 stm2

(>+) :: Aexpr -> Aexpr -> Aexpr
a1 >+ a2 = Sum a1 a2

(>*) :: Aexpr -> Aexpr -> Aexpr
a1 >* a2 = Mult a1 a2

(>-) :: Aexpr -> Aexpr -> Aexpr
a1 >- a2 = Rest a1 a2

(=:) :: AritVar -> Aexpr -> Stm
avar =: a  = avar `AssA` a

(==:) :: BoolVar -> Bexpr -> Stm
bvar ==: b = bvar `AssB` b


(=.=) :: Aexpr -> Aexpr -> Bexpr
a1 =.= a2  =  Iguales a1 a2

(=/=) :: Aexpr -> Aexpr -> Bexpr
a1 =/= a2  =  Distintos a1 a2

(<.=) :: Aexpr -> Aexpr -> Bexpr
a1 <.= a2  =  MenorOigual a1 a2

(>.=) :: Aexpr -> Aexpr -> Bexpr
a1 >.= a2  =  MayorOigual a1 a2


crearEntero :: [Int] -> Entero
crearEntero []     = error "No se puede crear un Entero con la lista vacia"
crearEntero (n:ns) = foldl f aux ns
  where
    f ent 0 = N2 ent Cero
    f ent 1 = N2 ent Uno
    aux     = if (n == 0) then (N1 Cero) else (N1 Uno)


mkEnt :: String -> Entero
mkEnt = crearEntero . map digitToInt


{- PRUEBAS EN PANTALLA
*While> mkEnt "100"
N2 (N2 (N1 Uno) Cero) Cero
*While> semanticaN (mkEnt "100")
4
*While> semanticaN (mkEnt "112")
*** Exception: While.hs:(41,5)-(42,24): Non-exhaustive patterns in function f
-}


a1 = Sum (A2 (Avar "x")) (A1 (N1 Uno))
x = Avar "x"
y = Avar "y"
z = Avar "z"
m = Avar "m"
n = Avar "n"
n0 = (N1 Cero)
n1 = (N1 Uno)
n2 = mkEnt "10"
n3 = mkEnt "11"
n4 = mkEnt "100"
n5 = mkEnt "101"
n6 = mkEnt "110"
n7 = mkEnt "111"
n8 = mkEnt "1000"
n9 = mkEnt "1001"
n10 = mkEnt "1010"
n11 = mkEnt "1011"
a2 = Rest (Sum (A2 x) (A2 y)) (Mult (A2 z) (A1 n5))
m' = A2 m
n' = A2 n



factorial :: Stm
factorial = (y =: (A1 n1)) .: (Mientras (NO (Iguales (A2 x) (A1 n1))) ((y=:(Mult (A2 y) (A2 x))) .: (x=:(Rest (A2 x) (A1 n1)))))


stateA1 :: Astate
stateA1 (Avar "_") = 5

stateB1 :: Bstate
stateB1 _ = True


euclides :: Stm
euclides = Mientras (NO (m' =.= n')) (Si (m' <.= n') (n =: (n' >- m')) (m =: (m' >- n'))) 

stA1 :: Astate
stA1 (Avar x) = if x=="n" then 20 else (if x=="m" then 8 else 0)


probandoShow :: Stm
probandoShow = Si Verdadero euclides factorial


{- pruebas en pantalla:
*While> :t   fst $ semanticaSTM (factorial, stateA1, stateB1) 
fst $ semanticaSTM (factorial, stateA1, stateB1) :: Astate
*While> let aux = fst $ semanticaSTM (factorial, stateA1, stateB1) in map aux [x,y]
[1,120]
(0.03 secs, 7942288 bytes)
*While> let aux = fst $ semanticaSTM (factorial, const 16, stateB1) in map aux [x,y]
[1,20922789888000]
(0.02 secs, 0 bytes)
*While> product [1..16]
20922789888000
(0.00 secs, 0 bytes)
*While> let aux = fst $ semanticaSTM (factorial, const 20, stateB1) in map aux [x,y]
[1,2432902008176640000]
(0.02 secs, 0 bytes)
*While> let aux = fst $ semanticaSTM (factorial, const 21, stateB1) in map aux [x,y]
[1,-4249290049419214848]
(0.00 secs, 0 bytes)

*WhileV3>  let aux = fst $ semanticaSTM (euclides, stA1, stateB1) in map aux [n,m]
[4,4]
-}





-- instance Eq Entero where
--   n1 == n2 = (semanticaN n1) == (semanticaN n2)

-- instance Ord Entero where
--   compare n1 n2 = compare (semanticaN n1) (semanticaN n2)


instance Show Aexpr where
  show (A1 n)        = (show . semanticaN) n
  show (A2 (Avar x)) = x
  show (Sum a1 a2)   = '(' : (show a1) ++ " + " ++ (show a2) ++ ")"
  show (Mult a1 a2)  = '(' : (show a1) ++ " * " ++ (show a2) ++ ")"
  show (Rest a1 a2)  = '(' : (show a1) ++ " - " ++ (show a2) ++ ")"


instance Show Bexpr where
  show Verdadero = "Verdadero"
  show Falso     = "Falso"
  show (Iguales a1 a2)     = '(' : (show a1) ++ " = " ++ (show a2) ++ ")"
  show (Distintos a1 a2)   = '(' : (show a1) ++ " /= " ++ (show a2) ++ ")"
  show (MayorOigual a1 a2) = '(' : (show a1) ++ " >= " ++ (show a2) ++ ")"
  show (MenorOigual a1 a2) = '(' : (show a1) ++ " <= " ++ (show a2) ++ ")"
  show (Mayor a1 a2)       = '(' : (show a1) ++ " > " ++ (show a2) ++ ")"
  show (Menor a1 a2)       = '(' : (show a1) ++ " < " ++ (show a2) ++ ")"
  show (B (Bvar x))        = x
  show (NO bexpr)          = '(' : 'N' : 'o' : ' ' : (show bexpr) ++ ")"
  show (Y b1 b2)           = '(' : (show b1) ++ " Y " ++ (show b2) ++ ")"
  show (O b1 b2)           = '(' : (show b1) ++ " O " ++ (show b2) ++ ")"
  show (Entonces b1 b2)    = '(' : (show b1) ++ " => " ++ (show b2) ++ ")"
  show (Sii b1 b2)         = '(' : (show b1) ++ " <=> " ++ (show b2) ++ ")"


instance Show Stm where
  show s = "\n" ++ showStm s 0 ++ "\n"


showStm :: Stm -> Int -> String
showStm s n =  let esp k = take k (repeat ' ') in
  case s of
    (AssA (Avar x) a) -> (esp n) ++ "(" ++ x ++ " := " ++ (show a) ++ ")"
    (AssB (Bvar y) b) -> (esp n) ++ "(" ++ y ++ " :== " ++ (show b) ++ ")"
    Skip              -> (esp n) ++ "No hacer nada"
    (Comp s1 s2)      -> (showStm s1 n) ++ "; \n" ++ (showStm s2 n)
    (Si b s1 s2)      -> (esp n) ++ "Si " ++ (show b) ++ "\n" ++ (esp $ n+2) ++ "entonces \n" ++ (showStm s1 (n+4)) ++ "\n" ++ (esp $ n+2) ++ "en otro caso \n" ++ (showStm s2 (n+4))
    (Mientras b s)    -> (esp n) ++ "Mientras se cumpla " ++ (show b) ++ " hacer \n" ++ (showStm s (n+4))
    (Repetir s b)     -> (esp n) ++ "Repetir " ++ "\n" ++ (showStm s (n+4)) ++ "\n" ++ (esp $ n+2) ++ "hasta que " ++ (show b)

0 个答案:

没有答案