Module Qcert.EJson.Operators.EJsonGroupBy
Require
Import
List
.
Require
Import
String
.
Require
Import
Utils
.
Require
Import
Bindings
.
Require
Import
ForeignEJson
.
Require
Import
EJson
.
Section
EJsonGroupBy
.
Context
{
foreign_ejson_model
:
Set
}.
Context
{
fejson
:
foreign_ejson
foreign_ejson_model
}.
Import
ListNotations
.
Definition
ejson_key_is_eq_r
(
eval_key
: @
ejson
foreign_ejson_model
->
option
ejson
) (
d1
d2
:@
ejson
foreign_ejson_model
) :
option
bool
:=
olift2
(
fun
x
y
=>
if
ejson_eq_dec
x
y
then
Some
true
else
Some
false
)
(
eval_key
d1
)
(
Some
d2
).
Definition
ejson_group_of_key
(
eval_key
:
ejson
->
option
ejson
) (
k
:
ejson
) (
l
:
list
ejson
) :=
(
lift_filter
(
fun
d
=>
ejson_key_is_eq_r
eval_key
d
k
)
l
).
Definition
ejson_group_by_nested_eval
(
eval_key
:
ejson
->
option
ejson
) (
l
:
list
ejson
) :
option
(
list
(
ejson
* (
list
ejson
))) :=
let
dupkeys
:=
lift_map
(
fun
d
=>
eval_key
d
)
l
in
let
keys
:=
lift
bdistinct
dupkeys
in
olift
(
lift_map
(
fun
k
=>
olift
(
fun
group
=>
Some
(
k
,
group
)) (
ejson_group_of_key
eval_key
k
l
)))
keys
.
Definition
ejson_group_to_partitions
(
g
:
string
) (
group
: @
ejson
foreign_ejson_model
*
list
ejson
) :
option
ejson
:=
match
ejson_is_record
(
fst
group
)
with
|
Some
keys
=>
Some
(
ejobject
(
rec_concat_sort
keys
[(
g
,
ejarray
(
snd
group
))]))
|
_
=>
None
end
.
Definition
ejson_to_partitions
(
g
:
string
) (
l
:
list
(
ejson
*
list
ejson
)) :=
lift_map
(
ejson_group_to_partitions
g
)
l
.
Definition
ejson_group_by_nested_eval_keys_partition
(
g
:
string
) (
eval_keys
:
ejson
->
option
ejson
) (
l
:
list
ejson
) :
option
(
list
ejson
) :=
olift
(
ejson_to_partitions
g
) (
ejson_group_by_nested_eval
eval_keys
l
).
Section
tableform
.
Definition
ejson_group_by_nested_eval_table
(
g
:
string
) (
sl
:
list
string
) (
l
:
list
ejson
) :
option
(
list
ejson
) :=
ejson_group_by_nested_eval_keys_partition
g
(
fun
j
=>
match
ejson_is_record
j
with
|
Some
r
=>
Some
(
ejobject
(
rproject
r
sl
))
|
_
=>
None
end
)
l
.
End
tableform
.
End
EJsonGroupBy
.