anchor.diff:    let rec pairwise r l =
       match l with
         [] -> true
  -    | h::t -> forall (r h) t & pairwise r t in
  +    | h::t -> forall (r h) t && pairwise r t
     let rec pfrees ptm acc =
       match ptm with
         Varp(v,pty) ->
           if v = "" & pty = dpty then acc
  -        else if can get_const_type v or can num_of_string v
  -                or exists (fun (w,_) -> v = w) (!the_interface) then acc
  +        elif can get_const_type v or can num_of_string v or exists (fun (w,_) -> v = w) (!the_interface) then acc
           else insert ptm acc
       | Constp(_,_) -> acc
       | Combp(p1,p2) -> pfrees p1 (pfrees p2 acc)
       | Absp(p1,p2) -> subtract (pfrees p2 acc) (pfrees p1 [])
  -    | Typing(p,_) -> pfrees p acc in
  -  let pdest_eq (Combp(Combp(Varp(("="|"<=>"),_),l),r)) = l,r in
  +    | Typing(p,_) -> pfrees p acc
  +  let pdest_eq (Combp(Combp(Varp(("="|"<=>"),_),l),r)) = l,r
     let pmk_let (letbindings,body) =
  -    let vars,tms = unzip (map pdest_eq letbindings) in
  -    let _ = warn(not
  -     (pairwise (fun s t -> intersect(pfrees s []) (pfrees t []) = []) vars))
  -     "duplicate names on left of let-binding: latest is used" in
  -    let lend = Combp(Varp("LET_END",dpty),body) in
  -    let abs = itlist (fun v t -> Absp(v,t)) vars lend in
  -    let labs = Combp(Varp("LET",dpty),abs) in
  -    rev_itlist (fun x f -> Combp(f,x)) tms labs in
  +    let vars,tms = unzip (map pdest_eq letbindings)
  +    let _ = warn(not (pairwise (fun s t -> intersect(pfrees s []) (pfrees t []) = []) vars)) "duplicate names on left of let-binding: latest is used"
  +    let lend = Combp(Varp("LET_END",dpty),body)
  +    let abs = itlist (fun v t -> Absp(v,t)) vars lend
  +    let labs = Combp(Varp("LET",dpty),abs)
  +    rev_itlist (fun x f -> Combp(f,x)) tms labs
     let pmk_vbinder(n,v,bod) =
       if n = "\\" then Absp(v,bod)
  -    else Combp(Varp(n,dpty),Absp(v,bod)) in
  -  let pmk_binder(n,vs,bod) =
  -    itlist (fun v b -> pmk_vbinder(n,v,b)) vs bod in
  -  let pmk_set_enum ptms =
  -    itlist (fun x t -> Combp(Combp(Varp("INSERT",dpty),x),t)) ptms
  -           (Varp("EMPTY",dpty)) in
  +    else Combp(Varp(n,dpty),Absp(v,bod))
  +  let pmk_binder(n,vs,bod) = itlist (fun v b -> pmk_vbinder(n,v,b)) vs bod
  +  let pmk_set_enum ptms = itlist (fun x t -> Combp(Combp(Varp("INSERT",dpty),x),t)) ptms (Varp("EMPTY",dpty))
     let pgenvar =
  -    let gcounter = ref 0 in
  -    fun () -> let count = !gcounter in
  -              (gcounter := count + 1;
  -               Varp("GEN%PVAR%"^(string_of_int count),dpty)) in
  -  let pmk_exists(v,ptm) = Combp(Varp("?",dpty),Absp(v,ptm)) in
  -  let pmk_list els =
  -    itlist (fun x y -> Combp(Combp(Varp("CONS",dpty),x),y))
  -           els (Varp("NIL",dpty)) in
  +    let gcounter = ref 0
  +    fun () ->
  +        let count = !gcounter
  +        gcounter := count + 1
  +        Varp("GEN%PVAR%"^(string_of_int count),dpty)
  +  let pmk_exists(v,ptm) = Combp(Varp("?",dpty),Absp(v,ptm))
  +  let pmk_list els = itlist (fun x y -> Combp(Combp(Varp("CONS",dpty),x),y)) els (Varp("NIL",dpty))
     let pmk_bool =
  -    let tt = Varp("T",dpty) and ff = Varp("F",dpty) in
  -    fun b -> if b then tt else ff in
  +    let tt = Varp("T",dpty)
  +    let ff = Varp("F",dpty)
  +    fun b ->
  +        if b then tt else ff
     let pmk_char c =
  -    let lis = map (fun i -> pmk_bool((c / (1 lsl i)) mod 2 = 1)) (0--7) in
  -    itlist (fun x y -> Combp(y,x)) lis (Varp("ASCII",dpty)) in
  +    let lis = map (fun i -> pmk_bool((c / (1 <<< i)) % 2 = 1)) (0--7)
  +    itlist (fun x y -> Combp(y,x)) lis (Varp("ASCII",dpty))
     let pmk_string s =
  -    let ns = map (fun i -> Char.code(String.get s i))
  -                 (0--(String.length s - 1)) in
  -    pmk_list(map pmk_char ns) in
  +    let ns = map (fun i -> Char.code(String.get s i)) (0--(String.length s - 1))
  +    pmk_list(map pmk_char ns)
     let pmk_setcompr (fabs,bvs,babs) =
  -    let v = pgenvar() in
  -    let bod = itlist (curry pmk_exists) bvs
  -                     (Combp(Combp(Combp(Varp("SETSPEC",dpty),v),babs),fabs)) in
  -    Combp(Varp("GSPEC",dpty),Absp(v,bod)) in
  +    let v = pgenvar()
  +    let bod = itlist (curry pmk_exists) bvs (Combp(Combp(Combp(Varp("SETSPEC",dpty),v),babs),fabs))
  +    Combp(Varp("GSPEC",dpty),Absp(v,bod))
     let pmk_setabs (fabs,babs) =
       let evs =
         let fvs = pfrees fabs []
  -      and bvs = pfrees babs [] in
  +      let bvs = pfrees babs []
         if length fvs <= 1 or bvs = [] then fvs
  -      else intersect fvs bvs in
  -    pmk_setcompr (fabs,evs,babs) in
  +      else intersect fvs bvs
  +    pmk_setcompr (fabs,evs,babs)
     let rec mk_precedence infxs prs inp =
       match infxs with
         (s,(p,at))::_ ->
  -          let topins,rest = partition (fun (s',pat') -> pat' = (p,at)) infxs in
  +          let topins,rest = partition (fun (s',pat') -> pat' = (p,at)) infxs
             (if at = "right" then rightbin else leftbin)
             (mk_precedence rest prs)
             (end_itlist (||) (map (fun (s,_) -> a (Ident s)) topins))
  -          (fun (Ident op) x y -> Combp(Combp(Varp(op,dpty),x),y))
  -          ("term after binary operator")
  -          inp
  +          (fun (Ident op) x y -> Combp(Combp(Varp(op,dpty),x),y)) "term after binary operator" inp
       | _ -> prs inp in
  -  let pmk_geq s t = Combp(Combp(Varp("GEQ",dpty),s),t) in
  +  let pmk_geq s t = Combp(Combp(Varp("GEQ",dpty),s),t)
     let pmk_pattern ((pat,guards),res) =
  -    let x = pgenvar() and y = pgenvar() in
  +    let x = pgenvar() && y = pgenvar() in
       let vs = pfrees pat []
  -    and bod =
  +    let bod =
        if guards = [] then
  -       Combp(Combp(Varp("_UNGUARDED_PATTERN",dpty),pmk_geq pat x),
  -             pmk_geq res y)
  +       Combp(Combp(Varp("_UNGUARDED_PATTERN",dpty),pmk_geq pat x), pmk_geq res y)
        else
  -       Combp(Combp(Combp(Varp("_GUARDED_PATTERN",dpty),pmk_geq pat x),
  -                   hd guards),
  -             pmk_geq res y) in
  +       Combp(Combp(Combp(Varp("_GUARDED_PATTERN",dpty),pmk_geq pat x), hd guards), pmk_geq res y)
       Absp(x,Absp(y,itlist (curry pmk_exists) vs bod)) in
     let pretype = parse_pretype
  -  and string inp =
  +  let rec string inp =
       match inp with
  -      Ident s::rst when String.length s >= 2 &
  -                        String.sub s 0 1 = "\"" &
  +      Ident s::rst when String.length s >= 2 &&
  +                        String.sub s 0 1 = "\"" &&
                           String.sub s (String.length s - 1) 1 = "\""
          -> String.sub s 1 (String.length s - 2),rst
       | _ -> raise Noparse
  
positive.code:   || a (Resword "(") ++
       (any_identifier >> (fun s -> Varp(s,dpty))) ++
       a (Resword ")")
      >> (snd o fst)
    || a (Resword "(") ++
       preterm ++
       a (Resword ")")
      >> (snd o fst)
    || a (Resword "if") ++
       preterm ++
       a (Resword "then") ++
  
negative.code: /// Lexical analyzer, type and preterm parsers.
  module NHol.parser
  
  open NHol.lib
  open NHol.preterm
  
  (*
  
  (* ------------------------------------------------------------------------- *)
  (* Need to have this now for set enums, since "," isn't a reserved word.     *)
  (* ------------------------------------------------------------------------- *)
  
  // https://github.com/gilith/hol-light/blob/master/Help/parse_as_infix.doc
  // parse_as_infix : string * (int * string) -> unit
  parse_as_infix (",",(14,"right"))
  
  (* ------------------------------------------------------------------------- *)
  (* Basic parser combinators.                                                 *)
  (* ------------------------------------------------------------------------- *)
  
  exception Noparse
  
  let (||) parser1 parser2 input =
      try parser1 input
      with Noparse -> parser2 input
  
  let (++) parser1 parser2 input =
      let result1, rest1 = parser1 input
      let result2, rest2 = parser2 rest1
      (result1, result2), rest2
  
  let rec many prs input =
      try
          let result, next = prs input
          let results, rest = many prs next
          (result :: results), rest
      with Noparse ->
          [],input
  
  let (>>) prs treatment input =
      let result,rest = prs input
      treatment result, rest
  
  let fix err prs input =
      try prs input
      with Noparse ->
          failwith (err ^ " expected")
  
  let rec listof prs sep err =
      prs ++ many (sep ++ fix err prs >> snd) >> (fun (h, t) -> h :: t)
  
  let nothing input = [], input
  
  let elistof prs sep err =
      listof prs sep err || nothing;;
  
  let leftbin prs sep cons err =
      prs ++ many (sep ++ fix err prs) >>
      (fun (x,opxs) ->
          let ops, xs = unzip opxs
          itlist2 (fun op y x -> cons op x y) (rev ops) (rev xs) x);;
  
  let rightbin prs sep cons err =
      prs ++ many (sep ++ fix err prs) >>
      (fun (x, opxs) ->
          if opxs = [] then x
          else
              let ops, xs = unzip opxs
              itlist2 cons ops (x::butlast xs) (last xs))
  
  let possibly prs input =
      try
          let x, rest = prs input
          [x], rest
      with Noparse ->
          [],input
  
  let some p = function
      | [] -> raise Noparse
      | h :: t ->
          if p h then h, t
          else raise Noparse
  
  let a tok = some (fun item -> item = tok)
  
  let rec atleast n prs i =
      (if n <= 0 then many prs
       else prs ++ atleast (n - 1) prs >> (fun (h,t) -> h :: t)) i
  
  let finished input =
      if input = [] then 0, input
      else failwith "Unparsed input"
  
  (* ------------------------------------------------------------------------- *)
  (* The basic lexical classes: identifiers, strings and reserved words.       *)
  (* ------------------------------------------------------------------------- *)
  
  type lexcode =
      | Ident of string
      | Resword of string
  
  (* ------------------------------------------------------------------------- *)
  (* Lexical analyzer. Apart from some special bracket symbols, each           *)
  