- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 "simple imperative programs"软件基础一章,一路上也用 Agda 做练习。该书指出,在 AST-s 上进行证明是乏味的,并继续介绍 Coq 中的自动化工具。
如何减少 Agda 的乏味?
这是一个示例代码:
open import Data.Nat hiding (_≤?_)
open import Function
open import Data.Bool
open import Relation.Binary.PropositionalEquality
open import Data.Empty
open import Data.Product
open import Data.Unit hiding (_≤?_)
data AExp : Set where
ANum : ℕ → AExp
APlus AMinus AMult : AExp → AExp → AExp
aeval : AExp → ℕ
aeval (ANum x) = x
aeval (APlus a b) = aeval a + aeval b
aeval (AMinus a b) = aeval a ∸ aeval b
aeval (AMult a b) = aeval a * aeval b
opt-0+ : AExp → AExp
opt-0+ (ANum x) = ANum x
opt-0+ (APlus (ANum 0) b) = b
opt-0+ (APlus a b) = APlus (opt-0+ a) (opt-0+ b)
opt-0+ (AMinus a b) = AMinus (opt-0+ a) (opt-0+ b)
opt-0+ (AMult a b) = AMult (opt-0+ a) (opt-0+ b)
opt-0+-sound : ∀ e → aeval (opt-0+ e) ≡ aeval e
opt-0+-sound (ANum x) = refl
opt-0+-sound (APlus (ANum zero) b) rewrite opt-0+-sound b = refl
opt-0+-sound (APlus (ANum (suc x)) b) rewrite opt-0+-sound b = refl
opt-0+-sound (APlus (APlus a a₁) b) rewrite opt-0+-sound (APlus a a₁) | opt-0+-sound b = refl
opt-0+-sound (APlus (AMinus a a₁) b) rewrite opt-0+-sound (AMinus a a₁) | opt-0+-sound b = refl
opt-0+-sound (APlus (AMult a a₁) b) rewrite opt-0+-sound (AMult a a₁) | opt-0+-sound b = refl
opt-0+-sound (AMinus a b) rewrite opt-0+-sound a | opt-0+-sound b = refl
opt-0+-sound (AMult a b) rewrite opt-0+-sound a | opt-0+-sound b = refl
transform : (AExp → AExp) → AExp → AExp
transform f (ANum x) = f (ANum x)
transform f (APlus a b) = f (APlus (transform f a) (transform f b))
transform f (AMinus a b) = f (AMinus (transform f a) (transform f b))
transform f (AMult a b) = f (AMult (transform f a) (transform f b))
opt-0+ : AExp → AExp
opt-0+ = transform (λ {(APlus (ANum 0) b) → b; x → x})
opt-0+-sound (APlus (ANum zero) b) rewrite opt-0+-sound b = refl
opt-0+-sound (APlus (ANum (suc x)) b) rewrite opt-0+-sound b = refl
opt-0+-sound (APlus (APlus a a₁) b) rewrite opt-0+-sound (APlus a a₁) | opt-0+-sound b = refl
opt-0+-sound (APlus (AMinus a a₁) b) rewrite opt-0+-sound (AMinus a a₁) | opt-0+-sound b = refl
opt-0+-sound (APlus (AMult a a₁) b) rewrite opt-0+-sound (AMult a a₁) | opt-0+-sound b = refl
opt-0+
唯一相关的案例。因此我们必须再次写出每个构造函数。随着构造函数数量的增加,这个问题变得更加令人讨厌。
最佳答案
让我们概括一下您的 transform
一点:
foldAExp : {A : Set} -> (ℕ -> A) -> (_ _ _ : A -> A -> A) -> AExp -> A
foldAExp f0 f1 f2 f3 (ANum x) = f0 x
foldAExp f0 f1 f2 f3 (APlus a b) = f1 (foldAExp f0 f1 f2 f3 a) (foldAExp f0 f1 f2 f3 b)
foldAExp f0 f1 f2 f3 (AMinus a b) = f2 (foldAExp f0 f1 f2 f3 a) (foldAExp f0 f1 f2 f3 b)
foldAExp f0 f1 f2 f3 (AMult a b) = f3 (foldAExp f0 f1 f2 f3 a) (foldAExp f0 f1 f2 f3 b)
generalize : ∀ f0 f1 f2 f3
-> (∀ x -> aeval (f0 x) ≡ aeval (ANum x))
-> (∀ a b -> aeval (f1 a b) ≡ aeval (APlus a b))
-> (∀ a b -> aeval (f2 a b) ≡ aeval (AMinus a b))
-> (∀ a b -> aeval (f3 a b) ≡ aeval (AMult a b))
-> (∀ e -> aeval (foldAExp f0 f1 f2 f3 e) ≡ aeval e)
generalize f0 f1 f2 f3 p0 p1 p2 p3 (ANum x) = p0 x
generalize f0 f1 f2 f3 p0 p1 p2 p3 (APlus a b)
rewrite p1 (foldAExp f0 f1 f2 f3 a) (foldAExp f0 f1 f2 f3 b)
| generalize f0 f1 f2 f3 p0 p1 p2 p3 a | generalize f0 f1 f2 f3 p0 p1 p2 p3 b = refl
generalize f0 f1 f2 f3 p0 p1 p2 p3 (AMinus a b)
rewrite p2 (foldAExp f0 f1 f2 f3 a) (foldAExp f0 f1 f2 f3 b)
| generalize f0 f1 f2 f3 p0 p1 p2 p3 a | generalize f0 f1 f2 f3 p0 p1 p2 p3 b = refl
generalize f0 f1 f2 f3 p0 p1 p2 p3 (AMult a b)
rewrite p3 (foldAExp f0 f1 f2 f3 a) (foldAExp f0 f1 f2 f3 b)
| generalize f0 f1 f2 f3 p0 p1 p2 p3 a | generalize f0 f1 f2 f3 p0 p1 p2 p3 b = refl
f0
,
f1
,
f2
和
f3
,不改变任何适当子表达式的“含义”(
Num _
用于
f0
,
APlus _ _
用于
f1
等等),我们可以使用这些函数折叠任何表达式而不改变其“含义” .这是一个简单的例子:
idAExp : AExp → AExp
idAExp = foldAExp ANum APlus AMinus AMult
idAExp-sound : ∀ e → aeval (idAExp e) ≡ aeval e
idAExp-sound = generalize _ _ _ _ (λ _ → refl) (λ _ _ → refl) (λ _ _ → refl) (λ _ _ → refl)
0+-f1 : AExp -> AExp -> AExp
0+-f1 a b with a ≟AExp ANum 0
0+-f1 .(ANum 0) b | yes refl = b
0+-f1 a b | no p = APlus a b
opt-0+ : AExp → AExp
opt-0+ = foldAExp ANum 0+-f1 AMinus AMult
0+-p1 : ∀ a b -> aeval (0+-f1 a b) ≡ aeval (APlus a b)
0+-p1 a b with a ≟AExp ANum 0
0+-p1 .(ANum 0) b | yes refl = refl
0+-p1 a b | no p = refl
opt-0+-sound : ∀ e → aeval (opt-0+ e) ≡ aeval e
opt-0+-sound = generalize _ _ _ _ (λ _ → refl) 0+-p1 (λ _ _ → refl) (λ _ _ → refl)
fancy-lem : ∀ a1 a2 b1 b2 -> a1 * b1 + a1 * b2 + a2 * b1 + a2 * b2 ≡ (a1 + a2) * (b1 + b2)
fancy-lem = solve
4
(λ a1 a2 b1 b2 → a1 :* b1 :+ a1 :* b2 :+ a2 :* b1 :+ a2 :* b2 := (a1 :+ a2) :* (b1 :+ b2))
refl
where
import Data.Nat.Properties
open Data.Nat.Properties.SemiringSolver
AExp
进行这样的优化。学期:
left : AExp -> AExp
left (ANum x ) = ANum x
left (APlus a b) = a
left (AMinus a b) = a
left (AMult a b) = a
right : AExp -> AExp
right (ANum x ) = ANum x
right (APlus a b ) = b
right (AMinus a b) = b
right (AMult a b) = b
fancy-f3 : AExp -> AExp -> AExp
fancy-f3 a b with left a | right a | left b | right b
fancy-f3 a b | a1 | a2 | b1 | b2 with a ≟AExp APlus a1 a2 | b ≟AExp APlus b1 b2
fancy-f3 .(APlus a1 a2) .(APlus b1 b2) | a1 | a2 | b1 | b2 | yes refl | yes refl =
APlus (APlus (APlus (AMult a1 b1) (AMult a1 b2)) (AMult a2 b1)) (AMult a2 b2)
fancy-f3 a b | a1 | a2 | b1 | b2 | _ | _ = AMult a
opt-fancy : AExp → AExp
opt-fancy = foldAExp ANum APlus AMinus fancy-f3
fancy-p3 : ∀ a b -> aeval (fancy-f3 a b) ≡ aeval (AMult a b)
fancy-p3 a b with left a | right a | left b | right b
fancy-p3 a b | a1 | a2 | b1 | b2 with a ≟AExp APlus a1 a2 | b ≟AExp APlus b1 b2
fancy-p3 .(APlus a1 a2) .(APlus b1 b2) | a1 | a2 | b1 | b2 | yes refl | yes refl =
fancy-lem (aeval a1) (aeval a2) (aeval b1) (aeval b2)
fancy-p3 .(APlus a1 a2) b | a1 | a2 | b1 | b2 | yes refl | no _ = refl
fancy-p3 a .(APlus b1 b2) | a1 | a2 | b1 | b2 | no _ | yes refl = refl
fancy-p3 a b | a1 | a2 | b1 | b2 | no _ | no _ = refl
opt-fancy-sound : ∀ e → aeval (opt-fancy e) ≡ aeval e
opt-fancy-sound = generalize _ _ _ _ (λ _ → refl) (λ _ _ → refl) (λ _ _ → refl) fancy-p3
generalize
中的样板数量和
≟AExp
.技巧在这里描述:
http://rubrication.blogspot.ru/2012/03/decidable-equality-in-agda.html
foldAExp
东西。平时
transform
让事情变得更容易。以下是一些定义:
transform : (AExp → AExp) → AExp → AExp
transform f (ANum x) = f (ANum x)
transform f (APlus a b) = f (APlus (transform f a) (transform f b))
transform f (AMinus a b) = f (AMinus (transform f a) (transform f b))
transform f (AMult a b) = f (AMult (transform f a) (transform f b))
generalize : ∀ f -> (∀ e -> aeval (f e) ≡ aeval e)
-> (∀ e -> aeval (transform f e) ≡ aeval e)
generalize f p (ANum x) = p (ANum x)
generalize f p (APlus a b) rewrite p (APlus (transform f a) (transform f b))
| generalize f p a | generalize f p b = refl
generalize f p (AMinus a b) rewrite p (AMinus (transform f a) (transform f b))
| generalize f p a | generalize f p b = refl
generalize f p (AMult a b) rewrite p (AMult (transform f a) (transform f b))
| generalize f p a | generalize f p b = refl
idAExp : AExp → AExp
idAExp = transform id
idAExp-sound : ∀ e → aeval (idAExp e) ≡ aeval e
idAExp-sound = generalize _ (λ _ → refl)
关于agda - Agda 中非繁琐的 AST 转换证明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24475546/
我喜欢在 Lisp、Python 或 JavaScript 等(通常是动态的)语言中可以使用 boolean 运算符而不是条件来编写的简洁代码,如典型的: x = someString or "def
具体来说,我将 WPF 与 MVVM 一起使用。我有一个 MainWindow,它是一个 WPF 窗口,所有操作都在其中发生。它为其属性、命令等使用相应的 View 模型类。 我在 Applicati
对于我从 VB6 移植的应用程序,我有几个关于 CLS 合规性的烦人的编译器警告,包括: Name '_AnIdentifier' is not CLS-Compliant. Type of para
Module Unix 包含 time 函数来获取自 Epoch 以来的秒数,但是是否有一种独立于平台的方式来获取相同的值并确保代码在非-Unix 部署? 最佳答案 尽管有它的名字,Unix modu
我有一个 R 函数,它试图将每个“单词”的第一个字母大写 proper = function(x){ gsub("(? proper("Māori") [1] "MāOri" 显然,RE 引擎认为
我有一个包含两列的表格。一个是 auto_increment 说 columnA 而另一个是非 auto_increment 说 columnB。我想在 columnB 中执行两种类型的插入操作: 插
我遇到了这个错误,但无法调试它 helpers.c:136:1: error: control may reach end of non-void function IDE 在最后一行中说} 这是我的
我想检查一个数组在 C 中是否按 acs 或 desc 顺序排序。这是使用 mpicc -Wall -o file file.c 编译的结果,因为我稍后在代码中使用 MPI 库。 mypractice
我想了解编译器对 C 中的非 volatile 变量有哪些限制(如果有的话)。 我不确定这是否属实,但有人告诉我,如果您有以下代码: int x; ... void update_x() { lo
我的代码在 IE 中有效,但在 Firefox 中无效。我试图让 onmousedown 和 onmouseup 事件以及 swapFE、swapEF 和 setUpTranslation 函数在 I
我的问题是.. 是否可以在非 root 设备上静默自动更新应用程序?如果设备已 Root ,则它会使用 super 用户权限更新我的应用程序,否则不会。请回复谢谢! 最佳答案 无法在非 Root 设备
阅读了 PropertyAnimator 的文档后,似乎只要满足以下条件之一,我们就可以为每个对象设置动画, 如果您有权限,请将 setter 方法添加到类中。 使用您有权更改的包装器类,并让该包装器
所以我正在制作移动应用程序,并希望使用相同的 URL 创建链接以激活 iOS 和 Android 中的内容。我已经知道该怎么做了。我对 android 的 Intent 是这样的:
这个问题很接近我的问题,但又不完全是:List minimum in Python with None? .我需要考虑到列表中所有值都为 None 的可能性。 我有一种情况,我必须在数据库中查找一些数
如何从 Pandas 数据框中获取非“NaN”值的索引? 我的数据框是 A b c 0 1 q1 1 1 2 NaN 3 2 3 q2
对于数据框 df = pd.DataFrame([[np.nan, 3.0, 7.0], [0.0, 5.0, 8.0], [0.0, 0.0, 0.0], [1.0, 3.0, np.nan], [
我在 Android 中播放视频之前对其进行解密。当我解密它时,我想将它存储在 Android 私有(private)文件夹中,这样其他应用程序和用户就无法访问它 - 我已经查找了一些看起来像这样的代
我有一个非常大的 csv 文件,如下所示: 关键词,印象 下载 juegos gratis,951 パソコン kakaku com,451 公司 session ,155 租车,356
我有一个继承自 AbstractType 的表单生成器类,我需要解析如下路径: $uri = $router->generate('blog_show', array('slug' => 'my-bl
我想从 Android 应用程序中的一个原始文本文件中读取一些文本,并在应用程序中显示该文本文件中的一行。小部件。 对于 MainActivity,我编写了一个使用以下代码获取 InputStream
我是一名优秀的程序员,十分优秀!