Fixpoint first_rule_rec (prog': list rule) (t: active_term) :
  option (nat * (variable -> value) * term) :=
  match prog' with
    | [] => None
  | rule_intro f lp t' :: prog'' =>
    if function_beq function_eq_dec (fst t) f
    then
      match unify_list [] (snd t) lp with
        | None =>
          match first_rule_rec prog'' t with
            | None => None
            | Some (i, s, t) => Some (S i, s, t)
            end
        | Some s => Some (0, s, subst s t')
      end
    else
      match first_rule_rec prog'' t with
        | None => None
        | Some (i, s, t) => Some (S i, s, t)
      end
  end.Definition first_rule (t: active_term) :
  option (nat * (variable -> value) * term) :=
  first_rule_rec prog t.

(* Specifications: *)
Lemma first_rule_sound : forall (f: function) (lv: list value) (i: nat) (s: variable -> value) (t: term), first_rule (f, lv) = Some (i, s, t) -> { lpt : (list pattern * term)| let (lp, t') := lpt in i < length prog /\ nth i prog rule_default = rule_intro f lp t' /\ unify_list [] lv lp = Some s /\ t = subst s t'}.