lambdapi icon indicating copy to clipboard operation
lambdapi copied to clipboard

problem with the apply tactic

Open bodeveix opened this issue 1 year ago • 8 comments

The apply has a strange behaviour when the goal is quantified. In the following proof, apply (λ h, h) lets the goal unchanged as expected. However, if we try to explicitly type the parameter h, the tactic apply fails. When looking at the unification problem, it seems that the universal variable x of the goal is discharged before the unification attempt, which makes it fail.

symbol Prop: TYPE;
symbol π: Prop → TYPE;
symbol Set: TYPE;
constant symbol τ: Set → TYPE;

constant symbol ∀ [a] : (τ a → Prop) → Prop;
notation ∀ quantifier;
rule π (∀ $f) ↪ Π x, π ($f x);

symbol T: Set;
symbol P : τ T → Prop;

symbol bug: π (`∀ (x: τ T), P x) ≔
begin
print;
debug +u;
  apply (λ (h : π (`∀ x: τ T, P x)), h ); // error
//  apply (λ h, h); // correct
print;
  admit;
end;

bodeveix avatar Aug 26 '24 12:08 bodeveix

It seems the problem can be fixed by modifying line 247 of tactic.ml:

    | Some (_, a) -> count_products c a **- count_products c gt.goal_type**     

bodeveix avatar Aug 26 '24 15:08 bodeveix

Hi Jean-Paul. Thanks for your issue, and your suggestion. Note also that in case you have problems with apply, you can always use refine instead. But your tactic call is strange anyway. Your goal is (`∀ x, P x). (λ h, h) cannot be of this type. You can see this if instead you write: refine λ h, h, or perhaps better: refine λ x, x.

fblanqui avatar Aug 26 '24 19:08 fblanqui

Hello Frédéric,

Thanks for your reply.  (λ h, h) was used to make an apply, not a refine. So it should let the goal unchanged. In the original proof, the purpose of

the apply was to change the goal into an equivalent one modulo rewriting rules by giving a type to the parameter h. And yes, I plan to replace apply by refine in the proof generator (from Event-B). In fact, after the suggested fix, apply (λ h, h) fails but apply (λ h: \pi (`∀ x, P x), h) succeeds. So discovering the correct number of parameters is not so easy but Coq succeeds to apply both the generic and the instantiated identity...

Jean-Paul

Le 26 août 2024 à 21:08, Frédéric Blanqui @.***> a écrit :

