Ich fand diese Übung über Gleichargumentation und Beweise in Haskell. Der folgende Code ist gegeben:Wie man diesen Haskell-Code unter Verwendung von Gleichargumentation beweisen kann
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]
Jetzt muss ich, dass exec(comp e) s = eval e : s
beweisen.
So fand ich diese Antwort so weit:
wir, dass exec (comp e) s = eval e : s
beweisen.
Erster Fall: Angenommen e = (Val n)
. Dann comp (Val n) = [PUSH n]
, so müssen wir beweisen, dass exec ([PUSH n]) s = eval ([PUSH n] : s)
. Wir finden das exec ([PUSH n]) s = exec [] (n:s) = (n:s)
mit der Funktionsdefinition von exec.
Jetzt eval (Val n) : s = n : s
. Der erste Fall ist OK!
Zweiter Fall: angenommen e = (Add x y)
. Dann comp (Add x y) = comp x ++ comp y ++ [ADD]
.
Aber jetzt kämpfe ich mit dieser rekursiven Verwendung von comp. Sollte ich eine Form von Bäumen und Induktion auf diesen Bäumen verwenden, um dies zu beweisen? Ich bin mir nicht ganz sicher, wie ich das machen soll.
Beachten Sie, dass Sie eine Zeile in 'exec _ [] = Fehler" ADD auf einen leeren oder Singleton-Stack " – epsilonhalbe
Vermutlich brauchen Sie ein Lemma über' exec' - insbesondere haben Sie 'exec (a + + b) s = exec b (exec as) '. Dies würde Ihnen erlauben, 'exec (comp x ++ comp y ++ [ADD])' als 'exec [ADD] zu schreiben (exec (comp y) (exec (comp x)))' – user2407038
Vielen Dank! Aber wie kann ich die comp x und comp y dann beweisen? –