let rec requires values ki state p = match p.content with
      | Pand(p1, p2) ->
          let state = requires values ki state p1 in
          requires values ki state p2
      | (* [state(lval) op term] *)
          Prel(rel,
               { term_node = Tapp(f1, _, [ x ]) },
               { term_node = Tapp(f2, _, l) })
            when f1.l_var_info.lv_name = state_name
              ->
          (match find_term_loc_or_status values state f2 l with
           | None -> warn_todo (); state
           | Some sly ->
               let subst trans e = fst (Subst.expr ~trans e state.subst) in
               let ex = !Properties.Interp.term_to_exp x in
               let sx = find_exp_status values state (subst true ex) in
               let sx =
                 if S.use_ctrl_dependencies then
                   join_deps values state sx
                 else
                   sx
               in
               let sy =
                 match sly with
                 | Status s -> s
                 | Location l -> find_loc_status_with_deps
                     ~with_deps:S.use_ctrl_dependencies
                       state
                       l
               in
               match cmp_of_rel sx sy rel with
               | truetrue -> assert false
               | truefalse -> state (* secure *)
               | false, b ->
                   Options.debug "add security leak for %a"
                     !Ast_printer.d_exp (subst true ex);
                   let state =
                     add_leak ~potential:(not b) state ki (subst false ex)
                   in
                   if Options.PropagateAssertions.get () then
                     (* you have just emitted a leak corresponding to a
                        propertie P, so you can assume that P is verified. Be
                        careful to only perform over-approximation. *)

                     match rel with
                     | Req | Rle ->
                         (try
                            let x = !Properties.Interp.term_to_lval x in
                            change_lval_status values state x sly
                          with Invalid_argument _ ->
                            state)
                     | Rlt | Rgt | Rge | Rneq ->
                         state
                   else
                     state)
      | Ptrue -> state
      | Pfalse -> state
      | _ ->
          (* Deal yet only with conjunction of relation. *)
          warn_todo ();
          state