1

I am defining three mutually recursive functions on inductive type event, using two different ways: using with and fix keywords, however, Coq complains about principal argument and The reference ... was not found in ..., respectively. Two implementations of the functions are the following:

Require Import List.

Parameter max: list nat -> nat.
Inductive event : Type := node: list event -> event. 
Parameter eventbool : forall (P:event->Prop) (e:event), {P e} + {~ P e}.
Definition event_sumbool_b (e: event) (p: event -> Prop) : bool :=
  if eventbool p e then true else false.

Fixpoint parentround (e: event) : nat :=
  match e with
 | node l =>  max (rounds l)
 end

 with rounds l := 
   match l with 
   | nil => 0::nil 
   | h::tl => round h:: rounds tl
   end 

 with round e := 
   if event_sumbool_b e roundinc then parentround e + 1 else parentround e

 with roundinc e :=
  exists S:list event, (forall y, List.In y S /\ round y = parentround e). 

Coq complains Recursive call to round has principal argument equal to "h" instead of "tl". Even though, h in calling round is a sub-term of e. Following the idea in Recursive definitions over an inductive type, I replaced parentround with the following:

Fixpoint parentround (e: event) : nat :=

 let round := 
   ( fix round (e: event) : nat := 
      if event_sumbool_b e roundinc then parentround e + 1 else parentround e
   ) in

 let roundinc := 
   ( fix roundinc (e: event) : Prop :=
     exists S:list event, (forall y, List.In y S /\ round y = parentround e)
   ) in

 match e with
 | node l =>  max (rounds l)
 end

 with rounds l :=
   match l with 
   | nil => 0::nil 
   | h::tl => round h:: rounds tl
   end. 

It now complains about missing definition of roundinc.

Please help me defining these three mutually recursive functions parentround, round and roundinc.

EDIT There is a fourth function rounds in the definition, however, it is not problematic so far.

Community
  • 1
  • 1
Khan
  • 303
  • 2
  • 14
  • Btw, there is an issue with your `round` function: it doesn't call `parentround` on a sub-term of `e`, but directly on `e`. I don't think this is allowed. – Vinz Sep 07 '16 at 11:31
  • 1
    Also, in `roundinc`, the call to `round y` is not decreasing, it should be something like `round l` where `e = node l` – Vinz Sep 07 '16 at 11:46
  • @Vinz The function `round` is called from within `rounds` where the sub-term of `e` (which is `h`) is passed (renaming `e` in `round` makes no difference). When it is called from within `roundinc`, as you pointed it out, `y` is not decreasing. Actually, the real function is using a complex predicate `stronglysee` on `y` and `e`, which include that `y` is a sub-event of `e`. The problem now, in addition, is: even if we include that predicate in `roundinc`, Coq does not understand automatically, that `y` is indeed a sub-term of `e`. – Khan Sep 07 '16 at 13:54

2 Answers2

2

It was a bit difficult for me to figure out what you would like to compute, I'd start with something like:

From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq choice fintype.
From mathcomp Require Import bigop.

Definition max_seq l := \max_(x <- l) x.

Inductive event : Type :=
  node : seq event -> event.

Fixpoint round_lvl (e : event) : nat :=
  (* XXX: Missing condition *)
  let cond_inc x := round_lvl x in
  match e with
  | node l => max_seq (map cond_inc l)
  end.

But I had trouble parsing what the existence condition means. I suggest you try to express the problem without Coq code first, and maybe from that a solution pops.

ejgallego
  • 6,709
  • 1
  • 14
  • 29
1

From my experience, it is really hard to define mutual function on a type T and on list T. I recall a post on Coq-club about this subjet, I have to find it again.

The "easy" solution is to define a mutual inductive type where you define event and event_list at the same time. However, you won't be able to use the list library...

Vinz
  • 5,997
  • 1
  • 31
  • 52
  • There is one method as shared in the link in post, however, it is for two mutually recursive functions. The problem is, to generalize it to more than two functions. Your suggested method will make the proofs difficult, as we won't be able to use list related lemmas from the library. – Khan Sep 07 '16 at 08:48