Module Qcert.EJson.Model.EJsonNorm
Require
Import
String
.
Require
Import
List
.
Require
Import
Sumbool
.
Require
Import
Arith
.
Require
Import
Bool
.
Require
Import
EquivDec
.
Require
Import
Assoc
.
Require
Import
Bindings
.
Require
Import
SortingAdd
.
Require
Import
CoqLibAdd
.
Require
Import
ForeignEJson
.
Require
Import
EJson
.
Section
EJsonNorm
.
Context
{
foreign_ejson_model
:
Set
}.
Context
{
fejson
:
foreign_ejson
foreign_ejson_model
}.
Fixpoint
normalize_ejson
(
d
:
ejson
) :
ejson
:=
match
d
with
|
ejobject
rl
=>
ejobject
(
rec_sort
(
map
(
fun
x
=> (
fst
x
,
normalize_ejson
(
snd
x
)))
rl
))
|
ejarray
l
=>
ejarray
(
map
normalize_ejson
l
)
|
ejforeign
fd
=>
ejforeign
(
foreign_ejson_normalize
fd
)
|
_
=>
d
end
.
Inductive
ejson_normalized
:
ejson
->
Prop
:=
|
ejnnull
:
ejson_normalized
ejnull
|
ejnnumber
n
:
ejson_normalized
(
ejnumber
n
)
|
ejnbigint
n
:
ejson_normalized
(
ejbigint
n
)
|
ejnbool
b
:
ejson_normalized
(
ejbool
b
)
|
ejnstring
s
:
ejson_normalized
(
ejstring
s
)
|
ejnarray
dl
:
Forall
(
fun
x
=>
ejson_normalized
x
)
dl
->
ejson_normalized
(
ejarray
dl
)
|
ejnobject
dl
:
Forall
(
fun
d
=>
ejson_normalized
(
snd
d
))
dl
->
(
is_list_sorted
ODT_lt_dec
(
domain
dl
) =
true
) ->
ejson_normalized
(
ejobject
dl
)
|
ejnforeign
fd
:
foreign_ejson_normalized
fd
->
ejson_normalized
(
ejforeign
fd
).
Theorem
ejson_normalize_normalizes
:
forall
(
d
:
ejson
),
ejson_normalized
(
normalize_ejson
d
).
Proof.
induction
d
using
ejsonInd2
;
simpl
.
-
apply
ejnnull
.
-
apply
ejnnumber
.
-
apply
ejnbigint
.
-
apply
ejnbool
.
-
apply
ejnstring
.
-
apply
ejnarray
.
apply
Forall_forall
;
intros
.
induction
c
;
elim
H0
;
intros
.
rewrite
<-
H1
.
apply
(
H
a
);
left
;
reflexivity
.
assert
(
forall
x
:
ejson
,
In
x
c
->
ejson_normalized
(
normalize_ejson
x
))
by
(
intros
;
apply
(
H
x0
);
right
;
assumption
).
specialize
(
IHc
H2
H1
).
assumption
.
-
apply
ejnobject
.
+
apply
Forall_sorted
.
apply
Forall_forall
;
intros
.
induction
r
.
contradiction
.
simpl
in
*.
elim
H0
;
intros
;
clear
H0
.
rewrite
<-
H1
.
simpl
.
apply
(
H
(
fst
a
) (
snd
a
)).
left
;
destruct
a
;
reflexivity
.
assert
(
forall
(
x
:
string
) (
y
:
ejson
),
In
(
x
,
y
)
r
->
ejson_normalized
(
normalize_ejson
y
));
intros
.
apply
(
H
x0
y
);
right
;
assumption
.
apply
(
IHr
H0
).
assumption
.
+
apply
(@
rec_sort_sorted
string
ODT_string
)
with
(
l1
:= (
map
(
fun
x
:
string
*
ejson
=> (
fst
x
,
normalize_ejson
(
snd
x
)))
r
)).
reflexivity
.
-
constructor
.
apply
foreign_ejson_normalize_normalizes
.
Qed.
Theorem
ejson_normalize_normalized_eq
{
d
}:
ejson_normalized
d
->
normalize_ejson
d
=
d
.
Proof.
induction
d
using
ejsonInd2
;
simpl
;
trivial
.
-
intros
.
rewrite
(@
map_eq
_
_
normalize_ejson
id
).
+
rewrite
map_id
;
trivial
.
+
inversion
H0
;
simpl
;
subst
.
revert
H2
.
apply
Forall_impl_in
.
auto
.
-
intros
.
inversion
H0
;
subst
.
rewrite
(@
map_eq
_
_
(
fun
x
:
string
*
ejson
=> (
fst
x
,
normalize_ejson
(
snd
x
)))
id
).
+
rewrite
map_id
.
rewrite
rec_sorted_id
;
trivial
.
+
revert
H2
.
apply
Forall_impl_in
.
destruct
a
;
unfold
id
;
simpl
;
intros
.
f_equal
;
eauto
.
-
inversion
1;
subst
.
f_equal
.
apply
foreign_ejson_normalize_idempotent
.
trivial
.
Qed.
Lemma
ejson_map_normalize_normalized_eq
c
:
Forall
(
fun
x
=>
ejson_normalized
(
snd
x
))
c
->
(
map
(
fun
x0
:
string
*
ejson
=> (
fst
x0
,
normalize_ejson
(
snd
x0
)))
c
) =
c
.
Proof.
induction
c
;
simpl
;
trivial
.
destruct
a
;
inversion
1;
simpl
in
*;
subst
.
rewrite
ejson_normalize_normalized_eq
;
trivial
.
rewrite
IHc
;
trivial
.
Qed.
Corollary
ejson_normalize_idem
d
:
normalize_ejson
(
normalize_ejson
d
) =
normalize_ejson
d
.
Proof.
apply
ejson_normalize_normalized_eq
.
apply
ejson_normalize_normalizes
.
Qed.
Corollary
normalize_ejson_eq_normalized
{
d
} :
normalize_ejson
d
=
d
->
ejson_normalized
d
.
Proof.
intros
.
generalize
(
ejson_normalize_normalizes
d
).
congruence
.
Qed.
Theorem
normalized_ejson_dec
d
: {
ejson_normalized
d
} + {~
ejson_normalized
d
}.
Proof.
destruct
(
normalize_ejson
d
==
d
);
unfold
equiv
,
complement
in
*.
-
left
.
apply
normalize_ejson_eq_normalized
;
trivial
.
-
right
.
intro
dn
;
elim
c
.
apply
ejson_normalize_normalized_eq
;
trivial
.
Defined.
Lemma
ejson_normalized_jarray
a
l
:
(
ejson_normalized
a
/\
ejson_normalized
(
ejarray
l
)) <->
ejson_normalized
(
ejarray
(
a
::
l
)).
Proof.
split
.
-
destruct
1
as
[
d1
d2
].
inversion
d2
;
subst
.
constructor
;
auto
.
-
inversion
1;
subst
.
inversion
H1
;
subst
.
split
;
trivial
.
constructor
;
auto
.
Qed.
Lemma
ejson_normalized_rec_sort_app
l1
l2
:
ejson_normalized
(
ejobject
l1
) ->
ejson_normalized
(
ejobject
l2
) ->
ejson_normalized
(
ejobject
(
rec_sort
(
l1
++
l2
))).
Proof.
inversion
1;
inversion
1;
subst
.
constructor
;
eauto
1
with
qcert
.
apply
Forall_sorted
.
apply
Forall_app
;
trivial
.
Qed.
Lemma
ejson_normalized_rec_concat_sort
l1
l2
:
ejson_normalized
(
ejobject
l1
) ->
ejson_normalized
(
ejobject
l2
) ->
ejson_normalized
(
ejobject
(
rec_concat_sort
l1
l2
)).
Proof.
apply
ejson_normalized_rec_sort_app
.
Qed.
Lemma
ejson_normalized_jarray_in
x
l
:
In
x
l
->
ejson_normalized
(
ejarray
l
) ->
ejson_normalized
x
.
Proof.
inversion
2;
subst
.
rewrite
Forall_forall
in
H2
.
eauto
.
Qed.
Lemma
ejnobject_nil
:
ejson_normalized
(
ejobject
nil
).
Proof.
econstructor
;
trivial
.
Qed.
Lemma
ejnobject_sort_content
c
:
Forall
(
fun
d
:
string
*
ejson
=>
ejson_normalized
(
snd
d
))
c
->
Forall
(
fun
d
:
string
*
ejson
=>
ejson_normalized
(
snd
d
)) (
rec_sort
c
).
Proof.
intros
F
.
apply
Forall_sorted
;
trivial
.
Qed.
Lemma
ejnobject_sort
c
:
Forall
(
fun
d
:
string
*
ejson
=>
ejson_normalized
(
snd
d
))
c
->
ejson_normalized
(
ejobject
(
rec_sort
c
)).
Proof.
intros
F
;
econstructor
;
trivial
with
qcert
.
apply
Forall_sorted
;
trivial
.
Qed.
Lemma
ejson_normalized_jarray_Forall
l
:
ejson_normalized
(
ejarray
l
) <->
Forall
ejson_normalized
l
.
Proof.
split
;
intros
H
.
-
invcs
H
;
trivial
.
-
constructor
;
trivial
.
Qed.
End
EJsonNorm
.