anchor.diff:  
       | Tm_app (h1, args1), Tm_app (h2, args2) ->
         begin match (un_uinst h1).n, (un_uinst h2).n with
  -      | Tm_fvar f1, Tm_fvar f2 when f1.fv_qual = Some Data_ctor && f2.fv_qual = Some Data_ctor ->
  -        equal_data f1 args1 f2 args2
  -
         | Tm_fvar f1, Tm_fvar f2 when fv_eq f1 f2 && List.mem (string_of_lid (lid_of_fv f1)) injectives ->
           equal_data f1 args1 f2 args2
   
  
positive.code:       | Equal -> g()
        | _ -> Unknown
      in
      let equal_data f1 (args1:Syntax.args) f2 (args2:Syntax.args) =
          // we got constructors! we know they are injective and disjoint, so we can do some
          // good analysis on them
          if fv_eq f1 f2
  
negative.code:                                 eq_inj acc (eq_tm a1 a2)) Equal <| List.zip args1 args2
          ) else NotEqual
      in
      let heads_and_args_in_case_both_data :option<(fv * args * fv * args)> =
        let head1, args1 = t1 |> unmeta |> head_and_args in
        let head2, args2 = t2 |> unmeta |> head_and_args in
        match (un_uinst head1).n, (un_uinst head2).n with
        | Tm_fvar f, Tm_fvar g when f.fv_qual = Some Data_ctor &&
                                    g.fv_qual = Some Data_ctor -> Some (f, args1, g, args2)
        | _ -> None
      in
      match (unmeta t1).n, (unmeta t2).n with
      // We sometimes compare open terms, as we get alpha-equivalence
      // for free.
  