问题
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