[coq] add number notation example
This commit is contained in:
parent
0da344b045
commit
e72f7c7457
|
@ -0,0 +1,57 @@
|
|||
From mathcomp Require Import all_ssreflect all_algebra.
|
||||
|
||||
(* Example from Chapter 8 of mathcomp book *)
|
||||
|
||||
Inductive dir: predArgType :=
|
||||
| South | North | East | West.
|
||||
|
||||
(* dir to an existing ordinal ?? *)
|
||||
Definition d2o (d: dir): 'I_4 :=
|
||||
match d with
|
||||
| South => inord 0
|
||||
| North => inord 1
|
||||
| East => inord 2
|
||||
| West => inord 3
|
||||
end.
|
||||
|
||||
Definition o2d (o: 'I_4): option dir :=
|
||||
match val o with
|
||||
| 0 => Some South
|
||||
| 1 => Some North
|
||||
| 2 => Some East
|
||||
| 3 => Some West
|
||||
| _ => None
|
||||
end.
|
||||
|
||||
(* d2o and o2d cancel out *)
|
||||
Lemma pcan_do4: pcancel d2o o2d.
|
||||
Proof.
|
||||
by case; rewrite /o2d /= inordK.
|
||||
Qed.
|
||||
|
||||
Compute (North \in dir).
|
||||
(* = true : bool *)
|
||||
|
||||
Fail Check (North != South). (* needs EqType *)
|
||||
Fail Check (#| dir | == 4). (* needs FinType *)
|
||||
|
||||
(* Give structure of ordinals to [dir] *)
|
||||
Definition dir_eqMixin := PcanEqMixin pcan_do4.
|
||||
Canonical dir_eqType := EqType dir dir_eqMixin.
|
||||
Check (North != South).
|
||||
(* North != South : bool *)
|
||||
|
||||
(* [CountType] implies [ChoiceType] by the way.
|
||||
Here it's explicitly given though *)
|
||||
Definition dir_choiceMixin := PcanChoiceMixin pcan_do4.
|
||||
Canonical dir_choiceType := ChoiceType dir dir_choiceMixin.
|
||||
|
||||
Definition dir_countMixin := PcanCountMixin pcan_do4.
|
||||
Canonical dir_countType := CountType dir dir_countMixin.
|
||||
|
||||
Definition dir_finMixin := PcanFinMixin pcan_do4.
|
||||
Canonical dir_finType := FinType dir dir_finMixin.
|
||||
Check (#| dir | == 4).
|
||||
(* #|dir| == 4 : bool *)
|
||||
|
||||
Check (North != South) && (North \in dir) && (#| dir | == 4).
|
|
@ -0,0 +1,60 @@
|
|||
(* From https://coq.inria.fr/refman/user-extensions/syntax-extensions.html#number-notations *)
|
||||
|
||||
Inductive radix2: Set :=
|
||||
| x0: radix2
|
||||
| x2p0: radix2 -> radix2
|
||||
| x2p1: radix2 -> radix2.
|
||||
|
||||
Print Decimal.
|
||||
|
||||
Definition of_uint_dec (u : Decimal.uint) : option radix2 :=
|
||||
let fix f u := match u with
|
||||
| Decimal.Nil => Some x0
|
||||
| Decimal.D0 u =>
|
||||
match f u with
|
||||
| Some u => Some (x2p0 u)
|
||||
| None => None
|
||||
end
|
||||
| Decimal.D1 u =>
|
||||
match f u with
|
||||
| Some u => Some (x2p1 u)
|
||||
| None => None
|
||||
end
|
||||
| _ => None end in
|
||||
f (Decimal.rev u).
|
||||
|
||||
Definition of_uint (u : Number.uint) : option radix2 :=
|
||||
match u with
|
||||
| Number.UIntDecimal u => of_uint_dec u
|
||||
| Number.UIntHexadecimal _ => None
|
||||
end.
|
||||
|
||||
(* Printing stuff *)
|
||||
Definition to_uint_dec (x : radix2) : Decimal.uint :=
|
||||
let fix f x :=
|
||||
match x with
|
||||
| x0 => Decimal.Nil
|
||||
| x2p0 x => Decimal.D0 (f x)
|
||||
| x2p1 x => Decimal.D1 (f x)
|
||||
end in
|
||||
Decimal.rev (f x).
|
||||
Definition to_uint (x : radix2) : Number.uint := Number.UIntDecimal (to_uint_dec x).
|
||||
|
||||
Declare Scope radix2_scope.
|
||||
Delimit Scope radix2_scope with r2.
|
||||
Number Notation radix2 of_uint to_uint : radix2_scope.
|
||||
|
||||
Check 01%r2.
|
||||
(* 01%r2 : radix2 *)
|
||||
|
||||
Fail Check 02%r2.
|
||||
(*
|
||||
The command has indeed failed with message:
|
||||
Cannot interpret this number as a value of type radix2
|
||||
*)
|
||||
|
||||
Check (x2p1 x0).
|
||||
(* 1%r2 : radix2 *)
|
||||
|
||||
Check (x2p1 (x2p0 x0)).
|
||||
(* 01%r2 : radix2 *)
|
Loading…
Reference in New Issue