(* * Basic definitions of decidablility and Functions - includes basic Lemmas about said functions *)
Require Export PslBase.Base.
(** * Definition of useful tactics *)
(** dec is used to destruct all decisions appearing in the goal or assumptions. *)
Ltac dec := repeat (destruct Dec).
(** This tactic completely solves listComplete goals for base types *)
Ltac listComplete := intros x; simpl; dec; destruct x; try congruence.
(** simplifies (decision x = x) *)
Ltac deq x := destruct (Dec (x=x)) as [[]  | isnotequal]; [> | contradict isnotequal; reflexivity] .
(** Function that takes two lists and returns the list of all pairs of elements from the two lists *)
Fixpoint prodLists {X Y: Type} (A: list X) (B: list Y) {struct A} :=
match A with
| nil => nil
| cons x A' => map (fun y => (x,y)) B ++ prodLists A' B end.

(** Crossing any list with the empty list always yields the empty list *)
Lemma prod_nil (X Y: Type) (A: list X) :
prodLists A ([]: list Y) = [].