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 (*upper non-strict is Or - move it down*)
            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 (*upper non-strict is MUX, move it down*)
              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 (*Ka mux tipud*)
              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 (*only one non-strict node*)
          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(*remove backward edge*)
          else let edge_id = upper_mux_edge cycle tree (*move MUX down*)
            in 
            if edge_id == NewName.invalid_id 
              then let or_edge = upper_or_edge cycle tree (*Move or down*)
                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 (*strict cycle*)
        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