Qcert.Basic.Typing.TOpsInfer


Section TOpsInfer.



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


  Definition tunrecsortable (sl:list string) (τ:rtype) : option rtype.


  Section b.

    Context {fbop:foreign_binary_op}.
    Context {fboptyping:foreign_binary_op_typing}.

    Definition infer_binop_type (b:binOp) (τ τ:rtype) : option rtype :=
      match b with
      | AEq
        if (τ == τ) then Some Bool else None
      | AConcattrecConcat τ τ
      | AMergeConcatlift Coll (tmergeConcat τ τ)
      | AAnd
        match (`τ, `τ) with
        | (Bool₀, Bool₀)Some Bool
        | _None
        end
      | AOr
        match (`τ, `τ) with
        | (Bool₀, Bool₀)Some Bool
        | _None
        end
      | ABArith _
        match (`τ, `τ) with
        | (Nat₀, Nat₀)Some Nat
        | _None
        end
      | ALt | ALe
        match (`τ, `τ) with
        | (Nat₀, Nat₀)Some Bool
        | (_, _)None
        end
      | AUnion | AMinus | AMin | AMax
        match (tuncoll τ, tuncoll τ) with
        | (Some τ₁₀, Some τ₂₀)
          if (`τ₁₀ == `τ₂₀) then Some τ else None
        | _None
        end
      | AContains
        match tuncoll τ with
        | Some τ₂₀
          if (`τ == `τ₂₀) then Some Bool else None
        | NoneNone
        end
      | ASConcat
        match (`τ, `τ) with
        | (String₀, String₀)Some String
        | (_, _)None
        end
      | AForeignBinaryOp fb
        foreign_binary_op_typing_infer fb τ τ
      end.

    Lemma ATConcat_trec τ τout} :
      trecConcat τ τ = Some τout
      binOp_type AConcat τ τ τout.

    Lemma ATMergeConcat_tmerge τ τout} :
      tmergeConcat τ τ = Some τout
      binOp_type AMergeConcat τ τ (Coll τout).

    Theorem infer_binop_type_correct (b:binOp) (τ τ τout:rtype) :
      infer_binop_type b τ τ = Some τout
      binOp_type b τ τ τout.

    Theorem infer_binop_type_least {b:binOp} {τ τ:rtype} {τout₁ τout₂:rtype} :
      infer_binop_type b τ τ = Some τout₁
      binOp_type b τ τ τout₂
      subtype τout₁ τout₂.

    Theorem infer_binop_type_complete {b:binOp} {τ τ:rtype} (τout:rtype) :
      infer_binop_type b τ τ = None
      ¬ binOp_type b τ τ τout.

  End b.


  Section u.
    Context {fuop:foreign_unary_op}.
    Context {fuoptyping:foreign_unary_op_typing}.

    Definition infer_unop_type (u:unaryOp) (τ:rtype) : option rtype :=
      match u with
      | AIdOpSome τ
      | ANeg
        match `τ with
        | Bool₀Some Bool
        | _None
        end
      | ACollSome (Coll τ)
      | ASingletontsingleton τ
      | AFlatten
        match (tuncoll τ) with
        | Some τ₁₀
          match tuncoll τ₁₀ with
          | Some _Some τ₁₀
          | _None
          end
        | NoneNone
        end
      | ADistinct
        olift (fun xSome (Coll x)) (tuncoll τ)
      | AOrderBy sl
        match (tuncoll τ) with
        | Some τ₁₀
          match tunrecsortable (List.map fst sl) τ₁₀ with
          | Some _Some τ
          | NoneNone
          end
        | NoneNone
        end
      | ARec sSome (Rec Closed ((s, τ)::nil) eq_refl)
      | ADot stunrecdot s τ
      | ARecRemove stunrecremove s τ
      | ARecProject sltunrecproject sl τ
      | ACount
        match `τ with
        | Coll₀ _Some Nat
        | _None
        end
      | ASum
      | ANumMin
      | ANumMax
      | AArithMean
        match `τ with
        | Coll₀ Nat₀Some Nat
        | _None
        end
      | AToStringSome String
      | ASubstring _ _
        match `τ with
        | String₀Some String
        | _None
        end
      | ALike _ _
        match `τ with
        | String₀Some Bool
        | _None
        end
      | ALeft
        Some (Either τ )
      | ARight
        Some (Either τ)
      | ABrand b
        if (rtype_eq_dec τ (brands_type b))
        then Some (Brand b)
        else None
      | AUnbrand
        match `τ with
        | Brand₀ bSome (brands_type b)
        | _None
        end
      | ACast b
        match `τ with
        | Brand₀ _Some (Option (Brand b))
        | _None
        end
      | AUArith op
        match `τ with
        | Nat₀Some Nat
        | _None
        end
      | AForeignUnaryOp fu
        foreign_unary_op_typing_infer fu τ
      end.

    Lemma empty_domain_remove {A} (l:list (string × A)) (s:string):
      domain l = nil domain (rremove l s) = nil.

    Lemma sorted_rremove_done {A} (l:list (string×A)) (a:(string×A)) (s:string) :
      is_list_sorted ODT_lt_dec (domain (a::l)) = true
      StringOrder.lt s (fst a)
      domain (rremove (a :: l) s) = domain (a :: l).

    Lemma Forall_rremove {A} {a} {l:list (string × A)} :
      Forall (StringOrder.lt a) (domain l)
       s,
        Forall (StringOrder.lt a) (domain (rremove l s)).

    Lemma is_sorted_rremove {A} (l:list (string × A)) (s:string):
      is_list_sorted ODT_lt_dec (domain l) = true
      is_list_sorted ODT_lt_dec (domain (rremove l s)) = true.

    Lemma ATDot_tunrec {s} {τ τout} :
      tunrecdot s τ = Some τout
      unaryOp_type (ADot s) τ τout.

    Lemma ATRecRemove_tunrec {s} {τ τout} :
      tunrecremove s τ = Some τout
      unaryOp_type (ARecRemove s) τ τout.

    Lemma ATRecProject_tunrec {sl} {τ τout} :
      tunrecproject sl τ = Some τout
      unaryOp_type (ARecProject sl) τ τout.

    Lemma ATOrderBy_tunrec {sl} {τ τout} :
      tunrecsortable (List.map fst sl) τ = Some τout
      unaryOp_type (AOrderBy sl) (Coll τ) (Coll τ).

    Lemma ATSingleton_tsingleton τout} :
      tsingleton τ = Some τout
      unaryOp_type ASingleton τ τout.

    Lemma infer_unop_type_correct (u:unaryOp) (τ τout:rtype) :
      infer_unop_type u τ = Some τout
      unaryOp_type u τ τout.

    Lemma infer_unop_type_least (u:unaryOp) (τ τout₁ τout₂:rtype) :
      infer_unop_type u τ = Some τout₁
      unaryOp_type u τ τout₂
      subtype τout₁ τout₂.

    Lemma infer_unop_type_complete (u:unaryOp) (τ τout:rtype) :
      infer_unop_type u τ = None
      ¬ unaryOp_type u τ τout.

  End u.

End TOpsInfer.