Qcert.DNNRC.Typing.TOpsInferSub
Section TOpsInferSub.
Context {fdata:foreign_data}.
Context {ftype:foreign_type}.
Context {fdtyping:foreign_data_typing}.
Context {m:brand_model}.
Section b.
Context {fbop:foreign_binary_op}.
Context {fboptyping:foreign_binary_op_typing}.
Definition infer_binop_type_sub
(b:binOp) (τ₁ τ₂:rtype) : option (rtype×rtype×rtype) :=
match b with
| AEq ⇒
let τcommon := τ₁ ⊔ τ₂ in
Some (Bool, τcommon, τcommon)
| AConcat ⇒
match τ₁ ==b ⊥, τ₂ ==b ⊥ with
| true, true ⇒ Some (⊥, ⊥, ⊥)
| true, false ⇒
lift (fun _ ⇒ (τ₂, ⊥, τ₂)) (tunrec τ₂)
| false, true ⇒
lift (fun _ ⇒ (τ₁, τ₁, ⊥)) (tunrec τ₁)
| false, false ⇒
lift (fun τ ⇒ (τ, τ₁, τ₂)) (trecConcat τ₁ τ₂)
end
| AMergeConcat ⇒
match τ₁ ==b ⊥, τ₂ ==b ⊥ with
| true, true ⇒ Some (Coll ⊥, ⊥, ⊥)
| true, false ⇒
lift (fun _ ⇒ (Coll τ₂, ⊥, τ₂)) (tunrec τ₂)
| false, true ⇒
lift (fun _ ⇒ (Coll τ₁, τ₁, ⊥)) (tunrec τ₁)
| false, false ⇒
lift (fun τ ⇒ (Coll τ, τ₁, τ₂)) (tmergeConcat τ₁ τ₂)
end
| AAnd ⇒
match subtype_dec τ₁ Bool, subtype_dec τ₂ Bool with
| left _, left _ ⇒ Some (Bool, Bool, Bool)
| _, _ ⇒ None
end
| AOr ⇒
match subtype_dec τ₁ Bool, subtype_dec τ₂ Bool with
| left _, left _ ⇒ Some (Bool, Bool, Bool)
| _, _ ⇒ None
end
| ABArith _ ⇒
match subtype_dec τ₁ Nat, subtype_dec τ₂ Nat with
| left _, left _ ⇒ Some (Nat, Nat, Nat)
| _, _ ⇒ None
end
| ALt
| ALe ⇒
match subtype_dec τ₁ Nat, subtype_dec τ₂ Nat with
| left _, left _ ⇒ Some (Bool, Nat, Nat)
| _, _ ⇒ None
end
| AUnion | AMinus | AMin | AMax ⇒
let τcommon := τ₁ ⊔ τ₂ in
if (tuncoll τcommon)
then Some (τcommon, τcommon, τcommon)
else None
| AContains ⇒
if τ₂ ==b ⊥
then Some (Bool, τ₁, τ₂)
else lift (fun τ₂' ⇒
let τ := τ₁ ⊔ τ₂' in
(Bool, τ, Coll τ))
(tuncoll τ₂)
| ASConcat ⇒
match subtype_dec τ₁ String, subtype_dec τ₂ String with
| left _, left _ ⇒ Some (String, String, String)
| _, _ ⇒ None
end
| AForeignBinaryOp fb ⇒
foreign_binary_op_typing_infer_sub fb τ₁ τ₂
end.
End b.
Section u.
Context {fuop:foreign_unary_op}.
Context {fuoptyping:foreign_unary_op_typing}.
Definition infer_unop_type_sub (u:unaryOp) (τ₁:rtype) : option (rtype×rtype) :=
match u with
| AIdOp ⇒ Some (τ₁,τ₁)
| ANeg ⇒
if subtype_dec τ₁ Bool
then Some (Bool, Bool)
else None
| AColl ⇒ Some (Coll τ₁,τ₁)
| ASingleton ⇒
let τ₁' := τ₁ ⊔ (Coll ⊥) in
lift (fun τ ⇒ (τ, τ₁')) (tsingleton τ₁')
| AFlatten ⇒
let τ₁' := τ₁ ⊔ (Coll (Coll ⊥)) in
bind (tuncoll τ₁')
(fun τ₁in ⇒
lift (fun _ ⇒ (τ₁in, τ₁'))
(tuncoll τ₁in))
| ADistinct ⇒
let τ₁' := τ₁ ⊔ (Coll ⊥) in
lift (fun τ ⇒ (Coll τ, τ₁')) (tuncoll τ₁')
| AOrderBy sl ⇒
let τ₁' := τ₁ ⊔ (Coll ⊥) in
match (tuncoll τ₁') with
| Some τ₁₀ ⇒
match tunrecsortable (List.map fst sl) τ₁₀ with
| Some _ ⇒ Some (τ₁', τ₁')
| None ⇒ None
end
| None ⇒ None
end
| ARec s ⇒ Some (Rec Closed ((s, τ₁)::nil) eq_refl, τ₁)
| ADot s ⇒
if τ₁ == ⊥
then Some (⊥, ⊥)
else lift (fun τ ⇒ (τ, τ₁)) (tunrecdot s τ₁)
| ARecRemove s ⇒
if τ₁ == ⊥
then Some (⊥, ⊥)
else lift (fun τ ⇒ (τ, τ₁)) (tunrecremove s τ₁)
| ARecProject sl ⇒
if τ₁ == ⊥
then Some (⊥, ⊥)
else lift (fun τ ⇒ (τ, τ₁)) (tunrecproject sl τ₁)
| ACount ⇒
let τ₁' := τ₁ ⊔ (Coll ⊥) in
lift (fun τ ⇒ (Nat, τ₁')) (tuncoll τ₁')
| ASum
| ANumMin
| ANumMax
| AArithMean ⇒
if subtype_dec τ₁ (Coll Nat)
then Some (Nat, Coll Nat)
else None
| AToString ⇒
Some (String, τ₁)
| ASubstring _ _ ⇒
if (subtype_dec τ₁ String)
then Some (String, String)
else None
| ALike _ _ ⇒
if (subtype_dec τ₁ String)
then Some (Bool, String)
else None
| ALeft ⇒
Some (Either τ₁ ⊥, τ₁)
| ARight ⇒
Some (Either ⊥ τ₁, τ₁)
| ABrand b ⇒
if (subtype_dec τ₁ (brands_type b))
then Some (Brand b, τ₁)
else None
| AUnbrand ⇒
if τ₁ == ⊥
then
Some (⊥, ⊥)
else
match `τ₁ with
| Brand₀ b ⇒ Some (brands_type b, τ₁)
| _ ⇒ None
end
| ACast b ⇒
if τ₁ == ⊥
then
Some (⊥, ⊥)
else
match `τ₁ with
| Brand₀ _ ⇒ Some (Option (Brand b), τ₁)
| _ ⇒ None
end
| AUArith op ⇒
if subtype_dec τ₁ Nat
then Some (Nat, Nat)
else None
| AForeignUnaryOp fu ⇒
foreign_unary_op_typing_infer_sub fu τ₁
end.
End u.
End TOpsInferSub.