Problems with dependent types in Coq proof assistant

Consider the following simple expression language:

Inductive Exp : Set :=
| EConst : nat -> Exp
| EVar   : nat -> Exp
| EFun   : nat -> list Exp -> Exp.

      

and a predicate for its correctness:

Definition Env := list nat.

Inductive WF (env : Env) : Exp -> Prop :=
| WFConst : forall n, WF env (EConst n)
| WFVar   : forall n, In n env -> WF env (EVar n)
| WFFun   : forall n es, In n env ->
                         Forall (WF env) es ->
                         WF env (EFun n es).

      

which basically states that every variable and function symbol must be defined in the environment. Now I want to define a function that determines the decidability of the predicate WF

:

Definition WFDec (env : Env) : forall e, {WF env e} + {~ WF env e}.
   refine (fix wfdec e : {WF env e} + {~ WF env e} :=
             match e as e' return e = e' -> {WF env e'} + {~ WF env e'} with
             | EConst n => fun _ => left _ _
             | EVar n => fun _ =>
                      match in_dec eq_nat_dec n env with
                      | left _ _ => left _ _ 
                      | right _ _ => right _ _                    
                      end
             | EFun n es => fun _ =>
                      match in_dec eq_nat_dec n env with
                      | left _ _ => _
                      | right _ _ => right _ _                    
                      end  
             end (eq_refl e)) ; clear wfdec ; subst ; eauto.

      

The problem is how to assert that the predicate WF

is executed or not for the list of expressions in the case EFun

. My obvious guess is:

     ...  

     match Forall_dec (WF env) wfdec es with

     ...

      

But Kok dismisses it, arguing that the recursive call is wfdec

ill-formed. My question is, is it possible to determine the decidability of such a justification predicate without changing the representation of the expression?

Full working code is given below gist .

+3


source to share


2 answers


The problem is what Forall_dec

is defined as opaque in the standard library (i.e. Qed

instead of Defined

). Because of this, Coq doesn’t know what the use wfdec

is.

The immediate solution to your problem is to override Forall_dec

it to be transparent. You can do this by typing proof that Coq is generating and inserting it into the source file. I've added a gist here with a complete solution.



Needless to say, this approach lends itself to bloated, hard to read, and difficult to maintain code. As ejgallego pointed out in his answer, your best bet in this case is probably to define a boolean function that solves WF

, and use that instead wfdec

. The only problem with his approach, he says, is that you will need to write your own induction principle before Exp

to prove that the boolean version does indeed solve the inductive definition. Adam Chlipala CPDT has a chapter on inductive types which gives an example of such an induction principle; just search for "nested inductive types".

+6


source


As a temporary workaround, you can define wf

as:

Definition wf (env : Env) := fix wf (e : Exp) : bool :=
  match e with
  | EConst _ => true
  | EVar v   => v \in env
  | EFun v l => [&& v \in env & all wf l]
  end.

      



which is usually more convenient to use. However, this definition would be rather useless due to the fact that Coq generates the wrong induction principle for exp

, since it does not detect the list. I usually do this to fix the induction principle by hand, but it's expensive. Example:

From Coq Require Import List.
From mathcomp Require Import all_ssreflect.

Set Implicit Arguments.
Unset Printing Implicit Defensive.
Import Prenex Implicits.

Section ReflectMorph.

Lemma and_MR P Q b c : reflect P b -> reflect Q c -> reflect (P /\ Q) (b && c).
Proof. by move=> h1 h2; apply: (iffP andP) => -[/h1 ? /h2 ?]. Qed.

Lemma or_MR P Q b c : reflect P b -> reflect Q c -> reflect (P \/ Q) (b || c).
Proof. by move=> h1 h2; apply: (iffP orP) => -[/h1|/h2]; auto. Qed.

End ReflectMorph.

Section IN.
Variables (X : eqType).

Lemma InP (x : X) l : reflect (In x l) (x \in l).
Proof.
elim: l => [|y l ihl]; first by constructor 2.
by apply: or_MR; rewrite // eq_sym; exact: eqP.
Qed.

End IN.

Section FORALL.

Variables (X : Type) (P : X -> Prop).
Variables (p : X -> bool).

Lemma Forall_inv x l : Forall P (x :: l) -> P x /\ Forall P l.
Proof. by move=> U; inversion U. Qed.

Lemma ForallP l : (forall x, In x l -> reflect (P x) (p x)) -> reflect (Forall P l) (all p l).
Proof.
elim: l => [|x l hp ihl /= ]; first by constructor.
have/hp {hp}hp : forall x : X, In x l -> reflect (P x) (p x).
  by move=> y y_in; apply: ihl; right.
have {ihl} ihl := ihl _ (or_introl erefl).
by apply: (iffP andP) => [|/Forall_inv] [] /ihl hx /hp hall; constructor.
Qed.

End FORALL.

Inductive Exp : Type :=
| EConst : nat -> Exp
| EVar   : nat -> Exp
| EFun   : nat -> list Exp -> Exp.

Lemma Exp_rect_list (P : Exp -> Type) :
  (forall n : nat, P (EConst n)) ->
  (forall n : nat, P (EVar n)) ->
  (forall (n : nat) (l : seq Exp), (forall x, In x l -> P x) -> P (EFun n l)) ->
  forall e : Exp, P e.
Admitted.

Definition Env := list nat.

Definition wf (env : Env) := fix wf (e : Exp) : bool :=
  match e with
  | EConst _ => true
  | EVar v   => v \in env
  | EFun v l => [&& v \in env & all wf l]
  end.

Inductive WF (env : Env) : Exp -> Prop :=
| WFConst : forall n, WF env (EConst n)
| WFVar   : forall n, In n env -> WF env (EVar n)
| WFFun   : forall n es, In n env ->
                         Forall (WF env) es ->
                         WF env (EFun n es).

Lemma WF_inv env e (wf : WF env e ) :
  match e with
  | EConst n  => True
  | EVar n    => In n env
  | EFun n es => In n env /\ Forall (WF env) es
  end.
Proof. by case: e wf => // [n|n l] H; inversion H. Qed.

Lemma wfP env e : reflect (WF env e) (wf env e).
Proof.
elim/Exp_rect_list: e => [n|n|n l ihe] /=; try repeat constructor.
  by apply: (iffP idP) => [/InP|/WF_inv/InP //]; constructor.
apply: (iffP andP) => [[/InP ? /ForallP H]|/WF_inv[/InP ? /ForallP]].
  by constructor => //; exact: H.
by auto.
Qed.

      

+5


source







All Articles