Module Qcert.JSON.Model.JSONNorm
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
JSON
.
Section
JSONNorm
.
Fixpoint
normalize_json
(
d
:
json
) :
json
:=
match
d
with
|
jobject
rl
=>
jobject
(
rec_sort
(
map
(
fun
x
=> (
fst
x
,
normalize_json
(
snd
x
)))
rl
))
|
jarray
l
=>
jarray
(
map
normalize_json
l
)
|
_
=>
d
end
.
Inductive
json_normalized
:
json
->
Prop
:=
|
jnnull
:
json_normalized
jnull
|
jnnumber
n
:
json_normalized
(
jnumber
n
)
|
jnbool
b
:
json_normalized
(
jbool
b
)
|
jnstring
s
:
json_normalized
(
jstring
s
)
|
jnarray
dl
:
Forall
(
fun
x
=>
json_normalized
x
)
dl
->
json_normalized
(
jarray
dl
)
|
jnobject
dl
:
Forall
(
fun
d
=>
json_normalized
(
snd
d
))
dl
->
(
is_list_sorted
ODT_lt_dec
(
domain
dl
) =
true
) ->
json_normalized
(
jobject
dl
).
Theorem
normalize_normalizes
:
forall
(
d
:
json
),
json_normalized
(
normalize_json
d
).
Proof.
induction
d
using
jsonInd2
;
simpl
.
-
apply
jnnull
.
-
apply
jnnumber
.
-
apply
jnbool
.
-
apply
jnstring
.
-
apply
jnarray
.
apply
Forall_forall
;
intros
.
induction
c
;
elim
H0
;
intros
.
rewrite
<-
H1
.
apply
(
H
a
);
left
;
reflexivity
.
assert
(
forall
x
:
json
,
In
x
c
->
json_normalized
(
normalize_json
x
))
by
(
intros
;
apply
(
H
x0
);
right
;
assumption
).
specialize
(
IHc
H2
H1
).
assumption
.
-
apply
jnobject
.
+
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
:
json
),
In
(
x
,
y
)
r
->
json_normalized
(
normalize_json
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
*
json
=> (
fst
x
,
normalize_json
(
snd
x
)))
r
)).
reflexivity
.
Qed.
Theorem
normalize_normalized_eq
{
d
}:
json_normalized
d
->
normalize_json
d
=
d
.
Proof.
induction
d
using
jsonInd2
;
simpl
;
trivial
.
-
intros
.
rewrite
(@
map_eq
_
_
normalize_json
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
*
json
=> (
fst
x
,
normalize_json
(
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
.
Qed.
Lemma
map_normalize_normalized_eq
c
:
Forall
(
fun
x
=>
json_normalized
(
snd
x
))
c
->
(
map
(
fun
x0
:
string
*
json
=> (
fst
x0
,
normalize_json
(
snd
x0
)))
c
) =
c
.
Proof.
induction
c
;
simpl
;
trivial
.
destruct
a
;
inversion
1;
simpl
in
*;
subst
.
rewrite
normalize_normalized_eq
;
trivial
.
rewrite
IHc
;
trivial
.
Qed.
Corollary
normalize_idem
d
:
normalize_json
(
normalize_json
d
) =
normalize_json
d
.
Proof.
apply
normalize_normalized_eq
.
apply
normalize_normalizes
.
Qed.
Corollary
normalize_json_eq_normalized
{
d
} :
normalize_json
d
=
d
->
json_normalized
d
.
Proof.
intros
.
generalize
(
normalize_normalizes
d
).
congruence
.
Qed.
Theorem
normalized_json_dec
d
: {
json_normalized
d
} + {~
json_normalized
d
}.
Proof.
destruct
(
normalize_json
d
==
d
);
unfold
equiv
,
complement
in
*.
-
left
.
apply
normalize_json_eq_normalized
;
trivial
.
-
right
.
intro
dn
;
elim
c
.
apply
normalize_normalized_eq
;
trivial
.
Defined.
Lemma
json_normalized_jarray
a
l
:
(
json_normalized
a
/\
json_normalized
(
jarray
l
)) <->
json_normalized
(
jarray
(
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
json_normalized_rec_sort_app
l1
l2
:
json_normalized
(
jobject
l1
) ->
json_normalized
(
jobject
l2
) ->
json_normalized
(
jobject
(
rec_sort
(
l1
++
l2
))).
Proof.
inversion
1;
inversion
1;
subst
.
constructor
;
eauto
1
with
qcert
.
apply
Forall_sorted
.
apply
Forall_app
;
trivial
.
Qed.
Lemma
json_normalized_rec_concat_sort
l1
l2
:
json_normalized
(
jobject
l1
) ->
json_normalized
(
jobject
l2
) ->
json_normalized
(
jobject
(
rec_concat_sort
l1
l2
)).
Proof.
apply
json_normalized_rec_sort_app
.
Qed.
Lemma
json_normalized_jarray_in
x
l
:
In
x
l
->
json_normalized
(
jarray
l
) ->
json_normalized
x
.
Proof.
inversion
2;
subst
.
rewrite
Forall_forall
in
H2
.
eauto
.
Qed.
Lemma
jnobject_nil
:
json_normalized
(
jobject
nil
).
Proof.
econstructor
;
trivial
.
Qed.
Lemma
jnobject_sort_content
c
:
Forall
(
fun
d
:
string
*
json
=>
json_normalized
(
snd
d
))
c
->
Forall
(
fun
d
:
string
*
json
=>
json_normalized
(
snd
d
)) (
rec_sort
c
).
Proof.
intros
F
.
apply
Forall_sorted
;
trivial
.
Qed.
Lemma
jnobject_sort
c
:
Forall
(
fun
d
:
string
*
json
=>
json_normalized
(
snd
d
))
c
->
json_normalized
(
jobject
(
rec_sort
c
)).
Proof.
intros
F
;
econstructor
;
trivial
with
qcert
.
apply
Forall_sorted
;
trivial
.
Qed.
Lemma
json_normalized_jarray_Forall
l
:
json_normalized
(
jarray
l
) <->
Forall
json_normalized
l
.
Proof.
split
;
intros
H
.
-
invcs
H
;
trivial
.
-
constructor
;
trivial
.
Qed.
End
JSONNorm
.