Qcert.NNRC.Typing.TcNNRCInfer


Section TcNNRCInfer.




  Context {m:basic_model}.

Type inference for NNRC when given the type of the environment


  Fixpoint infer_nnrc_type (tenv:tbindings) (n:nnrc) {struct n} : option rtype :=
    match n with
    | NNRCVar v
      lookup equiv_dec tenv v
    | NNRCConst dinfer_data_type (normalize_data brand_relation_brands d)
    | NNRCBinop b n1 n2
      let binf τ:rtype) := infer_binop_type b τ τ in
      olift2 binf (infer_nnrc_type tenv n1) (infer_nnrc_type tenv n2)
    | NNRCUnop u n1
        let unf:rtype) := infer_unop_type u τ in
        olift unf (infer_nnrc_type tenv n1)
    | NNRCLet v n1 n2
      let τ := infer_nnrc_type tenv n1 in
      let let_infer τ := infer_nnrc_type ((v,τ)::tenv) n2 in
      olift let_infer τ
    | NNRCFor v n1 n2
      let τ := infer_nnrc_type tenv n1 in
      let for_infer τ := lift Coll (infer_nnrc_type ((v,τ)::tenv) n2) in
      olift for_infer (olift tuncoll τ)
    | NNRCIf n0 n1 n2
      match infer_nnrc_type tenv n0 with
      | Some τ
        match `τ with
        | Bool₀
          let oτ := infer_nnrc_type tenv n1 in
          let oτ := infer_nnrc_type tenv n2 in
          match (oτ, oτ) with
            | (Some τ, Some τ)
              if (rtype_eq_dec τ τ)
              then Some τ
              else None
            | (_, _)None
          end
        | _None
        end
      | NoneNone
      end
    | NNRCEither n0 v1 n1 v2 n2
      match olift tuneither (infer_nnrc_type tenv n0) with
      | Some (τl, τr)
          let oτ := infer_nnrc_type ((v1,τl)::tenv) n1 in
          let oτ := infer_nnrc_type ((v2,τr)::tenv) n2 in
          match (oτ, oτ) with
            | (Some τ, Some τ)
              if (rtype_eq_dec τ τ)
              then Some τ
              else None
            | (_, _)None
          end
      | _None
      end
    | NNRCGroupBy g sl n1
      None
    end.

  Lemma infer_nnrc_type_correctout} (tenv:tbindings) (n:nnrc) :
    infer_nnrc_type tenv n = Some τout
    nnrc_type tenv n τout.

End TcNNRCInfer.