let choose_move cycle tree =
let graph = graph_from_tree tree
in
if has_MUXOr cycle tree
then
if has_many_MUXOr cycle tree
then
if upper_is_or cycle tree
then
let or_edge = upper_or_edge cycle tree
in let _ = report2 "upper is or"
in let ed = findedge or_edge tree
in let (_,t,_) = ed.edge
in let node = DG.findnode t graph
in rearrange_treeOr tree (GrbTrMoveOverOr.Tr.umake graph (Right or_edge)) or_edge cycle node
else
let edge_id = upper_mux_edge cycle tree
in let (_,tt,_) = DG.findedge edge_id graph
in let bool_fuse = tt.nname == ShortMux
in if bool_fuse
then rearrange_treeFuse tree (GrbTrFuseTwoAndOr.Tr.umake graph (Right edge_id)) edge_id cycle
else
let (_,target_node_id,_) = (findedge edge_id tree).edge
in let target_node = findnode target_node_id tree
in let graph_node = target_node.node
in let desc = nodedesc graph_node.nname
in if ns_inclvalue desc.outputtype Boolean
then rearrange_treeMUX tree (GrbTrMoveDtoCMux.Tr.umake graph (Right edge_id)) edge_id cycle
else rearrange_treeMUX tree (GrbTrMoveOverMux.Tr.umake graph (Right edge_id)) edge_id cycle
else
if backward_end_MUX cycle tree
then let target = (List.hd (List.rev cycle))
in let source = (List.hd cycle)
in let possible_edges =
edgefilter tree (fun _ mx -> let (cx,tx,_)=mx.edge in tx == target && cx.sourceid == source && mx.edgeway == Backward)
in let edge_id =
List.hd (List.map (fun nx -> let (cx,_,_) = nx.edge in cx.nameforudg) possible_edges)
in rearrange_treeCut tree (GrbTrCutStrictCycle.Tr.umake graph (Right edge_id)) edge_id cycle
else let edge_id = upper_mux_edge cycle tree
in
if edge_id == NewName.invalid_id
then let or_edge = upper_or_edge cycle tree
in let ed = findedge or_edge tree
in let (c,t,p) = ed.edge
in let _ = DG.findedge or_edge graph
in let node = DG.findnode t graph
in rearrange_treeOr tree (GrbTrMoveOverOr.Tr.umake graph (Right or_edge)) or_edge cycle node
else
let (c,target_node_id,p) = (findedge edge_id tree).edge
in let target_node = findnode target_node_id tree
in let graph_node = target_node.node
in let desc = nodedesc graph_node.nname
in if ns_inclvalue desc.outputtype Boolean
then rearrange_treeMUX tree (GrbTrMoveDtoCMux.Tr.umake graph (Right edge_id)) edge_id cycle
else rearrange_treeMUX tree (GrbTrMoveOverMux.Tr.umake graph (Right edge_id)) edge_id cycle
else
let t=List.hd cycle
and x = List.hd (List.rev cycle)
in let possible_edges =
(edgefilter tree (fun _ x1 -> let (cx,tx,_)=x1.edge in tx ==x && cx.sourceid == t && x1.edgeway == Backward))
in let edge_id =
(List.hd (List.map (fun x -> let (cx,_,_) = x.edge in cx.nameforudg) possible_edges))
in rearrange_treeCut tree (GrbTrCutStrictCycle.Tr.umake graph (Right edge_id)) edge_id cycle