Section Syntax.
(* AST *)
Variables variable function constructor : Type.
Variable max_arity : nat.
Inductive value : Type :=
| c_capply : constructor -> list value -> value.
Inductive term : Type :=
| var : variable -> term
| capply : constructor -> list term -> term
| fapply : function -> list term -> term.
Inductive pattern : Type :=
| p_var : variable -> pattern
| p_capply : constructor -> list pattern -> pattern.
Inductive rule : Type :=
| rule_intro : function -> list pattern -> term -> rule.
(* Smarter induction principles than the ones automatically generated *)
(* Boolean equalities for syntax *)
Variable variable_eq_dec : forall (x1 x2 : variable), {x1=x2}+{x1<>x2}.
Definition variable_beq (x1 x2 : variable) : bool :=
if variable_eq_dec x1 x2 then true else false.
Variable function_eq_dec : forall (x1 x2 : function), {x1=x2}+{x1<>x2}.
Definition function_beq (x1 x2 : function) : bool :=
if function_eq_dec x1 x2 then true else false.
Variable constructor_eq_dec : forall (x1 x2 : constructor), {x1=x2}+{x1<>x2}.
Definition constructor_beq (x1 x2 : constructor) : bool :=
if constructor_eq_dec x1 x2 then true else false.
Fixpoint value_beq (v1 v2 : value) : bool :=
match v1, v2 with
| c_capply c lv, c_capply c' lv' => constructor_beq c c' && list_beq _ value_beq lv lv'
end.

Lemma value_beq_eq v1 v2 : value_beq v1 v2 = true <-> v1 = v2.