(How) can I define partial coercions in Coq?

心不动则不痛 提交于 2019-12-10 22:31:07

问题


I want to set Coq up, without redefining the : with a notation (and without a plugin, and without replacing the standard library or redefining the constants I'm using---no cheating like that), so that I have something like a partial coercion from option nat to nat, which is defined only on Some _. In particular, I want

Eval compute in Some 0 : nat.

to evaluate to 0, and I want

Check None : nat.

to raise an error.


The closest I've managed is the ability to do this with two :s:

Definition dummy {A} (x : option A) := A.
Definition inverted_option {A} (x : option A)
  := match x with Some _ => A | _ => True end.
Definition invert_Some {A} (x : option A) : inverted_option x
  := match x with Some v => v | None => I end.
Coercion invert_Some : option >-> inverted_option.
Notation nat' := (inverted_option (A:=nat) (Some _)).
Eval compute in (Some 0 : nat') : nat.
Check (None : nat') : nat.
(* The term "None" has type "option ?A" while it is expected to have type
 "nat'". *)

However, this only works when nat' is a notation, and I can't define a coercion out of a notation. (And trying to define a coercion from inverted_option (Some _) to nat violated the uniform inheritance condition.) I thought I might be able to get around this issue by using canonical structures, but I haven't managed to figure out how to interleave canonical structure resolution with coercion insertion (see also Can canonical structure resolution be interleaved with coercion insertion?).

(I ran into this issue when attempting to answer Coq: Defining a subtype.)

来源:https://stackoverflow.com/questions/46147643/how-can-i-define-partial-coercions-in-coq

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!