Recursion Coq中函数终止性的证明

Recursion Coq中函数终止性的证明,recursion,coq,termination,Recursion,Coq,Termination,我无法证明以下功能的终止: Fixpoint norm_union u v : regex := match u, v with | Empty , v => v | u , Empty => u | Union u v, w => norm_union u (norm_union v w) | u , Union v w => if eq_regex_dec u v

我无法证明以下功能的终止:

Fixpoint norm_union u v : regex :=
  match u, v with
  | Empty    , v         => v
  | u        , Empty     => u
  | Union u v, w         => norm_union u (norm_union v w)
  | u        , Union v w => if eq_regex_dec u v
                            then Union v w
                            else if le_regex u v
                                 then Union u (Union v w)
                                 else Union v (norm_union u w)
  | u        , v         => if eq_regex_dec u v
                            then u
                            else if le_regex u v
                                 then Union u v
                                 else Union v u
  end.
Definition norm_union_F : forall p : regex * regex,
   forall g : (forall p', order p' p -> 
                {r : regex | size_regex r <= size_2regex p'}), 
    {r : regex | size_regex r <= size_2regex p} :=
 fun p norm_union =>
   match ar (fst p) with
     arE _ eq1 => exist _ (snd p) (th1 p)
   | arU _ u v eq1 =>
     match ar (snd p) with
       arE _ eq2 => exist _ (Union u v) (th2' _ _ _ eq1)
     | _ => exist _ (proj1_sig 
             (norm_union (u, 
                 proj1_sig (norm_union (v, snd p) 
                 (th3' _ _ _ eq1)))
                 (th4' _ _ _ eq1 (th3' _ _ _ eq1) 
                   (proj1_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))
                   _))) 
             (th5' _ _ _ eq1 
                 (proj1_sig (norm_union (v, snd p)
                               (th3' _ _ _ eq1)))
                 (proj2_sig (norm_union (v, snd p)
                               (th3' _ _ _ eq1)))
                 (proj1_sig
                     (norm_union 
                          (u, proj1_sig (norm_union (v, snd p)
                                          (th3' _ _ _ eq1)))
                   (th4' _ _ _ eq1 (th3' _ _ _ eq1) 
                   (proj1_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))
                   (proj2_sig (norm_union (v, snd p) (th3' _ _ _ eq1))))))
                 (proj2_sig
                     (norm_union 
                          (u, proj1_sig (norm_union (v, snd p)
                                          (th3' _ _ _ eq1)))
                   (th4' _ _ _ eq1 (th3' _ _ _ eq1) 
                   (proj1_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))
                   (proj2_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))))))
     end
   | arO _ d1 d2 =>
     match ar (snd p) with
       arE _ eq2 => exist _ (fst p) (th11' _)
     | arU _ v w eq2 =>
       if eq_regex_dec (fst p) v then
          exist _ (Union v w) (th7' _ _ _ eq2)
       else if le_regex (fst p) v then
         exist _ (Union (fst p) (Union v w)) (th8' _ _ _ eq2)
       else exist _ (Union v (proj1_sig (norm_union (fst p, w)
               (th9' _ _ _ eq2))))
               (th10' _ _ _ eq2
                 (proj1_sig (norm_union (fst p, w)
                       (th9' _ _ _ eq2)))
                 (proj2_sig (norm_union (fst p, w)
                       (th9' _ _ _ eq2))))
     | arO _ d1 d2 =>
       if eq_regex_dec (fst p) (snd p) then
         exist _ (fst p) (th11' _)
       else if le_regex (fst p) (snd p) then
         exist _ (Union (fst p) (snd p)) (th12' _)
       else exist _ (Union (snd p) (fst p)) (th13' _)
     end
   end.
其中,
regex
是正则表达式的类型,
le_regex
实现正则表达式的总排序。资料来源为本文件第五页。该函数作为正则表达式规范化函数的一部分出现(在Isabelle/HOL中形式化)。
le_regex
函数改编自同一篇文章。我正在使用
ascii
来避免通过可确定的总顺序来参数化
regex
(并希望提取程序)

归纳正则表达式:设置:=
|空:正则表达式
|ε:正则表达式
|符号:ascii->regex
|联合:正则表达式->正则表达式->正则表达式
|Concat:regex->regex->regex
|星:正则表达式->正则表达式。
引理eq_regex_dec:forall u v:regex,{u=v}+{u v}。
证据决定平等;应用ascii_dec.定义。
固定点leu_regex v:bool:=
将u,v与
|空,=>true
|_u,Empty=>false
|ε=true
|_u,Epsilon=>false
|符号a,符号b=>ascii a的nat\u为真
|_u,符号=>false
|星u,星v=>le_regex u v
|星号u,=>true
|_u,星v=>假
|Union u1 u2,Union v1 v2=>如果等式为regex,则为dec u1 v1
然后le_regex u2 v2
else le_regex u1 v1
|联合u,=>true
|联合,联合,假,
|Concat u1 u2,Concat v1 v2=>if eq_regex_dec u1 v1
然后le_regex u2 v2
else le_regex u1 v1
终止

我认为正确的方法是定义一个递减度量,并使用
程序固定点
来证明终止。然而,我很难想出正确的措施(基于操作员数量的尝试没有成功)。我曾尝试将工作分解为单独的函数,但遇到了类似的问题。任何帮助或指向正确方向的提示都将不胜感激。

您的代码比通常使用度量函数处理的代码更复杂,因为您在以下行中有一个嵌套的递归调用:

Union u v, w         => norm_union u (norm_union v w)  (* line 5 *)
我建议您不应该在type
regex
中返回值,而应该在type
{r:regex | size r
中返回值,以获得
size
combined_size
的合适概念

在对问题进行了几个小时的研究之后,还发现递归依赖于参数的词汇顺序
norm\u union v w
可能返回
union v w
,因此需要参数对
(u,union v w)
小于
(union u v,w)
。 因此,如果你真的想使用一个度量,你需要左手边的重量大于右手边的重量,你需要一个
联合体的一个组件的度量小于整体的度量


由于词汇顺序的性质,我选择不使用度量,而是使用一个有充分根据的顺序。另外,我对
程序固定点不太了解,所以我用另一种工具为您的问题开发了一个解决方案。我想出的解决办法是显而易见的。至少这显示了所有需要证明的递减条件。

您的代码比通常使用度量函数处理的代码更复杂,因为您在以下行中有一个嵌套的递归调用:

Union u v, w         => norm_union u (norm_union v w)  (* line 5 *)
我建议您不应该在type
regex
中返回值,而应该在type
{r:regex | size r
中返回值,以获得
size
combined_size
的合适概念

在对问题进行了几个小时的研究之后,还发现递归依赖于参数的词汇顺序
norm\u union v w
可能返回
union v w
,因此需要参数对
(u,union v w)
小于
(union u v,w)
。 因此,如果你真的想使用一个度量,你需要左手边的重量大于右手边的重量,你需要一个
联合体的一个组件的度量小于整体的度量


由于词汇顺序的性质,我选择不使用度量,而是使用一个有充分根据的顺序。另外,我对
程序固定点不太了解,所以我用另一种工具为您的问题开发了一个解决方案。我想出的解决办法是显而易见的。至少这显示了所有需要证明的递减条件。

经过一天的额外工作,我现在对这个问题有了更完整的答案。现在仍然可以看到它。这个解决方案值得一些评论

首先,我使用一个名为
Fix
(长名称是代码> COQ.inq.Wf.Fix< /Cord>。这是一个高阶函数,可以用来定义函数,建立良好的递归。我需要一个有根据的顺序,这个顺序被称为“代码>命令< /代码>。ixpoint
命令

其次,您编写的代码同时对
regex
类型的两个值执行案例分析,因此导致36个案例(稍微少一点,因为当第一个参数
为空时,第二个参数没有案例分析)。您在代码中看不到36种情况,因为模式只是一个变量的同一规则涵盖了多个构造函数。为了避免这种情况的倍增,我为它们设计了一种特定的归纳类型
案例分析。我将此特定类型称为
arT
。然后我定义了一个函数
ar
,该函数将
regex>类型的任何元素映射到
arT的相应元素
Definition norm_union_F : forall p : regex * regex,
   forall g : (forall p', order p' p -> 
                {r : regex | size_regex r <= size_2regex p'}), 
    {r : regex | size_regex r <= size_2regex p} :=
 fun p norm_union =>
   match ar (fst p) with
     arE _ eq1 => exist _ (snd p) (th1 p)
   | arU _ u v eq1 =>
     match ar (snd p) with
       arE _ eq2 => exist _ (Union u v) (th2' _ _ _ eq1)
     | _ => exist _ (proj1_sig 
             (norm_union (u, 
                 proj1_sig (norm_union (v, snd p) 
                 (th3' _ _ _ eq1)))
                 (th4' _ _ _ eq1 (th3' _ _ _ eq1) 
                   (proj1_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))
                   _))) 
             (th5' _ _ _ eq1 
                 (proj1_sig (norm_union (v, snd p)
                               (th3' _ _ _ eq1)))
                 (proj2_sig (norm_union (v, snd p)
                               (th3' _ _ _ eq1)))
                 (proj1_sig
                     (norm_union 
                          (u, proj1_sig (norm_union (v, snd p)
                                          (th3' _ _ _ eq1)))
                   (th4' _ _ _ eq1 (th3' _ _ _ eq1) 
                   (proj1_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))
                   (proj2_sig (norm_union (v, snd p) (th3' _ _ _ eq1))))))
                 (proj2_sig
                     (norm_union 
                          (u, proj1_sig (norm_union (v, snd p)
                                          (th3' _ _ _ eq1)))
                   (th4' _ _ _ eq1 (th3' _ _ _ eq1) 
                   (proj1_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))
                   (proj2_sig (norm_union (v, snd p) (th3' _ _ _ eq1)))))))
     end
   | arO _ d1 d2 =>
     match ar (snd p) with
       arE _ eq2 => exist _ (fst p) (th11' _)
     | arU _ v w eq2 =>
       if eq_regex_dec (fst p) v then
          exist _ (Union v w) (th7' _ _ _ eq2)
       else if le_regex (fst p) v then
         exist _ (Union (fst p) (Union v w)) (th8' _ _ _ eq2)
       else exist _ (Union v (proj1_sig (norm_union (fst p, w)
               (th9' _ _ _ eq2))))
               (th10' _ _ _ eq2
                 (proj1_sig (norm_union (fst p, w)
                       (th9' _ _ _ eq2)))
                 (proj2_sig (norm_union (fst p, w)
                       (th9' _ _ _ eq2))))
     | arO _ d1 d2 =>
       if eq_regex_dec (fst p) (snd p) then
         exist _ (fst p) (th11' _)
       else if le_regex (fst p) (snd p) then
         exist _ (Union (fst p) (snd p)) (th12' _)
       else exist _ (Union (snd p) (fst p)) (th13' _)
     end
   end.
Definition norm_union_1 : forall p : regex*regex,
  {x | size_regex x <= size_2regex p} :=
  Fix well_founded_order (fun p => {x | size_regex x <= size_2regex p})
  norm_union_F.
Definition norm_union u v : regex := proj1_sig (norm_union_1 (u, v)).
Lemma norm_union_eqn u v :
  norm_union u v = 
  match u, v with
  | Empty    , v         => v
  | u        , Empty     => u
  | Union u v, w         => norm_union u (norm_union v w)
  | u        , Union v w => if eq_regex_dec u v
                            then Union v w
                            else if le_regex u v
                                 then Union u (Union v w)
                                 else Union v (norm_union u w)
  | u        , v         => if eq_regex_dec u v
                            then u
                            else if le_regex u v
                                 then Union u v
                                 else Union v u
  end.