Qcert.Basic.Typing.TDataInfer


Section TDataInfer.




  Context {fdata:foreign_data}.
  Context {ftype:foreign_type}.
  Context {fdtyping:foreign_data_typing}.

  Context {m:brand_model}.

  Fixpoint infer_data_type (d:data) : option rtype
    := match d with
         | dunitSome Unit
         | dnat nSome Nat
         | dbool bSome Bool
         | dstring sSome String
         | dcoll ld
           lift Coll
                ((fix infer_data_type_dcoll ld : option rtype
                  := match ld with
                       | nilSome
                       | d::ld'lift2 join (infer_data_type d) (infer_data_type_dcoll ld')
                     end
                 ) ld)
         | drec lsd
           match (fix infer_data_type_drec lsd : option (list(string×rtype))
                  := match lsd with
                       | nilSome nil
                       | (s,d)::lsd'
                         match (infer_data_type d), (infer_data_type_drec lsd') with
                           | Some r, Some lsr'
                             Some ((s,r)::lsr')
                           | _, _None
                         end
                     end
                 ) lsd with
             | Some lRecMaybe Closed l
             | NoneNone
           end
         | dleft d
            lift (fun tEither t ) (infer_data_type d)
         | dright d
            lift (fun tEither t) (infer_data_type d)
         | dbrand b d
           match is_canon_brands_dec brand_relation_brands b with
              | left pfmatch infer_data_type d with
                           | Some t
                             if subtype_dec t (brands_type b)
                             then Some (Brand b)
                             else Some
                  | NoneNone
                end
              | right _None
           end
         | dforeign dflift Foreign (foreign_data_typing_infer df)
       end.

  Lemma infer_data_type_drec_domain {d:list (string×data)} {r'} :
    (fix infer_data_type_drec lsd : option (list(string×rtype))
                  := match lsd with
                       | nilSome nil
                       | (s,d)::lsd'
                         match (infer_data_type d), (infer_data_type_drec lsd') with
                           | Some r, Some lsr'
                             Some ((s,r)::lsr')
                           | _, _None
                         end
                     end
                 ) d = Some r'
     domain d = domain r'.

  Lemma infer_data_type_normalized' {d} :
    data_normalized brand_relation_brands d
    {τ | infer_data_type d = Some τ}.

  Theorem infer_data_type_normalized {d} :
    data_normalized brand_relation_brands d
    {τ | infer_data_type d = Some τ}.

  Theorem infer_data_type_correct {d τ} :
    infer_data_type d = Some τ
    d τ.

  Theorem infer_data_type_least {d τ τ} :
    infer_data_type d = Some τ
    d τ
    τ <: τ.

  Theorem infer_data_type_complete {d τ} :
    d τ {τ' | infer_data_type d = Some τ'}.

  Lemma normalized_data_type_infer {d τ} :
    infer_data_type d = Some τ
    data_normalized brand_relation_brands d.


  Section dt_dec.
We can compute if the data_type relation holds using by seeing if its inferred type (if any) is a subtype of the given type.
    Theorem data_type_dec d τ : {data_type d τ} + {¬ data_type d τ}.
  End dt_dec.

End TDataInfer.