system: [SYSTEM]

user: 4. 策略 从本节开始，我们将在Coq中证明工作中使用的部分推理规则的可靠性并介绍证明带有分离蕴含的分离逻辑断言的策略。 4.1. 推理规则 以下是两个重要的推理规则，分别称为柯灵规则和柯灵逆反： P ∗ Q ⇒ R P ⇒ ( Q - ​ - ​ ∗ R ) ( 柯 灵 规 则 )   P ⇒ ( Q - ​ - ​ ∗ R ) P ∗ Q ⇒ R ( 柯 灵 逆 反 规 则 ) 柯灵规则及其逆反规则表述了分离合取和分离蕴涵之间的关系，并且由此可以推导出一系列推理规则。我们从几个基本示例开始阐述如何在Coq中证明它们是正确的。考虑下面的推断规则，它可由柯灵规则推出： emp ⇒ ( P − ​ ∗ P ) 证明过程如下： T h e o r e m     a w a n d _ e m p     :     f o r a l l   P ，   e m p ⇒   P - ​ - ​ * P . Theorem是一个命令，它表示正确性证明的开始，其证明过程从以下状态开始： 1   s u b g o a l ================= f o r a l l P : a s r t ， e m p ⇒   P - ​ - ​ *   P P r o o f .       i n t r o   P . P :   a s r t ================= e m p ⇒   P - ​ - ​ *   P proof是指启动证明脚本，而intro P将P转变为自由变量。这里，我们可以应用柯灵规则如下： a p p l y   C U R R Y I N G   w i t h     (   Q : = P   )     (   R : = P   )   . P :   a s r t ================= e m p   *   P ⇒   P a p p l y a s t a r _ e l i m . astar_elim是一个证明定理，其内容是：对所有P，emp ∗ P⇒P成立。应用astar_elim后，则不再有子目标，这意味着证明已完成。 Q e d . 最后，Qed检查证明是否完成。 注意到上面证明的规则可以被用来消去一些分离蕴含，那么以这样一个简单的设想为例，实现一个简单的策略，以展示如何使用交互式的机器证明代替手动证明。该策略称为sclearwand： L t a c   s c l e a r w a n d   : = 1       m a t c h   g o a l   w i t h 2   |   |   −   ? s |=     ? ​ A ⇒   m a t c h   f i n d _ a w a n d   A   w i t h 3                       |     s o m e ? n ⇒ s e p _ l i f t   n ; 4                   m a t c h   g o a l   w i t h 5                         | H : _ |= _ |   −   _   |= ( ? B - ​ - ​ * ? B ) * ? C ⇒   6                           ​ ​   a p p l y   a s t a r _ l _ a e m p _ i n t r o   i n   H ; 7                             e a p p l y   a s t a r _ m o n o ; [ e a p p l y   a w a n d _ e m p     |   8                             i n t r o s   s '   H ' ;   e x a c t   H '     |     a u t o ] ;   s c l e a r w a n d 9                           |   _ ⇒ i d t a c 10                     e n d 1 1                       |     _ ⇒ i d t a c 12                     e n d 13     ​ |     _ ⇒ f a i l   14       e n d . 首先匹配目标的模式，如果目标是类似于第2行的模式，则在第3行中，调用find_awand以查找A中分离蕴涵的位置。在第3行中，sep_lift将其移至A的左侧，随后证明目标将在第5~11行中解决，其中astar_l_aemp_intro和astar_mono分别是如下规则： P ⇒ emp ∗ P   P ⇒ P ′     Q ⇒ Q ′ P ∗ Q ⇒ P ′ ∗ Q ′ sclearwand可以消除(P −∗ P)，之后“emp”将在证明目标中取代它，例如： G o a l ​   f o r a l l   (   A   B :   a s r t   ) ，   A ⇒ A * ( B - ​ * B ) . P r o o f .     i n t r o s .     s c l e a r w a n d .     Q e d . 现在，考虑下面的推理规则并在Coq中证明其整确定性 P ′ ⇒ P   Q ⇒ Q ′ P - ​ - ​ ∗ Q ⇒ P ′ - ​ - ​ ∗ Q ′ T h e o r e m   a w a n d _ p r o : f o r a l l   P     P '     Q     Q ' ， P ' ⇒ P → Q ⇒ Q ' → P - ​ - ​ * Q ⇒ P ' - ​ - ​ * Q ' . P r o o f .   i n t r o s . s i m p l   i n   *   ;     m y t a c .   d o   3   e e x i s t s ;   m y t a c ; e a u t o . Q e d . mytac是原有系统中用于断言的自动证明策略，而上面的规则可以使用mytac证明，说明分离蕴含已被很好的添加到系统中。 仍然有很多关于分离蕴含的推理规则如下，在这里省略对他们的可靠性证明： Q ∗ ( Q - ​ - ​ ∗ P ) ⇒ P   P ⇒ Q ∗ ( Q - ​ - ​ ∗ P )     ( P ∗ R ) ⇒ ( P ∗ ( Q - ​ - ​ ∗ ( Q ∗ R ) ) )       P 0 ⇒ ( Q - ​ - ​ ∗ R )   P 1 ⇒ ( R - ​ - ​ ∗ S ) P 0 ∗ P 1 ⇒ ( Q - ​ - ​ ∗ S )         P ⇒ P ′ P ∗ ( P ′ - ​ - ​ ∗ Q ) ⇒ Q 4.2. 资源检测 在 [ 5 ] 提供的实用策略可以仅使用一行证明脚本证明整个程序，即“repeat hoare forward; sep pure”，其中repeat表示重复执行某项策略，这里指重复执行“hoare forward; sep pure”，sep pure是证明关于纯断言的策略，而hoare forward可以证明霍尔三元组⊢{P} c {Q}，是验证程序的的关键。 hoare forward的第一步是资源检测(check_resource)，它检测前置条件是否具有语句执行所需的信息。例如： { y > ​ ​ ​ → __} y : = x {       x > ​ ​ ​ → __ ∗     y > ​ ​ ​ → __} 其中 x ↣ v 表示变量x的值为v。显然，如果将x的值赋给y我们首先需要x的值。这里，resource_check在前置条件中没有找到有关x的信息，它将返回一条用户友好的消息，用户可以根据将相应的信息添加前置条件中，如下： { x > ​ ​ ​ → __ ∗ y > ​ ​ ​ → __} y : = x     {     x > ​ ​ ​ → __ ∗ y > ​ ​ ​ → _} 这就像开始验证前的预处理一样。然而，尽管如上一节所述分离蕴含已经被添加到系统中，并且前置条件中具有足够的信息，resource_check也无法检测到有关分离蕴含的信息，例如： {   x   > ​ ​ ​ →   __   ∗   ( x   > ​ ​ ​ →   v 1     - ​ - ​ ∗     y   > ​ ​ ​ →   _ )   }   x : = v 1   ;   y : =   v 2   {   y   > ​ ​ ​ →   v 2   } 前置条件中虽然存在 y ↣ _ ，但无法被识别。因此，我们需要调整resource_check的组件使得分离蕴含可以被识别并可以从中检测到需要的信息。 考虑resource_check的组件find_match_retV，它可以识别“∗”，但无法识别“−∗”，如下： L t a c   f i n d _ m a t c h _ r e t V     H p     x : =     1   m a t c h     H p     w i t h     2     |     ? A     *   ? B ⇒ m a t c h     f i n d _ m a t c h _ r e t V     A     x     w i t h     3                 |     s o m e   ? v ⇒   c o n s t r :   ( s o m e   v )       4                 |     _ ⇒ m a t c h     f i n d _ m a t c h _ r e t V     B     x     w i t h     5                       |     s o m e   ? v ⇒     c o n s t r :   ( s o m e   v )     6                                   |     _ ⇒   c o n s t r :   ( @ N o n e )     7                             e n d     8                             e n d     9         |     ? A     ⇒   ( *   h o a r e _ t a c t i c s . v   *   )     10   e n d . 将其更改如下： L t a c   f i n d _ m a t c h _ r e t V '     H p     x : =     1   m a t c h     H p     w i t h     2     |     ? A     *     ? B ⇒ m a t c h     f i n d _ m a t c h _ r e t V     A     x     w i t h     3                           |     s o m e   ? v ⇒   c o n s t r :   ( s o m e   v )     4                             |     _ ⇒ m a t c h     f i n d _ m a t c h _ r e t V     B     x     w i t h     5                                       |     s o m e   ? v ⇒     c o n s t r :   ( s o m e   v )     6                                           |     _ ⇒   c o n s t r :   ( @ N o n e )     7                                 e n d     8                         e n d     9         |     ? C     - ​ - ​ *   ? D ⇒ m a t c h     f i n d _ m a t c h _ r e t V     C     x     w i t h     10                             |     s o m e   ? v ⇒     c o n s t r :   ( s o m e   v )     11                               |     _ ⇒   ( *     h o a r e _ t a c t i c s . v   * )     12                                 m a t c h     f i n d _ m a t c h _ r e t V     D     x     w i t h     13                                   |   s o m e   ? v ⇒   c o n s t r :   ( s o m e   v )     14                                     |     _ ⇒   c o n s t r :   ( @ N o n e )     15                             e n d     16                   e n d     17       |     ? A ⇒ ( *   h o a r e _ t a c t i c s . v   *   )     18     e n d . 将resource_check中的find_match_retV替换为find_match_retV'之后，上述 ，因此hoare forward可以正常开始运行。