anchor.diff:          (Print.term_to_string t)))
     | Tm_match _ ->
         raise (Err (Util.format1 "Tm_match is outside of the definition language: %s"
  -        (Print.term_to_string t)))
  -  | Tm_ascribed _ ->
  -      raise (Err (Util.format1 "Tm_ascribed is outside of the definition language: %s"
           (Print.term_to_string t)))
     | Tm_let _ ->
         raise (Err (Util.format1 "Tm_let is outside of the definition language: %s"
  
positive.code:   | Tm_app (head, args) ->
        // Sums and products. TODO: re-use the cache in [env] to not recompute
        // (st a)* every time.
        let is_valid_application head =
          match (SS.compress head).n with
          | Tm_fvar fv when (
            // TODO: implement a better check (non-dependent, user-defined data type)
            fv_eq_lid fv Const.option_lid ||
            fv_eq_lid fv Const.either_lid ||
            is_tuple_constructor (SS.compress head)
          ) ->
              true
          | Tm_uinst _ ->
              failwith "impossible (Tm_uinst)"
          | _ ->
              false
        in
        if is_valid_application head then
          mk (Tm_app (head, List.map (fun (t, qual) -> star_type' env t, qual) args))
        else
          raise (Err (Util.format1 "For now, only [either] and [option] are \
            supported in the definition language (got: %s)"
              (Print.term_to_string t)))
  
  
negative.code:         { bv with sort = star_type' env bv.sort }, aqual
        ) binders in
        (* Catch the GTotal case early; it seems relatively innocuous to allow
         * GTotal to appear. TODO fix this as a clean, single pattern-matching. *)
        begin match t.n with
        | Tm_arrow (_, { n = GTotal (hn, _) }) ->
            mk (Tm_arrow (binders, mk_GTotal (star_type' env hn)))
  