Module ErgoSpec.Backend.Lib.QType
Require Import String.
Require Import List.
Require Import Qcert.Utils.Utils.
Require Import Qcert.Data.DataSystem.
Require Import QBackendModel.
Require Import QBackendRuntime.
Require Import ErgoSpec.Backend.Qcert.QcertModel.
Module QType(
ergomodel:
QBackendModel).
Definition empty_brand_model (
x:
unit) :=
TBrandModel.empty_brand_model.
Definition record_kind :
Set
:=
RType.record_kind.
Definition open_kind :
record_kind
:=
RType.Open.
Definition closed_kind :
record_kind
:=
RType.Closed.
Definition ectype_struct {
br:
brand_relation} :
Set
:=
RType.rtype₀.
Definition ectype {
br:
brand_relation} :
Set
:=
RType.rtype.
Definition t {
br:
brand_relation} :
Set
:=
ectype.
Definition sorted_pf_type {
br:
brand_relation}
srl
:=
SortingAdd.is_list_sorted Bindings.ODT_lt_dec (@
Assoc.domain String.string ectype srl) =
true.
Definition tbottom {
br:
brand_relation} :
ectype
:=
RType.Bottom.
Definition ttop {
br:
brand_relation} :
ectype
:=
RType.Top.
Definition tunit {
br:
brand_relation} :
ectype
:=
RType.Unit.
Definition tfloat {
br:
brand_relation} :
ectype
:=
RType.Float.
Definition tnat {
br:
brand_relation} :
ectype
:=
RType.Nat.
Definition tbool {
br:
brand_relation} :
ectype
:=
RType.Bool.
Definition tstring {
br:
brand_relation} :
ectype
:=
RType.String.
Definition tdateTimeFormat {
br:
brand_relation} :
ectype
:=
DateTimeFormat.
Definition tdateTime {
br:
brand_relation} :
ectype
:=
DateTime.
Definition tduration {
br:
brand_relation} :
ectype
:=
DateTimeDuration.
Definition tperiod {
br:
brand_relation} :
ectype
:=
DateTimePeriod.
Definition tcoll {
br:
brand_relation} :
ectype ->
ectype
:=
RType.Coll.
Definition trec {
br:
brand_relation} :
record_kind ->
forall (
r:
list (
String.string*
ectype)),
sorted_pf_type r ->
ectype
:=
RType.Rec.
Definition teither {
br:
brand_relation} :
ectype ->
ectype ->
ectype
:=
RType.Either.
Definition tarrow {
br:
brand_relation} :
ectype ->
ectype ->
ectype
:=
RType.Arrow.
Definition tbrand {
br:
brand_relation} :
list String.string ->
ectype
:=
RType.Brand.
Definition toption {
br:
brand_relation} :
ectype ->
ectype
:=
RType.Option.
Definition ergoc_type_meet {
br:
brand_relation} :
ectype ->
ectype ->
ectype :=
rtype_meet.
Definition ergoc_type_join {
br:
brand_relation} :
ectype ->
ectype ->
ectype :=
rtype_join.
Definition ergoc_type_subtype {
br:
brand_relation} :
ectype ->
ectype ->
Prop :=
subtype.
Theorem ergoc_type_subtype_dec {
m:
brand_model} (
t1 t2:
ectype) :
{
ergoc_type_subtype t1 t2} + {~
ergoc_type_subtype t1 t2}.
Proof.
Definition untcoll {
m:
brand_model} :
ectype ->
option ectype :=
tuncoll.
Definition unteither {
m:
brand_model} :
ectype ->
option (
ectype *
ectype) :=
tuneither.
Definition untrec {
m:
brand_model} :
ectype ->
option (
record_kind * (
list (
string *
ectype))) :=
tunrec.
Definition ergoc_type_infer_data {
m:
brand_model} :
data ->
Datatypes.option ectype :=
infer_data_type.
Definition ergoc_type_infer_binary_op {
m:
brand_model} :
binary_op ->
ectype ->
ectype ->
option (
ectype *
ectype *
ectype) :=
infer_binary_op_type_sub.
Definition ergoc_type_infer_unary_op {
m:
brand_model} :
unary_op ->
ectype ->
option (
ectype *
ectype) :=
infer_unary_op_type_sub.
Definition unpack_ergoc_type {
br:
brand_relation} (
t:
ectype) :
ectype_struct :=
proj1_sig t.
Definition tbrand_relation :
Set :=
brand_relation.
Definition tempty_brand_relation :
tbrand_relation :=
mkBrand_relation nil (
eq_refl _) (
eq_refl _).
Definition mk_tbrand_relation :
list (
string *
string) ->
qresult tbrand_relation :=
Schema.mk_brand_relation.
Definition tbrand_context_decls {
br:
brand_relation} :
Set :=
brand_context_decls.
Definition tbrand_context {
br:
brand_relation} :
Set :=
brand_context.
Definition mk_tbrand_context {
br:
brand_relation} :
tbrand_context_decls ->
tbrand_context :=
@
mk_brand_context _ br.
Definition tbrand_model :
Set :=
brand_model.
Definition mk_tbrand_model {
br:
brand_relation} :
tbrand_context_decls ->
qresult tbrand_model :=
@
Schema.make_brand_model_from_decls_fails _ _ br.
Program Definition tempty_brand_model :
tbrand_model :=
@
make_brand_model _ tempty_brand_relation (
mkBrand_context nil _)
_.
Definition ergoc_type_unpack {
br:
brand_relation} (
t:
ectype) :
ectype_struct :=
proj1_sig t.
Program Definition ergoc_closed_from_open {
m:
brand_model} (
t:
ectype) :
ectype :=
match untrec t with
|
None =>
t
|
Some (
k,
fields) =>
Rec Closed fields _
end.
Next Obligation.
assert (
untrec t0 =
Some (
k,
fields))
by auto;
clear Heq_anonymous.
generalize (
tunrec_correct k t0 H);
intros.
elim H0;
clear H0;
intros.
auto.
Qed.
Definition infer_brand_strict {
m:
brand_model} (
b:
brands) (
t:
ectype) :
option (
rtype *
ectype) :=
if (
subtype_dec t (
ergoc_closed_from_open (
brands_type b)))
then Some (
Brand b,
t)
else None.
Definition recminus {
br:
brand_relation} (
rt:
list (
string*
rtype)) (
sl:
list string) :
list (
string*
rtype) :=
fold_left rremove sl rt.
Definition diff_record_types {
m:
brand_model} (
b:
brands) (
t:
ectype) :
option (
list string *
list string) :=
match tunrec t with
|
None =>
None
|
Some (
_,
actual_rt) =>
match tunrec (
ergoc_closed_from_open (
brands_type b))
with
|
None =>
None
|
Some (
_,
expected_rt) =>
let in_expected_not_in_actual :=
recminus expected_rt (
map fst actual_rt)
in
let in_actual_not_in_expected :=
recminus actual_rt (
map fst expected_rt)
in
Some (
map fst in_expected_not_in_actual,
map fst in_actual_not_in_expected)
end
end.
Fixpoint rec_fields_that_are_not_subtype {
m:
brand_model} (
t1 t2:
list (
string*
ectype)) :
list (
string *
ectype *
ectype) :=
match t1,
t2 with
|
nil,
_ =>
nil
|
_,
nil =>
nil
| (
name1,
t1)::
rest1, (
name2,
t2)::
rest2 =>
if string_dec name1 name2
then
if subtype_dec t2 t1
then
rec_fields_that_are_not_subtype rest1 rest2
else
(
name1,
t1,
t2) ::
rec_fields_that_are_not_subtype rest1 rest2
else
rec_fields_that_are_not_subtype rest1 rest2
end.
Definition fields_that_are_not_subtype {
m:
brand_model} (
b:
brands) (
t:
ectype) :
list (
string *
ectype *
ectype) :=
match tunrec t with
|
None =>
nil
|
Some (
_,
actual_rt) =>
match tunrec (
ergoc_closed_from_open (
brands_type b))
with
|
None =>
nil
|
Some (
_,
expected_rt) =>
rec_fields_that_are_not_subtype expected_rt actual_rt
end
end.
End QType.