하스켈에서 방정식 추론과 증명에 대해이 연습을 발견했습니다. 다음 코드는 주어진 :방정식 추론을 사용하여 하스켈 코드를 증명하는 법
type Stack = [Int]
type Code = [Op]
data Op = PUSH Int | ADD
deriving (Show)
--
-- Stack machine
--
exec :: Code -> Stack -> Stack
exec [ ] s = s
exec (PUSH n : c) s = exec c (n:s)
exec (ADD:c) (m:n:s) = exec c (n+m : s)
--
-- Interpeter
--
data Expr = Val Int | Add Expr Expr
deriving (Show)
eval :: Expr -> Int
eval (Val n) = n
eval (Add x y) = eval x+eval y
--
-- Compiler
--
comp :: Expr -> Code
comp (Val n) = [PUSH n]
comp (Add x y) = comp x ++ comp y ++ [ADD]
지금 내가 그 exec(comp e) s = eval e : s
을 증명해야합니다.
그래서 나는 지금까지 답을 발견
우리는 그 exec (comp e) s = eval e : s
을 증명해야합니다.
첫 번째 경우 : e = (Val n)
이라고 가정합니다. 그런 다음 comp (Val n) = [PUSH n]
이므로 exec ([PUSH n]) s = eval ([PUSH n] : s)
임을 증명해야합니다. exec의 함수 정의를 사용하여 exec ([PUSH n]) s = exec [] (n:s) = (n:s)
을 찾습니다.
지금 eval (Val n) : s = n : s
. 첫 번째 경우는 OK입니다!
두 번째 경우 : e = (Add x y)
이라고 가정합니다. 그 다음 comp (Add x y) = comp x ++ comp y ++ [ADD]
.
하지만 이제는 comp의 재귀 적 사용에 어려움을 겪고 있습니다. 내가 이것을 증명하기 위해 어떤 형태의 나무와 유도를 사용해야합니까? 나는 그것을하는 방법을 완전히 모르겠습니다. exec
에 첫 번째 인수가리스트 인 경우
빈 줄 또는 싱글 톤 스택에 적용된 추가 "exec _ [] = error"에 한 줄 빠진 점에 유의하십시오. – epsilonhalbe
아마도'exec'에 대한 보조 정리가 필요할 것입니다 - 특히 exec (a + + b) s = exec b (exec as)'. 이렇게하면'exec (comp x ++ comp y ++ [ADD])'를'exec [ADD] (exec (comp y) (exec (comp x)))'로 쓸 수 있습니다. – user2407038
감사합니다! 그렇다면 어떻게하면 comp x과 comp y를 증명할 수 있습니까? –