val collect_arr_ln : typ -> list typ * comp
let collect_arr_ln t =
    let bs, c = collect_arr_ln_bs t in
    List.Tot.Base.map type_of_binder bs, c
val collect_arr_ln : typ -> list typ * comp
let collect_arr_ln t =
let bs, c = collect_arr_ln_bs t in
List.Tot.Base.map type_of_binder bs, c
FStar.Reflection.V1.Derived.fst.checked
prims.fst.checked FStar.VConfig.fsti.checked FStar.Reflection.V1.Data.fsti.checked FStar.Reflection.V1.Builtins.fsti.checked FStar.Reflection.Types.fsti.checked FStar.Reflection.Const.fst.checked FStar.Pervasives.Native.fst.checked FStar.Pervasives.fsti.checked FStar.Order.fst.checked FStar.List.Tot.Base.fst.checked
FStar.Reflection.V1.Derived.fst
FStar.Reflection.Types.typ Prims.list FStar.Reflection.Types.binder FStar.Reflection.Types.comp FStar.Pervasives.Native.Mktuple2 FStar.List.Tot.Base.map FStar.Reflection.V1.Derived.type_of_binder FStar.Pervasives.Native.tuple2 FStar.Reflection.V1.Derived.collect_arr_ln_bs
(*
   Copyright 2008-2018 Microsoft Research

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*)
module FStar.Reflection.V1.Derived

open FStar.Reflection.Types
open FStar.Reflection.Const
open FStar.Reflection.V1.Builtins
open FStar.Reflection.V1.Data
open FStar.Order
open FStar.VConfig

let bv_of_binder (b : binder) : bv = (inspect_binder b).binder_bv

let rec inspect_ln_unascribe (t:term) : tv:term_view{tv << t /\ notAscription tv} =
    match inspect_ln t with
    | Tv_AscribedT t' _ _ _
    | Tv_AscribedC t' _ _ _ -> inspect_ln_unascribe t'
    | tv -> tv

(*
 * AR: add versions that take attributes as arguments?
 *)
let mk_binder (bv : bv) (sort : typ) : binder =
  pack_binder {
    binder_bv=bv;
    binder_qual=Q_Explicit;
    binder_attrs=[];
    binder_sort = sort;
  }

let mk_implicit_binder (bv : bv) (sort : typ) : binder =
  pack_binder {
    binder_bv=bv;
    binder_qual=Q_Implicit;
    binder_attrs=[];
    binder_sort = sort;
  }

let type_of_binder (b : binder) : typ =
    (inspect_binder b).binder_sort

val flatten_name : name -> Tot string
let rec flatten_name ns =
    match ns with
    | [] -> ""
    | [n] -> n
    | n::ns -> n ^ "." ^ flatten_name ns

(* Helpers for dealing with nested applications and arrows *)
let rec collect_app_ln' (args : list argv) (t : term) : Tot (term * list argv) (decreases t) =
    match inspect_ln_unascribe t with
    | Tv_App l r ->
        collect_app_ln' (r::args) l
    | _ -> (t, args)

val collect_app_ln : term -> term * list argv
let collect_app_ln = collect_app_ln' []

let rec mk_app (t : term) (args : list argv) : Tot term (decreases args) =
    match args with
    | [] -> t
    | (x::xs) -> mk_app (pack_ln (Tv_App t x)) xs

// Helper for when all arguments are explicit
let mk_e_app (t : term) (args : list term) : Tot term =
    let e t = (t, Q_Explicit) in
    mk_app t (List.Tot.Base.map e args)

let u_unk : universe = pack_universe Uv_Unk

let rec mk_tot_arr_ln (bs: list binder) (cod : term) : Tot term (decreases bs) =
    match bs with
    | [] -> cod
    | (b::bs) -> pack_ln (Tv_Arrow b (pack_comp (C_Total (mk_tot_arr_ln bs cod))))

let rec collect_arr' (bs : list binder) (c : comp) : Tot (list binder * comp) (decreases c) =
    begin match inspect_comp c with
    | C_Total t ->
        begin match inspect_ln_unascribe t with
        | Tv_Arrow b c ->
            collect_arr' (b::bs) c
        | _ ->
            (bs, c)
        end
    | _ -> (bs, c)
    end

val collect_arr_ln_bs : typ -> list binder * comp
let collect_arr_ln_bs t =
    let (bs, c) = collect_arr' [] (pack_comp (C_Total t)) in
    (List.Tot.Base.rev bs, c)
val collect_arr_ln : typ -> list typ * comp
t: FStar.Reflection.Types.typ -> Prims.list FStar.Reflection.Types.typ * FStar.Reflection.Types.comp