Fixpoint BDDor_1 (cfg : BDDconfig) (ul : list ad) (node1 node2 : ad)
 (bound : nat) {struct bound} : BDDconfig * ad :=
  match bound with
  | O => (* Error *)  (initBDDconfig, BDDzero)
  | S bound' =>
      match MapGet2 _ (orm_of_cfg cfg) node1 node2 with
      | Some node' => (cfg, node')
      | None =>
          match MapGet _ (fst cfg) node1 with
          | None =>
              if Neqb node1 BDDzero
              then (BDDor_memo_put cfg node1 node2 node2, node2)
              else (BDDor_memo_put cfg node1 node2 node1, node1)
          | Some (x1, (l1, r1)) =>
              match MapGet _ (fst cfg) node2 with
              | None =>
                  if Neqb node2 BDDzero
                  then (BDDor_memo_put cfg node1 node2 node1, node1)
                  else (BDDor_memo_put cfg node1 node2 node2, node2)
              | Some (x2, (l2, r2)) =>
                  match BDDcompare x1 x2 with
                  | Datatypes.Eq =>
                      match BDDor_1 cfg ul l1 l2 bound' with
                      | (cfgl, nodel) =>
                          match BDDor_1 cfgl (nodel :: ul) r1 r2 bound' with
                          | (cfgr, noder) =>
                              match
                                BDDmake gc cfgr x1 nodel noder
                                  (noder :: nodel :: ul)
                              with
                              | (cfg', node') =>
                                  (BDDor_memo_put cfg' node1 node2 node',
                                  node')
                              end
                          end
                      end
                  | Datatypes.Gt =>
                      match BDDor_1 cfg ul l1 node2 bound' with
                      | (cfgl, nodel) =>
                          match
                            BDDor_1 cfgl (nodel :: ul) r1 node2 bound'
                          with
                          | (cfgr, noder) =>
                              match
                                BDDmake gc cfgr x1 nodel noder
                                  (noder :: nodel :: ul)
                              with
                              | (cfg', node') =>
                                  (BDDor_memo_put cfg' node1 node2 node',
                                  node')
                              end
                          end
                      end
                  | Datatypes.Lt =>
                      match BDDor_1 cfg ul node1 l2 bound' with
                      | (cfgl, nodel) =>
                          match
                            BDDor_1 cfgl (nodel :: ul) node1 r2 bound'
                          with
                          | (cfgr, noder) =>
                              match
                                BDDmake gc cfgr x2 nodel noder
                                  (noder :: nodel :: ul)
                              with
                              | (cfg', node') =>
                                  (BDDor_memo_put cfg' node1 node2 node',
                                  node')
                              end
                          end
                      end
                  end
              end
          end
      end
  end.

Lemma BDDor_1_lemma : forall (bound : nat) (cfg : BDDconfig) (ul : list ad) (node1 node2 : ad), max (nat_of_N (node_height cfg node1)) (nat_of_N (node_height cfg node2)) < bound -> BDDconfig_OK cfg -> used_list_OK cfg ul -> used_node' cfg ul node1 -> used_node' cfg ul node2 -> BDDconfig_OK (fst (BDDor_1 cfg ul node1 node2 bound)) /\ config_node_OK (fst (BDDor_1 cfg ul node1 node2 bound)) (snd (BDDor_1 cfg ul node1 node2 bound)) /\ used_nodes_preserved cfg (fst (BDDor_1 cfg ul node1 node2 bound)) ul /\ Nleb (node_height (fst (BDDor_1 cfg ul node1 node2 bound)) (snd (BDDor_1 cfg ul node1 node2 bound))) (BDDvar_max (node_height cfg node1) (node_height cfg node2)) = true /\ bool_fun_eq (bool_fun_of_BDD (fst (BDDor_1 cfg ul node1 node2 bound)) (snd (BDDor_1 cfg ul node1 node2 bound))) (bool_fun_or (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)).