anchor.diff:                                  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.
  
positive.code: 
      | 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
  
  
negative.code:       | Equal -> g()
        | _ -> Unknown
      in
      let equal_data (f1:fv) (args1:Syntax.args) (f2:fv) (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
  