[英]How to prove this Haskell code using equational reasoning
I found this exercise on equational reasoning and proofs in Haskell. 我在Haskell中找到了有关方程式推理和证明的练习。 The following code is given: 给出以下代码:
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]
Now I have to prove that exec(comp e) s = eval e : s
. 现在,我必须证明exec(comp e) s = eval e : s
。
So I found this answer so far: 所以到目前为止,我找到了这个答案:
We have to prove that exec (comp e) s = eval e : s
. 我们必须证明exec (comp e) s = eval e : s
。
First case: Assume e = (Val n)
. 第一种情况:假设e = (Val n)
。 Then comp (Val n) = [PUSH n]
, so we have to prove that exec ([PUSH n]) s = eval ([PUSH n] : s)
. 然后comp (Val n) = [PUSH n]
,因此我们必须证明exec ([PUSH n]) s = eval ([PUSH n] : s)
。 We find that exec ([PUSH n]) s = exec [] (n:s) = (n:s)
using the function definition of exec. 我们使用exec的函数定义发现exec ([PUSH n]) s = exec [] (n:s) = (n:s)
。
Now eval (Val n) : s = n : s
. 现在eval (Val n) : s = n : s
。 The first case is OK! 第一种情况还可以!
Second case: Assume e = (Add xy)
. 第二种情况:假设e = (Add xy)
。 Then comp (Add xy) = comp x ++ comp y ++ [ADD]
. 然后comp (Add xy) = comp x ++ comp y ++ [ADD]
。
But now I'm struggling with this recursive use of comp. 但是现在,我正在为comp的递归使用而苦苦挣扎。 Should I be using some form of trees and induction on these trees to prove this? 我是否应该使用某种形式的树木并对这些树木进行归纳来证明这一点? I'm not completely sure how to do that. 我不太确定该怎么做。
When the first argument to exec
is a list, the two possibilities are: 当exec
的第一个参数是列表时,两种可能性是:
exec (PUSH n: codes) -- #1
exec (ADD : codes) -- #2
In the induction step you get to assume that the proposition holds for codes
, ie you may assume: 在归纳步骤中,您假设该命题适用于codes
,即,您可以假设:
exec codes s = eval codes : s
for any value of s -- Keep this in mind - this is usually the key step in any induction proof. 对于s的 任何值-请记住这一点-这通常是任何归纳证明的关键步骤。
Start by expanding #1 using the code you've written for exec
: 首先使用您为exec
编写的代码扩展#1:
exec (PUSH n: codes) s == exec codes (n:s)
== ...
== ...
== eval (PUSH n: codes) : s
Can you see a place to use the induction hypothesis? 您可以看到使用归纳假设的地方吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.