Zulip Chat Archive

Stream: general

Topic: correct by construction/or a typing relation


Christopher Upshaw (Aug 08 2021 at 00:44):

So I have been trying to formalize an reversible programing language in lean, and have:

structure ctype := (fst snd : base)

notation x `  `:50 y := (ctype.mk x y : ctype)

inductive pie : ctype  Type
  | atomic {c} : atomic c  pie c
  | comp {a b c} : pie (a  b)  pie (b  c)  pie (a  c)
  | add {a b c d} :  pie (a  b)  pie (c  d)  pie (a + c  b + d)
  | mul {a b c d} :  pie (a  b)  pie (c  d)  pie (a * c  b * d)

But there are two problems here, one composition is only associative up to isomorphism, when I would really like it to be strictly associative.
And two, the bigger problem, defining recursive functions is a real pain because the equation compiler doesn't seem to be able to handle the polymorphic recursion.

Should I keep going on my path of trying to define and prove well founded a subexpression relation?
Or should I make a untyped version, and then define a typing relation on raw expressions?

If I do the second I should be able to replace comp with comp' : list pie -> pie -> pie and make comp an append.

Mario Carneiro (Aug 08 2021 at 00:54):

And two, the bigger problem, defining recursive functions is a real pain because the equation compiler doesn't seem to be able to handle the polymorphic recursion.

Do you have an example of this?

Mario Carneiro (Aug 08 2021 at 00:55):

I would be inclined to go for the untyped version because it's easier to get the equations you want without dependent typing issues

Christopher Upshaw (Aug 08 2021 at 00:58):

Sure!

def pie.inv :  {a b}, pie (a  b)  pie (b  a)
  | a b (pie.atomic atom) := pie.atomic (atom.inv)
  | a b (f >> g) := g.inv >> f.inv
  | a b (f  g) := f.inv  g.inv
  |a b (f  g) := f.inv  g.inv

Gives me the error:

failed to prove recursive application is decreasing, well founded relation
  @has_well_founded.r (Σ' {a b : base}, pie {fst := a, snd := b})
    (@psigma.has_well_founded base (λ {a : base}, Σ' {b : base}, pie {fst := a, snd := b})
       (@has_well_founded_of_has_sizeof base base.has_sizeof_inst)
       (λ (a : base),
          @psigma.has_well_founded base (λ {b : base}, pie {fst := a, snd := b})
            (@has_well_founded_of_has_sizeof base base.has_sizeof_inst)
            (λ (a_1 : base),
               @has_well_founded_of_has_sizeof (pie {fst := a, snd := a_1})
                 (pie.has_sizeof_inst {fst := a, snd := a_1}))))
Possible solutions:
  - Use 'using_well_founded' keyword in the end of your definition to specify tactics for synthesizing well founded relations and decreasing proofs.
  - The default decreasing tactic uses the 'assumption' tactic, thus hints (aka local proofs) can be provided using 'have'-expressions.
The nested exception contains the failure state for the decreasing tactic.
nested exception message:
default_dec_tac failed
state:
pie.inv : Π (_p : Σ' {a b : base}, pie {fst := a, snd := b}), pie {fst := _p.snd.fst, snd := _p.fst},
__mlocal__fresh_75_215 __mlocal__fresh_75_216 __mlocal__fresh_75_217 __mlocal__fresh_75_218 : base,
f : pie {fst := __mlocal__fresh_75_215, snd := __mlocal__fresh_75_216},
g : pie {fst := __mlocal__fresh_75_217, snd := __mlocal__fresh_75_218}
 psigma.lex (λ (a₁ a₂ : base), a₁.sizeof < a₂.sizeof)
    (λ (a : base),
       psigma.lex (λ (a₁ a₂ : base), a₁.sizeof < a₂.sizeof)
         (λ (a_1 : base) (a₁ a₂ : pie {fst := a, snd := a_1}),
            pie.sizeof {fst := a, snd := a_1} a₁ < pie.sizeof {fst := a, snd := a_1} a₂))
    __mlocal__fresh_75_217, __mlocal__fresh_75_218, g⟩⟩
    . (__mlocal__fresh_75_215 + __mlocal__fresh_75_217),
     . (__mlocal__fresh_75_216 + __mlocal__fresh_75_218), fg⟩⟩

Mario Carneiro (Aug 08 2021 at 01:01):

You should try pie : base -> base -> Type


Last updated: Dec 20 2023 at 11:08 UTC