この演習は、ハスケルでの等式推論と証明に当てはまりました。次のコードが与えられます:等式推論を使用してこのハスケルコードを証明する方法
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)
が見つかりました。最初のケースはOKです!
第2の場合:e = (Add x y)
とします。その後、comp (Add x y) = comp x ++ comp y ++ [ADD]
。
しかし、今私はcompのこの再帰的な使用に苦しんでいます。これを証明するために、私は何らかの形の木を使用してこれらの木を誘導するべきですか?私はそれをどうやって行うのか完全にはわからない。
空文字列またはシングルトンスタックに適用されたADDのうち、1行が欠落していることに注意してください。 – 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を証明できますか? –