Fixpoint BDDunivl (cfg : BDDconfig) (ul : list ad) 
 (node : ad) (ly : list BDDvar) {struct ly} : BDDconfig * ad :=
  match ly with
  | nil => (cfg, node)
  | y :: ly' =>
      match BDDunivl cfg ul node ly' with
      | (cfg1, node1) => BDDuniv cfg1 (node1 :: ul) y node1
      end
  end.

(* Specifications: *)
Lemma BDDunivl_lemma : forall (ly : list BDDvar) (cfg : BDDconfig) (ul : list ad) (node : ad), BDDconfig_OK cfg -> used_list_OK cfg ul -> used_node' cfg ul node -> BDDconfig_OK (fst (BDDunivl cfg ul node ly)) /\ config_node_OK (fst (BDDunivl cfg ul node ly)) (snd (BDDunivl cfg ul node ly)) /\ used_nodes_preserved cfg (fst (BDDunivl cfg ul node ly)) ul /\ bool_fun_eq (bool_fun_of_BDD (fst (BDDunivl cfg ul node ly)) (snd (BDDunivl cfg ul node ly))) (bool_fun_univl (bool_fun_of_BDD cfg node) ly).
Lemma BDDunivl_config_OK : BDDconfig_OK (fst (BDDunivl cfg ul node ly)).
Lemma BDDunivl_node_OK : config_node_OK (fst (BDDunivl cfg ul node ly)) (snd (BDDunivl cfg ul node ly)).
Lemma BDDunivl_used_nodes_preserved : used_nodes_preserved cfg (fst (BDDunivl cfg ul node ly)) ul.
Lemma BDDunivl_list_OK : used_list_OK (fst (BDDunivl cfg ul node ly)) ul.
Lemma BDDunivl_list_OK_cons : used_list_OK (fst (BDDunivl cfg ul node ly)) (snd (BDDunivl cfg ul node ly) :: ul).
Lemma BDDunivl_is_univl : bool_fun_eq (bool_fun_of_BDD (fst (BDDunivl cfg ul node ly)) (snd (BDDunivl cfg ul node ly))) (bool_fun_univl (bool_fun_of_BDD cfg node) ly).