Hi Jean-Paul. Thanks for your issue, and your suggestion. Note also that in case you have problems with apply, you can always use refine instead. But your tactic call is strange anyway. Your goal is (`∀ x, P x). (λ h, h) cannot be of this type. You can see this if instead you write: refine λ h, h, or perhaps better: refine λ x, x.

— Reply to this email directly, view it on GitHub https://github.com/Deducteam/lambdapi/issues/1131#issuecomment-2310883596, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEH7HKFZRR3JJPVY537LB4LZTN4JVAVCNFSM6AAAAABND4QEP2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJQHA4DGNJZGY. You are receiving this because you authored the thread.

bodeveix avatar Aug 27 '24 06:08 bodeveix

I still don't understand why you would like to do some apply that does not change the goal. And this doesn't correspond to the semantics of (apply t), which is defined as (refine t _ ... _), which consists in instantiating the goal metavariable by (t _ ... _). Trying your suggestion makes other libraries fail, where t is of arity 2 (e.g. ∨ₑ p for some p) and you want (apply t) to be (refine t _ _) whatever the arity of the goal is. It is not clear to me how to define a better version of apply, but PRs are welcome.

fblanqui avatar Aug 27 '24 10:08 fblanqui

I have a definition x <> y := not (x = y) and a goal : \pi (P x y => x <> y) apply (fun (h: \pi (P x y => not (x = y)) => (P x y => x <> y), h) should transform the goal into \pi (P x y => not (x = y)) So even if we apply (an instance of ) the identity fonction, it has a syntactic effect on the goal. It would be possible to use simplify here but the purpose is to obtain exactly what is done by a given Event-B proof step.

Le 27 août 2024 à 12:11, Frédéric Blanqui @.***> a écrit :

I still don't understand why you would like to do some apply that does not change the goal. And this doesn't correspond to the semantics of (apply t), which is defined as (refine t _ ... _), which consists in instantiating the goal metavariable by (t _ ... _). Trying your suggestion makes other libraries fail, where t is of arity 2 (e.g. ∨ₑ p for some p) and you want (apply t) to be (refine t _ _) whatever the arity of the goal is. It is not clear to me how to define a better version of apply, but PRs are welcome.

— Reply to this email directly, view it on GitHub https://github.com/Deducteam/lambdapi/issues/1131#issuecomment-2312111927, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEH7HKGXJHRYEYJCCZAECJLZTRGERAVCNFSM6AAAAABND4QEP2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJSGEYTCOJSG4. You are receiving this because you authored the thread.

bodeveix avatar Aug 27 '24 11:08 bodeveix

Can you send me the failing proof? Thanks.

Le 27 août 2024 à 13:57, Jean-Paul Bodeveix @.***> a écrit :

I have a definition x <> y := not (x = y) and a goal : \pi (P x y => x <> y) apply (fun (h: \pi (P x y => not (x = y)) => (P x y => x <> y), h) should transform the goal into \pi (P x y => not (x = y)) So even if we apply (an instance of ) the identity fonction, it has a syntactic effect on the goal. It would be possible to use simplify here but the purpose is to obtain exactly what is done by a given Event-B proof step.

Le 27 août 2024 à 12:11, Frédéric Blanqui @.*** @.***>> a écrit :

I still don't understand why you would like to do some apply that does not change the goal. And this doesn't correspond to the semantics of (apply t), which is defined as (refine t _ ... _), which consists in instantiating the goal metavariable by (t _ ... _). Trying your suggestion makes other libraries fail, where t is of arity 2 (e.g. ∨ₑ p for some p) and you want (apply t) to be (refine t _ _) whatever the arity of the goal is. It is not clear to me how to define a better version of apply, but PRs are welcome.

— Reply to this email directly, view it on GitHub https://github.com/Deducteam/lambdapi/issues/1131#issuecomment-2312111927, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEH7HKGXJHRYEYJCCZAECJLZTRGERAVCNFSM6AAAAABND4QEP2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJSGEYTCOJSG4. You are receiving this because you authored the thread.

bodeveix avatar Aug 27 '24 12:08 bodeveix

You'll see it if you do make tests: this is in the stdlib.

fblanqui avatar Aug 27 '24 13:08 fblanqui

the purpose of the apply was to change the goal into an equivalent one modulo rewriting rules by giving a type to the parameter h.

Do you mean a type different from the one that is already there but not displayed? To display abstraction domains, use flag "print_domains" on.

apply (λ (h : π (`∀ x: τ T, P x)), h ); apply (λ h:π((Q x y ⇒ not(x = y)) ⇒ (Q x y ⇒ x <> y)), h) (λ z, z)

work with #1279:

symbol Set: TYPE;
constant symbol τ: Set → TYPE;

symbol Prop: TYPE;
symbol π: Prop → TYPE;

constant symbol ∀ [a] : (τ a → Prop) → Prop;
notation ∀ quantifier;
rule π (∀ $f) ↪ Π x, π ($f x);

symbol T: Set;
symbol P : τ T → Prop;

symbol test1: π (`∀ x, P x) ≔
begin
print;
apply λ h, h;
print;
abort;

symbol test2: π (`∀ x, P x) ≔
begin
print;
apply λ h:π(`∀ x:τ T, P x), h;
print;
abort;

symbol not:Prop → Prop;

symbol =: τ T → τ T → Prop;
notation = infix 10;

symbol <> x y ≔ not (x = y);
notation <> infix 10;

symbol ⇒: Prop → Prop → Prop;
notation ⇒ infix 5;
rule π($x ⇒ $y) ↪ π $x → π $y;

symbol Q: τ T → τ T → Prop;

symbol test3 x y: π(Q x y ⇒ x <> y) ≔
begin
assume x y;
print;
apply (λ h:π((Q x y ⇒ not(x = y)) ⇒ (Q x y ⇒ x <> y)), h) (λ z, z);
print;
abort;

fblanqui avatar Jul 02 '25 14:07 fblanqui