metacoq icon indicating copy to clipboard operation
metacoq copied to clipboard

extraction mode: adding level to environment in unquote_universe

Open aa755 opened this issue 6 years ago • 3 comments

There seems to be a discrepancy in how unquote_level is instantiated in extraction mode and in template-coq (live-coq) mode.

The extraction mode implementation is here and looks like:

  let unquote_level (trm : Univ0.Level.t) : Univ.Level.t =
    match trm with
    | Univ0.Level.Coq_lProp -> Univ.Level.prop
    | Univ0.Level.Coq_lSet -> Univ.Level.set
    | Univ0.Level.Level s ->
      let s = unquote_string s in
      let comps = CString.split '.' s in
      let last, dp = CList.sep_last comps in
      let dp = DirPath.make (List.map Id.of_string comps) in
      let idx = int_of_string last in
      Univ.Level.make dp idx
    | Univ0.Level.Var n -> Univ.Level.var (unquote_int n)

Clearly from the types, it does not thread the environment (Evd. evar_map). In contrast, the template-coq version, implemented here, threads the environment and makes a non-trivial change to it (the tLevel case calls get_level which can add a universe to the environment):

let get_level evm s =
  if CString.string_contains ~where:s ~what:"." then
    match List.rev (CString.split '.' s) with
    | [] -> CErrors.anomaly (str"Invalid universe name " ++ str s ++ str".")
    | n :: dp ->
       let num = int_of_string n in
       let dp = DirPath.make (List.map Id.of_string dp) in
       let l = Univ.Level.make dp num in
       try
         let evm = Evd.add_global_univ evm l in
         if !strict_unquote_universe_mode then
           CErrors.user_err ~hdr:"unquote_level" (str ("Level "^s^" is not a declared level and you are in Strict Unquote Universe Mode."))
         else (Feedback.msg_info (str"Fresh universe " ++ Level.pr l ++ str" was added to the context.");
               evm, l)
       with
       | UGraph.AlreadyDeclared -> evm, l
  else
    try
      evm, Evd.universe_of_name evm (Id.of_string s)
    with Not_found ->
         try
           let univ, k = Nametab.locate_universe (Libnames.qualid_of_string s) in
           evm, Univ.Level.make univ k
         with Not_found ->
           CErrors.user_err ~hdr:"unquote_level" (str ("Level "^s^" is not a declared level."))

let unquote_level evm trm (* of type level *) : Evd.evar_map * Univ.Level.t =
  let (h,args) = app_full trm [] in
  if Constr.equal h lProp then
    match args with
    | [] -> evm, Univ.Level.prop
    | _ -> bad_term_verb trm "unquote_level"
  else if Constr.equal h lSet then
    match args with
    | [] -> evm, Univ.Level.set
    | _ -> bad_term_verb trm "unquote_level"
  else if Constr.equal h tLevel then
    match args with
    | s :: [] -> debug (fun () -> str "Unquoting level " ++ pr_constr trm);
                 get_level evm (unquote_string s)
    | _ -> bad_term_verb trm "unquote_level"
  else if Constr.equal h tLevelVar then
    match args with
    | l :: [] -> evm, Univ.Level.var (unquote_nat l)
    | _ -> bad_term_verb trm "unquote_level"
  else
    not_supported_verb trm "unquote_level"

Should the extraction version be fixed to thread/update the context in a similar way?

aa755 avatar Apr 09 '19 16:04 aa755

They should definitely do the same thing.

gmalecha avatar Apr 29 '19 18:04 gmalecha

Yes it should do the same. It might be reasonable to have a strict mode of unquoting where universes cannot be created as well, ensuring reproducible results

mattam82 avatar May 22 '19 16:05 mattam82

To be clear, it should be the second version used in ‘live-coq’

mattam82 avatar May 22 '19 16:05 mattam82