Hello
When executing:
Require Import String.
From MetaCoq.Template Require Import utils All.
MetaCoq Run (tmQuote BinInt.Z.add >>= tmPrint).
it is quoted as BinIntDef.Z.add
. As far as I understand the Include
command, BinIntDef.Z.add
is however syntactically different from BinInt.Z.add
, isn't it?
This is tested with Coq 8.13 and Metacoq 1.0~beta2+8.13.
Thanks!
My understanding also is that they are syntactically different, for instance Check BinInt.Z.add = BinIntDef.Z.add.
yields not the exactly same printout on the left and right side. However, the two are convertible, and this even holds for inductive types obtained through Include
. I guess that MetaCoq somewhere does a little bit too much unfolding when quoting, the bug also seems present in more up-to-date versions. @Tan Yee Jian is currently revamping all of the quoting of modules, we can probably resolve this issue as part of the re-design
they are syntactically equal
Require Import String.
Goal False.
constr_eq BinInt.Z.add BinIntDef.Z.add. (* succeeds *)
Locate
can also help to figure these things out: Locate BinInt.Z.add
yields:
Constant Coq.ZArith.BinInt.Z.add (shorter name to refer to it in current context is Z.add) (alias of BinIntDef.Z.add)
So Include
does not create a copy, but an alias?
How do we recognize such aliases in MetaCoq? And in OCaml?
in ocaml it is the difference between Constant.canonical and Constant.user
How can I check that two econstr
are equal in the sense of the tactic constr_eq
?
Tactics.constr_eq ~strict:false
I guess you want to do it in MetaCoq @Chantal Keller ? Then you might be able to use the technique described here, just simplified a little: https://github.com/MetaCoq/metacoq/wiki/Calling-Ltac-from-the-TemplateMonad
From MetaCoq.Template Require Import All.
From MetaCoq Require Import bytestring.
Require Import List.
Import MCMonadNotation ListNotations.
Open Scope bs.
(* Definitions that can be outsourced to a central file *)
MetaCoq Run (tmCurrentModPath tt >>= tmDefinition "solve_ltac_mp").
Definition solve_ltac (tac : string) {args : Type} (a : args) (Goal : Type) := Goal.
Existing Class solve_ltac.
Definition tmDef name {A} a := @tmDefinitionRed name (Some (unfold (solve_ltac_mp, "solve_ltac"))) A a.
(* Local definition adding a new tactic *)
Hint Extern 0 (solve_ltac "tauto" tt _) => unfold solve_ltac; tauto : typeclass_instances.
Hint Extern 0 (solve_ltac "constr_eq" (?x, ?y) _) => constr_eq x y; exact tt : typeclass_instances.
(* Calling this tactic from the monad *)
Require Import String.
From MetaCoq.Template Require Import utils All.
MetaCoq Run (tmQuote BinInt.Z.add >>= tmPrint).
MetaCoq Run (res <- tmInferInstance None (solve_ltac "constr_eq" (BinInt.Z.add, BinIntDef.Z.add) unit) ;;
match res with
| my_Some _ => tmPrint "equal!"
| my_None => tmFail "not equal"
end).
Fail MetaCoq Run (res <- tmInferInstance None (solve_ltac "constr_eq" (fun x : nat => S x, fun x : nat => x + 1) unit) ;;
match res with
| my_Some _ => tmPrint "equal!"
| my_None => tmFail "not equal"
end).
Right now MetaCoq does not consider the aliasing status: I think it only produces entries/references to canonical names
Thanks to all of you, that is very clear now :-)
Last updated: May 31 2023 at 02:31 UTC