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.
Global Arguments first_rule t : simpl never.

(* 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'}.