How to deal with really big terms generated in Fixpoint programs in Coq?

I am trying to determine and prove the correctness in Coq of a function that effectively delimits two sorted lists. Since it does not always recurs on a structurally smaller member (either the first or second list is smaller), Fixpointit will not accept it, so I'm trying to use it Program Fixpointinstead.

When trying to prove the property of a function using simplor tactics program_simpl, Coq calculates the minutes and then produces a gigantic term hundreds of lines long. I was wondering if I am using the Program Fixpointwrong way, or, alternatively, if there are other tactics that should be used instead of simplification, when you think about it?

I also wondered if you should use the correct methods for correctness in parameters like this, or would it be better to have a separate wrapper function that uses the correctness properties as parameters and make this function just take two lists to be different?

Please note that I tried to define a simpler version make_diffthat took only l1 and l2 as parameters and fixed the type Aand relation R, but it still created a gigantic term when program_simplor simpl.

* Edit: my included (although they may not all be required here):

Require Import Coq.Sorting.Sorted.
Require Import Coq.Lists.List.
Require Import Coq.Relations.Relation_Definitions.
Require Import Recdef.
Require Import Coq.Program.Wf.
Require Import Coq.Program.Tactics.

The code:

Definition is_decidable (A : Type) (R : relation A) := forall x y, {R x y} + {~(R x y)}.
Definition eq_decidable (A : Type) := forall (x y : A), { x = y } + { ~ (x = y) }.

Inductive diff (X: Type) : Type :=
  | add : X -> diff X
  | remove : X -> diff X 
  | update : X -> X -> diff X.

Program Fixpoint make_diff (A : Type) 
    (R : relation A)
    (dec : is_decidable A R)
    (eq_dec : eq_decidable A)
    (trans : transitive A R) 
    (lt_neq : (forall x y, R x y -> x <> y))
    (l1 l2 : list A)
     {measure (length l1 + length l2) } : list (diff A) :=
  match l1, l2 with
  | nil, nil => nil
  | nil, (new_h::new_t) => (add A new_h) :: (make_diff A R dec eq_dec trans lt_neq nil new_t)
  | (old_h::old_t), nil => (remove A old_h) :: (make_diff A R dec eq_dec trans lt_neq old_t nil)
  | (old_h::old_t) as old_l, (new_h::new_t) as new_l => 
    if dec old_h new_h 
      then (remove A old_h) :: make_diff A R dec eq_dec trans lt_neq old_t new_l
      else if eq_dec old_h new_h 
        then (update A old_h new_h) :: make_diff A R dec  eq_dec trans lt_neq old_t new_t
        else  (add A new_h) :: make_diff A R dec eq_dec trans lt_neq old_l new_t 
  end.
Next Obligation.
Proof.
  simpl.
  generalize dependent (length new_t).
  generalize dependent (length old_t).
  auto with arith.
Defined.
Next Obligation.
Proof.
  simpl.
  generalize dependent (length new_t).
  generalize dependent (length old_t).
  auto with arith.
Defined.
+4
source share
2 answers

Program Fixpoint Fixpoint. make_diff , , . ( Section , )

Require Import Coq.Lists.List.
Import ListNotations.
Require Import Coq.Relations.Relations.

Section Make_diff.

Variable A : Type.
Variable R : relation A.
Variable dec : is_decidable A R.
Variable eq_dec : eq_decidable A.
Variable trans : transitive A R.
Variable lt_neq : forall x y, R x y -> x <> y.

Fixpoint make_diff (l1 l2 : list A) : list (diff A) :=
  let fix make_diff2 l2 :=
  match l1, l2 with
  | nil, nil => nil
  | nil, new_h::new_t => (add A new_h) :: make_diff2 new_t
  | old_h::old_t, nil => (remove A old_h) :: make_diff old_t nil
  | old_h::old_t, new_h::new_t =>
    if dec old_h new_h 
    then (remove A old_h) :: make_diff old_t l2
    else if eq_dec old_h new_h 
         then (update A old_h new_h) :: make_diff old_t new_t
         else (add A new_h) :: make_diff2 new_t
  end
  in make_diff2 l2.

End Make_diff.

, Section . :

(* make the first 2 arguments implicit *)    
Arguments make_diff [A R] _ _ _ _.

Require Import Coq.Arith.Arith.

Compute make_diff lt_dec Nat.eq_dec [1;2;3] [4;5;6].
(* = [remove nat 1; remove nat 2; remove nat 3; add nat 4; add nat 5; add nat 6] 
      : list (diff nat) *)
+2

, , Equations, Fixpoint.

+1

Source: https://habr.com/ru/post/1679543/


All Articles