Qcert.NRA.Typing.TNRAInfer


Section TNRAInfer.




Type inference for NRA when given the type of the input



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

    Definition tmapConcatInput: rtype) : option (list (string×rtype)).

    Definition tmapConcatOutput : list (string×rtype)) (τ: rtype) : option rtype.

  End aux.


  Context {m:basic_model}.

  Fixpoint infer_nra_type (e:nra) (τin:rtype) : option rtype :=
    match e with
      | AIDSome τin
      | AConst dinfer_data_type (normalize_data brand_relation_brands d)
      | ABinop b op1 op2
        let binf τ:rtype) := infer_binop_type b τ τ in
        olift2 binf (infer_nra_type op1 τin) (infer_nra_type op2 τin)
      | AUnop u op1
        let unf:rtype) := infer_unop_type u τ in
        olift unf (infer_nra_type op1 τin)
      | AMap op1 op2
        let mapf:rtype) :=
            olift (fun xlift (fun yColl y) (infer_nra_type op1 x)) (tuncoll τ)
        in
        olift mapf (infer_nra_type op2 τin)
      | AMapConcat op1 op2
        let mapconcatf:list (string×rtype)) :=
            match RecMaybe Closed τ with
              | NoneNone
              | Some τr₁
                match olift (tmapConcatOutput τ) (infer_nra_type op1 τr₁) with
                  | NoneNone
                  | Some τSome (Coll τ)
                end
            end
        in
        olift mapconcatf (olift tmapConcatInput (infer_nra_type op2 τin))
      | AProduct op1 op2
        let mapconcatf:list (string×rtype)) :=
            match RecMaybe Closed τ with
              | NoneNone
              | Some τr₁
                match olift (tmapConcatOutput τ) (infer_nra_type op2 τin) with
                  | NoneNone
                  | Some τSome (Coll τ)
                end
            end
        in
        olift mapconcatf (olift tmapConcatInput (infer_nra_type op1 τin))
      | ASelect op1 op2
        let selectf:rtype) :=
            match tuncoll τ with
              | Some τ₁'
                match infer_nra_type op1 τ₁' with
                  | Some τ
                    match `τ with
                      | Bool₀Some (Coll τ₁')
                      | _None
                    end
                  | NoneNone
                end
              | NoneNone
            end
        in
        olift selectf (infer_nra_type op2 τin)
      | ADefault op1 op2
        match ((infer_nra_type op1 τin), (infer_nra_type op2 τin)) with
            | (Some τ₁', Some τ₂')
              match (tuncoll τ₁', tuncoll τ₂') with
                | (Some τ₁₀, Some τ₂₀)
                  if (`τ₁₀ == `τ₂₀) then Some τ₁' else None
                | _None
              end
            | (_, _)None
        end
      | AEither op1 op2
        match tuneither τin with
        | Some (τl, τr)
          match ((infer_nra_type op1 τl), (infer_nra_type op2 τr)) with
          | (Some τ₁', Some τ₂')
            if (rtype_eq_dec τ₁' τ₂')
            then Some τ₁'
            else None
          | (_, _)None
          end
        | _None
        end
      | AEitherConcat op1 op2
        match (infer_nra_type op1 τin, infer_nra_type op2 τin) with
        | (Some τeither, Some τrecplus)
          match tuneither τeither with
          | Some (τl, τr)
            match (trecConcat τl τrecplus, trecConcat τr τrecplus) with
            | (Some τrecl, Some τrecr)
              Some (Either τrecl τrecr)
            | (_, _)None
            end
          | NoneNone
          end
        | (_, _)None
        end
      | AApp op1 op2
        let appf:rtype) := infer_nra_type op1 τ in
        olift appf (infer_nra_type op2 τin)
    end.

  Lemma infer_nra_type_correctin τout:rtype) (e:nra) :
    infer_nra_type e τin = Some τout
    nra_type e τin τout.


End TNRAInfer.