Question: I'm working on a Haskell assignment and I can't get the following outputs right: ghci> rankP [LDB True, LDI 1, LDI 10, LDI 5, IFELSE
I'm working on a Haskell assignment and I can't get the following outputs right:
ghci> rankP [LDB True, LDI 1, LDI 10, LDI 5, IFELSE [ADD] [LDI 7], ADD ] 0
what I get: Just 3
Expected: Just 1
ghci> rankP [LDI 10, LDI 5, LDB True, IFELSE [LDB False, IFELSE [ADD, DUP] [MULT]] [LDI 7] ] 0
what I get: Just 3
Expected: Just 1
And Here is my code:
import Data.Maybe
type Prog = [Cmd] data Cmd = LDI Int | ADD | MULT | DUP | DEC | SWAP | POP Int | IFELSE Prog Prog | LDB Bool | LEQ deriving Show data Val = I Int | B Bool deriving Show
type Stack = [Val]
data Result = A Stack | RankError | TypeError deriving Show
type D = Stack -> Stack type Rank = Int type CmdRank = (Int, Int)
-- Define a function rankP that computes the rank of a program -- when ran with a stack of rank r. -- Maybe data type is used to capture rank error. rankP :: Prog -> Rank -> Maybe Rank rankP [] s' = Just s' rankP (c:cs) s | s < n = Nothing | otherwise = rankP cs (s - n + m) where (n,m) = rankC c
rankError :: Prog -> Int -> Bool rankError p srank = ((rankP p srank) == Nothing )
-- Define a function run for evaluating a program with a given stack run :: Prog -> Stack -> Result --run [] s = Just s -- base case run p s = if (rankError p (length s)) then RankError else if isNothing((sem p s)) then TypeError else A (fromJust(sem p s))
sem :: Prog -> Stack -> Maybe Stack sem [] s = Just s sem [][] = Nothing sem (c:cs) s = case semCmd c s of Just s' -> sem cs s' Nothing -> Nothing semCmd :: Cmd -> Stack -> Maybe Stack -- loads integer onto the stack semCmd (LDI c ) s = Just (I c:s)
-- loads boolean parameter onto the stack semCmd (LDB b ) s = Just (B b:s)
-- add integers onto the stack semCmd ADD (I x:I y:xs) = Just (I (x+y):xs)
semCmd DEC (I x : xs) = Just (I (x - 1) : xs)
-- multiplies integer semCmd MULT (I x:I y:xs) = Just (I (x*y):xs)
-- places a copy of the stack's topmost element on the stack semCmd DUP (x:xs) = Just (x:x:xs)
semCmd SWAP (x : y : xs) = Just (y : x : xs)
-- removes the top integer from the stack. -- If top is greater than the second top, then the true is pushed on the stack semCmd LEQ (I x: I y:xs) = Just (B (x<=y):xs)
-- removes the top of the stack and if the value is true, --then run the first program, else run the secound program. semCmd (POP k) s | k <= length s = Just (drop k s) | otherwise = Nothing --semCmd (IFELSE m n) ((B x): xs) = sem (if x then m else n) xs semCmd (IFELSE [] _ ) ((B True): s) = Just s semCmd (IFELSE p1 _ ) ((B True): s) = sem p1 s semCmd (IFELSE _ []) ((B False): s) = Just s semCmd (IFELSE _ p2) ((B False): s) = sem p2 s --semCmd (IFELSE p1 _) ((B False): s) = semCmd _ _ = Nothing
rankC::Cmd -> CmdRank rankC (LDI _) = (0,1) rankC (LDB _) = (0,1) rankC LEQ = (2,1) rankC ADD = (2,1) rankC MULT = (2,1) rankC DUP = (1,2) rankC DEC = (1,1) rankC SWAP = (2,2) rankC (POP k) = (k,0) rankC (IFELSE p q) = (0,0)
Condition to accomplish the IFELSE:
The rank of a stack is given by the number of its elements. The rank of a single stack operation is given by a pair of numbers (n, m) where n indicates the number of elements the operation takes off the top of the stack and m is the number of elements the operation puts onto the stack. The rank for a stack program is defined to be the rank of the stack that would be obtained if the program was run on an empty stack. The rank of a stack program p1 run with stack s1 is the rank of the stack s1 after the execution of program p1. A rank error occurs in a stack program when an operation with rank (n, m) is executed on a stack with rank k < n. For example: p2 = [ LDI 5, LDI 10, ADD] has rank 1 when run with the stack s1 = [] and rank 2 when run with s2 = [I 5].
I will upvote! thanks!
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
