Zulip Chat Archive

Stream: lean4

Topic: dite vs ite


Tomas Skrivan (Jun 03 2023 at 07:09):

What is the purpose of ite if we have dite? Why doesn't normal if statement introduce the hypothesis into the context? I.e. why is normal if statement implemented with ite and not dite?

I am asking because I want to do some rewriting in one of the if branches and if I do not use dite explicitly then tactics do not have access to the if condition.

Yaël Dillies (Jun 03 2023 at 08:07):

if p then a else b is notation for ite p a b. if h : p then a h else b h is notation for dite p a b. Does that answer your question?

Patrick Massot (Jun 03 2023 at 08:11):

I don't think it answers his question. He asks why ite exists at all when it's strictly less powerful than dite.

Patrick Massot (Jun 03 2023 at 08:12):

I'm sure the answer is pretty technical and in an ideal world ite wouldn't exist.

Ruben Van de Velde (Jun 03 2023 at 08:22):

Yeah, I think it comes down to "dite is somewhat more difficult to work with in practice"

Yaël Dillies (Jun 03 2023 at 08:25):

The answer is pretty technical but surely you already know it: non-dependent arguments are much easier to rewrite than dependent ones. At any rate, it sounds like Tomas is looking for a congruency lemma. docs#if_congr isn't quite strong enough as I would have expected it to take p -> x = u and not p -> y = v as arguments instead of x = u and y = v.

Tomas Skrivan (Jun 03 2023 at 10:23):

Yes I'm interested in the technical details. Is there a simple example that demonstrates that working with dite is more difficult than working with ite? Does dite prevent compilers from doing some smart stuff? Something along those lines.

Tomas Skrivan (Jun 03 2023 at 10:36):

One possible argument: ite c x y would be dite c (fun _ => x) (fun _ => y) and applying rewrite x = x' is a bit more difficult as x is under a binder with dite.

Mario Carneiro (Jun 03 2023 at 10:38):

yes, the usual situation is that x has some spurious dependency on the fun _ => variable

Tomas Skrivan (Jun 03 2023 at 10:39):

What do you mean by "spurious dependency"?

Mario Carneiro (Jun 03 2023 at 10:40):

like fun h => Function.const _ x h only less obvious

Mario Carneiro (Jun 03 2023 at 10:40):

I mean, if there is a real dependency on the variable then it's not an ite and it will definitely be harder to rewrite, but you are talking about cases which are "in principle" ite applications, so there shouldn't actually be a dependency

Tomas Skrivan (Jun 03 2023 at 10:41):

But if you write an if statement with ite then there is no dependency, no? Why not convert it immediately to dite without any spurious dependency?

Mario Carneiro (Jun 03 2023 at 10:42):

From the compiler perspective dite is definitely preferred, and it has to bend over backwards to make sure that ite is unfolded to something with a lambda in it

Mario Carneiro (Jun 03 2023 at 10:42):

Tomas Skrivan said:

But if you write an if statement with ite then there is no dependency, no? Why not convert it immediately to dite without any spurious dependency?

After some simplifications and rewrites it may not stay that way

Mario Carneiro (Jun 03 2023 at 10:43):

also, at what stage are you talking about "convert it immediately to dite"? Is ite in the user source?

Mario Carneiro (Jun 03 2023 at 10:43):

is it there at elaboration time?

Mario Carneiro (Jun 03 2023 at 10:45):

Another way to find out the answer to this question BTW would be to change the definition of the if then else syntax in core and try to compile lean

Tomas Skrivan (Jun 03 2023 at 10:45):

Yes probably during elaboration, effectively I'm advocating for getting rid of ite all together

Mario Carneiro (Jun 03 2023 at 10:47):

actually maybe a more controlled place to try it out would be mathlib, just put

macro_rules | `(if $c then $t else $e) => `(if _ : $c then $t else $e)

in Mathlib.Tactic.Basic

Tomas Skrivan (Jun 03 2023 at 10:47):

Mario Carneiro said:

Tomas Skrivan said:

But if you write an if statement with ite then there is no dependency, no? Why not convert it immediately to dite without any spurious dependency?

After some simplifications and rewrites it may not stay that way

Well but I can't do those rewrites and simplifications when using ite in the first place. I would have to convert ite to dite, do the rewrites and then the branches will depend on h. That is ok

Mario Carneiro (Jun 03 2023 at 10:49):

no I mean doing simplifications on a non-dependent lambda might not retain the property of being non-dependent

Mario Carneiro (Jun 03 2023 at 10:49):

and there are things like assumption that might randomly decide to use the variable just because it's there

Tomas Skrivan (Jun 03 2023 at 10:52):

I would be curious if this spurious use is really a problem. My expectation is that giving access to that variable to assumption would allow me to do more desirable rewrites.

Tomas Skrivan (Jun 03 2023 at 10:55):

I'm on the phone right now and I can't test but I'm expecting that if (x != 0) then x/x else 1 does not simplify to 1 but dite version does(or easily can)

Mario Carneiro (Jun 03 2023 at 10:58):

you assume incorrectly

Mario Carneiro (Jun 03 2023 at 10:59):

or at least, it is provably equal to 1 and I don't know whether there is a simp lemma for it

Mario Carneiro (Jun 03 2023 at 11:00):

but you can definitely do conditional rewrites in an ite, this is the docs#if_ctx_congr theorem Yael mentioned before

Tomas Skrivan (Jun 03 2023 at 11:01):

Wouldn't that work if I run simp with assumptiondischarger and add simple simp lemma if _ : c then x else x = x?

Tomas Skrivan (Jun 03 2023 at 11:02):

And mark x != 0 -> x/x = 1 as simp lemma which I do not know if it is done or not

Eric Wieser (Jun 03 2023 at 11:04):

In Lean3 you needed contextual := true to make simp use hypotheses in binders

Mario Carneiro (Jun 03 2023 at 11:04):

lean 4 as well

Tomas Skrivan (Jun 03 2023 at 11:11):

Ok I turn on contextual, then it works right? And there is not much hope doing the same with ite

Mario Carneiro (Jun 03 2023 at 11:12):

there is, you can use contextual congr rules for ite

Mario Carneiro (Jun 03 2023 at 11:12):

like the one I linked

Tomas Skrivan (Jun 03 2023 at 11:21):

Right, but I would have to write my own automation or can I use such congruence lemma with simp?

Mario Carneiro (Jun 03 2023 at 11:22):

there is a @[congr] attribute for these kind of rules

Mario Carneiro (Jun 03 2023 at 11:23):

at least, as long as we are talking about the system we want to see it is not too hard to posit that this is marked up to work as expected

Eric Wieser (Jun 03 2023 at 11:26):

In the same way that finset.sum doesn't include the information that the element is in the set, but docs#finset.sum_congr does

Tomas Skrivan (Jun 03 2023 at 11:52):

Ok, I will look into these congr lemmas, see how they are commonly used and see if I can do what I want.


Last updated: Dec 20 2023 at 11:08 UTC