let ok_to_replace_with_incdec curiosh defiosh f id vi r =

  (* number of uses of vi where definition id reaches *)
  let num_uses () =
    let _ = useList := [] in
    let ulc = new useListerClass id vi in
    let _ = visitCilFunction (ulc :> cilVisitor) f in
    List.length (!useList)
  in

  (* Is e the addition or subtraction of one to vi?
     Return Some(PlusA) if it's an addition,
     Some(MinusA) if it's a subtraction,
     and None otherwise *)

  let inc_or_dec e vi =
    match e.enode with
      BinOp((PlusA|PlusPI|IndexPI),
            {enode = Lval(Var vi', NoOffset)},
            {enode = Const(CInt64(one,_,_))},_) ->
              if vi.vid = vi'.vid && one = Int64.one
              then Some(PlusA)
              else if vi.vid = vi'.vid && one = Int64.minus_one
              then Some(MinusA)
              else None
    | BinOp((MinusA|MinusPI),
            {enode = Lval(Var vi', NoOffset)},
            {enode = Const(CInt64(one,_,_))},_) ->
              if vi.vid = vi'.vid && one = Int64.one
              then Some(MinusA)
              else None
    | _ -> None
  in

  match r with
    RD.RDExp({enode = Lval(Var rhsvi, NoOffset)}) ->
      let curido = RD.iosh_singleton_lookup curiosh rhsvi in
      let defido = RD.iosh_singleton_lookup defiosh rhsvi in
      (match  curido, defido with
        Some(curid), _ ->
          let defios = try IH.find defiosh rhsvi.vid
          with Not_found -> RD.IOS.empty in
          let redefrhso = getDefRhs curid in
          (match redefrhso with
            None -> (if !debug then (Cilmsg.debug "ok_to_replace: couldn't get rhs for redef: %d" curid);
                     None)
          | Some(redefrhs, _, redefiosh) ->
              let tmprdido = RD.iosh_singleton_lookup redefiosh vi in
              match tmprdido with
                None -> (if !debug then (Cilmsg.debug "ok_to_replace: conflicting defs of %s reach redef of %s" vi.vname rhsvi.vname);
                         None)
              | Some tmprdid ->
                  if not (tmprdid = id) then
                    (if !debug then (Cilmsg.debug "ok_to_replace: initial def of %s doesn't reach redef of %s" vi.vname rhsvi.vname);
                     None)
                  else let redefios = try IH.find redefiosh rhsvi.vid
                  with Not_found -> RD.IOS.empty in
                  let curdef_stmt =
                    try IH.find RD.ReachingDef.defIdStmtHash curid
                    with Not_found ->
                      Cilmsg.fatal "ok_to_replace: couldn't find statement defining %d" curid in
                  if not (RD.IOS.compare defios redefios = 0) then
                    (if !debug then
                       (Cilmsg.debug
                          "ok_to_replace: different sets of definitions of %s reach the def of %s and the redef of %s"
                          rhsvi.vname
                          vi.vname
                          rhsvi.vname);
                     None)
                  else
                    (match redefrhs with
                      RD.RDExp(e) -> (match inc_or_dec e rhsvi with
                        Some(PlusA->
                          if num_uses () = 1 then
                            Some(curdef_stmt.sid, curid, rhsvi, PlusA)
                          else (if !debug then (Cilmsg.debug "ok_to_replace: tmp used more than once");
                                None)
                      | Some(MinusA->
                          if num_uses () = 1 then
                            Some(curdef_stmt.sid, curid, rhsvi, MinusA)
                          else (if !debug then (Cilmsg.debug "ok_to_replace: tmp used more than once");
                                None)
                      | None ->
                          (if !debug then (Cilmsg.debug "ok_to_replace: redef isn't adding or subtracting one from itself");
                           None)
                      | _ -> (Cilmsg.fatal "ok_to_replace: unexpected op in inc/dec info."))
                    | _ -> (if !debug then (Cilmsg.debug "ok_to_replace: redef a call");
                            None)))
      | _ -> (if !debug then (Cilmsg.debug "ok_to_replace: %s has conflicting definitions" rhsvi.vname);
              None))
  | _ -> (if !debug then (Cilmsg.debug "ok_to_replace: rhs not of correct form");
          None)