let pred_of_condition subst subst_res label cond =
  let mk_func_event f =
    let op = tat (mk_term_from_vi (get_varinfo curOp),label) in
      (* [VP] TODO: change int to appropriate enum type. Also true
         elsewhere.
       *)

    let f = term (TConst (func_to_cenum f)) (Ctype (func_enum_type ())) in
    prel (Req,op,f)
  in
  let mk_func_status f status =
    let curr = tat (mk_term_from_vi (get_varinfo curOpStatus),label) in
    let call =
      term (TConst (op_status_to_cenum status)) (Ctype (status_enum_type()))
    in Logic_const.pand (mk_func_event f, prel(Req,curr,call))
  in
  let mk_func_start f = mk_func_status f Promelaast.Call in
  let mk_func_return f = mk_func_status f Promelaast.Return in
  let rec aux kf pos = function
    | TOr(c1,c2) ->
      kf, Logic_const.por (snd (aux kf pos c1), snd (aux kf pos c2))
    | TAnd(c1,c2) ->
      let kf, c1 = aux kf pos c1 in
      let kf, c2 = aux kf pos c2 in
      kf, Logic_const.pand (c1, c2)
    | TNot c -> let kf, c = aux kf (not pos) c in kf, Logic_const.pnot c
    | TCall (s,b) ->
      let pred = mk_func_start (Kernel_function.get_name s) in
      let pred = 
        match b with
          | None -> pred
          | Some b ->
            Logic_const.pands
              (pred :: 
                 (List.map 
                    Logic_utils.named_of_identified_predicate b.b_assumes))
      in
      kf, pred
    | TReturn s ->
      let kf = if pos then Some s else kf in
      kf, mk_func_return (Kernel_function.get_name s)
    | TTrue -> kf, ptrue
    | TFalse -> kf, pfalse
    | TRel(rel,t1,t2) ->
      kf,
      unamed (change_vars subst subst_res kf label (prel (rel,t1,t2)).content)
  in snd (aux None true cond)