Zulip Chat Archive

Stream: new members

Topic: Well Founded Recursion New Problems


Joao Bregunci (Mar 24 2021 at 17:01):

nce again, I am having a few problems with pattern matching. Here is a minimal working example:

inductive Role (AtomicRole : Type) : Type
  | Atomic  : AtomicRole  Role
  | Compose : Role  Role  Role
  | Inverse : Role  Role

inductive Concept (AtomicConcept AtomicRole : Type) : Type
  | Top           : Concept
  | Bot           : Concept
  | Atomic        : AtomicConcept  Concept
  | Negation      : Concept  Concept
  | Intersection  : Concept  Concept  Concept
  | Union         : Concept  Concept  Concept
  | Some          : (Role AtomicRole)  Concept  Concept
  | Every         : (Role AtomicRole)  Concept  Concept

inductive upper_Label (AC AR : Type) : Type
  | Empty : upper_Label
  | Negation : upper_Label
  | Forall : (Role AR)  Concept AC AR  upper_Label
  | Exist : (Role AR)  Concept AC AR  upper_Label

instance upper_Label_inhabited {AC AR : Type} :
  inhabited (upper_Label AC AR) := inhabited.mk upper_Label.Empty

structure lab_Concept (AC AR: Type) :=
mk :: (roles : list (upper_Label AC AR))
      (concept : Concept AC AR)

def sigma_line {AC AR : Type} : lab_Concept AC AR  upper_Label AC AR   lab_Concept AC AR
  | a upper_Label.Empty           := a
  | a upper_Label.Negation        := lab_Concept.mk (a.roles.tail) (Concept.Negation a.concept)
  | a (upper_Label.Forall RO CO)  := lab_Concept.mk (a.roles.tail) (Concept.Every RO a.concept)
  | a (upper_Label.Exist RO CO)   := lab_Concept.mk (a.roles.tail) (Concept.Some RO a.concept)

def sigma_apply {AC AR : Type} (lc : @lab_Concept AC AR) :=
  sigma_line lc (lc.roles.head)

def sigma_line2 {AC AR : Type} : list (upper_Label AC AR)  lab_Concept AC AR  lab_Concept AC AR
  | [] a := a
  | ls a := sigma_line2 (ls.tail) (sigma_apply a)

def sigma_exhaust {AC AR : Type} (lb : lab_Concept AC AR) :=
  sigma_line2 lab_Concept.roles lab_Concept

I am having problems once again with pattern match in the function sigma_line2. I did read the page on using_well_founded, but I am still finding it extremely confusing on how to solve this issue, since the goal that I have found:

 psigma.lex (λ (a₁ a₂ : list (upper_Label AC AR)), a₁.sizeof < a₂.sizeof)
    (λ (a : list (upper_Label AC AR)) (a₁ a₂ : lab_Concept AC AR),
       lab_Concept.sizeof AC AR a₁ < lab_Concept.sizeof AC AR a₂)
    ls.tail, sigma_apply a
    ls, a

Is not very intuitive. I tried inserting an attribute tag to a few definition before, but to no avail (this solved one previous issue of mine with notations). I think that the problem may be that it doesn't know that the tail of the list is going to be smaller, so that it is well defined the recursion of sigma_line2.

Just a few comments for the code. I have what I call a Concept and lab_Concept is a Concept together with a list of transformations on it. The first two sigma functions goal is to apply the first transformation in the lab_Concept and I only didn't make a single function, because I think that I can't do pattern match with lambdas in Lean 3 (math function in Lean 4). And the other two functions goal is to do all the applications until I get back a Concept.

So, any kind of ideas?

Yakov Pechersky (Mar 24 2021 at 17:08):

def sigma_line2 {AC AR : Type} : list (upper_Label AC AR)  lab_Concept AC AR  lab_Concept AC AR
  | [] a := a
  | (_ :: ls) a := sigma_line2 ls (sigma_apply a)

Yakov Pechersky (Mar 24 2021 at 17:09):

You can do the patterned deconstruction, which will help the equation compiler see that the term is decreasing, as opposed to deferring it into ls.tail and proving that operating on ls.tail decreases

Joao Bregunci (Mar 24 2021 at 17:15):

Awesome, really neat solution, really interesting how the equation compiler can solve this. But if I wanted to prove that these deferring and subsequent applications of tail would there be a more straightforward way? What I mean is making using of using_well_founded. Just asking for learning purposes, since I already stumbled in a similar problem in the past.

Yakov Pechersky (Mar 24 2021 at 17:41):

Something like

def sigma_line2 {AC AR : Type} : list (upper_Label AC AR)  lab_Concept AC AR  lab_Concept AC AR
  | [] a := a
  | ls a := let h := (show sizeof ls.tail < sizeof ls, by sorry) in
    sigma_line2 ls.tail (sigma_apply a)

or something about the using_well_founded { rel_tac := _ }

Yakov Pechersky (Mar 24 2021 at 17:41):

but in general, well-founded recursion definitions have worse computation, so it's not great if you have to rely on it

Yakov Pechersky (Mar 24 2021 at 17:41):

and sizeof ls.tail < sizeof ls isn't actually true, unless ls = (x :: xs) already


Last updated: Dec 20 2023 at 11:08 UTC