let find_next_cycle cycles tree =
let no_back_inputs cycle =
let targets = List.tl (List.rev cycle)
in let rec no_back_in nodes =
match nodes with
n::tail -> if (List.length (edgefilter tree (fun _ e -> let (_,t,_) = e.edge in (e.edgeway == Backward && t==n))))!=0
then false
else no_back_in tail
| _ -> true
in no_back_in targets
in
let rec find_strict cycs =
match cycs with
x::tail -> if (has_MUXOr x tree) then (find_strict tail) else [x]
| _ -> []
in
let rec find_lower cycs=
match cycs with
x::tail -> if (no_back_inputs x) then x::(find_lower tail) else find_lower tail
| _ -> []
in
match (find_strict cycles) with
x::tail -> x
| _ -> let lower1 = find_lower cycles
in let beginnings = List.map (fun x -> List.hd (List.rev x)) lower1
in let rec find_lowest cycl =
match cycl with
x::tail -> let up = List.hd (List.rev x)
in if List.for_all (fun y -> y==up || not (is_child y up tree)) beginnings
then x::(find_lowest tail)
else find_lowest tail
| _ -> []
in let lower = find_lowest lower1
in if List.length lower!= 0
then let rec find_one cyc =
match cyc with
x::tail -> if not (has_many_MUXOr x tree) then x else find_one tail
| _ -> let rec find_only_or cy =
match cy with
x::tail -> if not (has_MUX x tree) then x else find_only_or tail
| _ -> List.hd lower
in find_only_or lower
in find_one lower
else []