Skip to content
Snippets Groups Projects
Commit 1855e425 authored by Robbert Krebbers's avatar Robbert Krebbers
Browse files

Fix `pretty` for `N`.

This fix is inspired by iris/stdpp!198.
parent 1b559061
No related branches found
No related tags found
1 merge request!200Pretty-print 0 as "0" for N, Z, and nat
...@@ -4,11 +4,16 @@ From Coq Require Import Ascii. ...@@ -4,11 +4,16 @@ From Coq Require Import Ascii.
From stdpp Require Import options. From stdpp Require Import options.
Class Pretty A := pretty : A string. Class Pretty A := pretty : A string.
Definition pretty_N_char (x : N) : ascii := Definition pretty_N_char (x : N) : ascii :=
match x with match x with
| 0 => "0" | 1 => "1" | 2 => "2" | 3 => "3" | 4 => "4" | 0 => "0" | 1 => "1" | 2 => "2" | 3 => "3" | 4 => "4"
| 5 => "5" | 6 => "6" | 7 => "7" | 8 => "8" | _ => "9" | 5 => "5" | 6 => "6" | 7 => "7" | 8 => "8" | _ => "9"
end%char%N. end%char%N.
Lemma pretty_N_char_inj x y :
(x < 10)%N (y < 10)%N pretty_N_char x = pretty_N_char y x = y.
Proof. compute; intros. by repeat (discriminate || case_match). Qed.
Fixpoint pretty_N_go_help (x : N) (acc : Acc (<)%N x) (s : string) : string := Fixpoint pretty_N_go_help (x : N) (acc : Acc (<)%N x) (s : string) : string :=
match decide (0 < x)%N with match decide (0 < x)%N with
| left H => pretty_N_go_help (x `div` 10)%N | left H => pretty_N_go_help (x `div` 10)%N
...@@ -18,6 +23,9 @@ Fixpoint pretty_N_go_help (x : N) (acc : Acc (<)%N x) (s : string) : string := ...@@ -18,6 +23,9 @@ Fixpoint pretty_N_go_help (x : N) (acc : Acc (<)%N x) (s : string) : string :=
end. end.
Definition pretty_N_go (x : N) : string string := Definition pretty_N_go (x : N) : string string :=
pretty_N_go_help x (wf_guard 32 N.lt_wf_0 x). pretty_N_go_help x (wf_guard 32 N.lt_wf_0 x).
Instance pretty_N : Pretty N := λ x,
if decide (x = 0)%N then "0" else pretty_N_go x "".
Lemma pretty_N_go_0 s : pretty_N_go 0 s = s. Lemma pretty_N_go_0 s : pretty_N_go 0 s = s.
Proof. done. Qed. Proof. done. Qed.
Lemma pretty_N_go_help_irrel x acc1 acc2 s : Lemma pretty_N_go_help_irrel x acc1 acc2 s :
...@@ -31,22 +39,34 @@ Lemma pretty_N_go_step x s : ...@@ -31,22 +39,34 @@ Lemma pretty_N_go_step x s :
= pretty_N_go (x `div` 10) (String (pretty_N_char (x `mod` 10)) s). = pretty_N_go (x `div` 10) (String (pretty_N_char (x `mod` 10)) s).
Proof. Proof.
unfold pretty_N_go; intros; destruct (wf_guard 32 N.lt_wf_0 x). unfold pretty_N_go; intros; destruct (wf_guard 32 N.lt_wf_0 x).
destruct wf_guard. (* this makes coqchk happy. *) destruct (wf_guard _ _). (* this makes coqchk happy. *)
unfold pretty_N_go_help at 1; fold pretty_N_go_help. unfold pretty_N_go_help at 1; fold pretty_N_go_help.
by destruct (decide (0 < x)%N); auto using pretty_N_go_help_irrel. by destruct (decide (0 < x)%N); auto using pretty_N_go_help_irrel.
Qed. Qed.
Instance pretty_N : Pretty N := λ x, pretty_N_go x ""%string.
Lemma pretty_N_unfold x : pretty x = pretty_N_go x "". Lemma pretty_N_go_ne_0 x s : s "0" pretty_N_go x s "0".
Proof. done. Qed. Proof.
revert s. induction (N.lt_wf_0 x) as [x _ IH]; intros s ?.
assert (x = 0 0 < x < 10 10 x)%N as [->|[[??]|?]] by lia.
- by rewrite pretty_N_go_0.
- rewrite pretty_N_go_step by done. apply IH.
{ by apply N.div_lt. }
assert (x = 1 x = 2 x = 3 x = 4 x = 5 x = 6
x = 7 x = 8 x = 9)%N by lia; naive_solver.
- rewrite 2!pretty_N_go_step by (try apply N.div_str_pos_iff; lia).
apply IH; [|done].
trans (x `div` 10)%N; apply N.div_lt; auto using N.div_str_pos with lia.
Qed.
Instance pretty_N_inj : Inj (=@{N}) (=) pretty. Instance pretty_N_inj : Inj (=@{N}) (=) pretty.
Proof. Proof.
assert ( x y, x < 10 y < 10
pretty_N_char x = pretty_N_char y x = y)%N.
{ compute; intros. by repeat (discriminate || case_match). }
cut ( x y s s', pretty_N_go x s = pretty_N_go y s' cut ( x y s s', pretty_N_go x s = pretty_N_go y s'
String.length s = String.length s' x = y s = s'). String.length s = String.length s' x = y s = s').
{ intros help x y Hp. { intros help x y. unfold pretty, pretty_N. intros.
eapply (help x y "" ""); [by rewrite <-!pretty_N_unfold|done]. } repeat case_decide; simplify_eq/=; [done|..].
- by destruct (pretty_N_go_ne_0 y "").
- by destruct (pretty_N_go_ne_0 x "").
- by apply (help x y "" ""). }
assert ( x s, ¬String.length (pretty_N_go x s) < String.length s) as help. assert ( x s, ¬String.length (pretty_N_go x s) < String.length s) as help.
{ setoid_rewrite <-Nat.le_ngt. { setoid_rewrite <-Nat.le_ngt.
intros x; induction (N.lt_wf_0 x) as [x _ IH]; intros s. intros x; induction (N.lt_wf_0 x) as [x _ IH]; intros s.
...@@ -57,18 +77,21 @@ Proof. ...@@ -57,18 +77,21 @@ Proof.
assert ((x = 0 0 < x) (y = 0 0 < y))%N as [[->|?] [->|?]] by lia; assert ((x = 0 0 < x) (y = 0 0 < y))%N as [[->|?] [->|?]] by lia;
rewrite ?pretty_N_go_0, ?pretty_N_go_step, ?(pretty_N_go_step y) by done. rewrite ?pretty_N_go_0, ?pretty_N_go_step, ?(pretty_N_go_step y) by done.
{ done. } { done. }
{ intros -> Hlen; edestruct help; rewrite Hlen; simpl; lia. } { intros -> Hlen. edestruct help; rewrite Hlen; simpl; lia. }
{ intros <- Hlen; edestruct help; rewrite <-Hlen; simpl; lia. } { intros <- Hlen. edestruct help; rewrite <-Hlen; simpl; lia. }
intros Hs Hlen; apply IH in Hs; destruct Hs; intros Hs Hlen.
simplify_eq/=; split_and?; auto using N.div_lt_upper_bound with lia. apply IH in Hs as [? [= Hchar]];
rewrite (N.div_mod x 10), (N.div_mod y 10) by done. [|auto using N.div_lt_upper_bound with lia|simpl; lia].
auto using N.mod_lt with f_equal. split; [|done].
apply pretty_N_char_inj in Hchar; [|by auto using N.mod_lt..].
rewrite (N.div_mod x 10), (N.div_mod y 10) by done. lia.
Qed. Qed.
Instance pretty_Z : Pretty Z := λ x, Instance pretty_Z : Pretty Z := λ x,
match x with match x with
| Z0 => "" | Zpos x => pretty (Npos x) | Zneg x => "-" +:+ pretty (Npos x) | Z0 => "" | Zpos x => pretty (Npos x) | Zneg x => "-" +:+ pretty (Npos x)
end%string. end%string.
Instance pretty_nat : Pretty nat := λ x, pretty (N.of_nat x). Instance pretty_nat : Pretty nat := λ x, pretty (N.of_nat x).
Instance pretty_nat_inj : Inj (=@{nat}) (=) pretty. Instance pretty_nat_inj : Inj (=@{nat}) (=) pretty.
Proof. apply _. Qed. Proof. apply _. Qed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment