let rearrange_treeOr tree gr edge_id cycle node=
match gr with
Right _ -> (tree,[])
| Left graph ->
let edge = findedge edge_id tree
in let (c,t,p) = edge.edge
in match edge.edgeway with
Normal -> (match node.nname with
And -> rearrange_treeMUX tree gr edge_id cycle
| LongOr -> rearrange_treeMUX tree gr edge_id cycle
| Or -> rearrange_treeFuse tree gr edge_id cycle
| Id -> let next_node =
let rec ne cyc =
match cyc with
x::y::tail -> if y == t then x else ne (y::tail)
| _ -> NewName.invalid_id
in if (List.hd cycle) == t then (List.hd (List.rev cycle)) else ne cycle
in let _ = report2 "Or yle Id"
in let next_edge = find_edge_id t next_node tree
in let gra = graph_from_tree tree
in let node = DG.findnode next_node gra
in let desc = nodedesc node.nname
in if ns_inclvalue desc.outputtype Boolean
then rearrange_treeId tree (GrbTrDtoCOverId.Tr.umake gra (Right next_edge)) next_edge cycle c.sourceid
else rearrange_treeId tree (GrbTrPassOverId.Tr.umake gra (Right next_edge)) next_edge cycle c.sourceid
| _ -> let op_node = findnode t tree
in let op_gnode = DG.findnode t graph
in let _ = report2 "Or over OP node normal"
in let op_new_out = DG.nodefoldoutedges graph (fun y a -> y::a) op_gnode []
in let op_old_out = edgefilter tree (fun _ x -> let (cx,_,_) = x.edge in cx.sourceid==t)
in let (cn,id_node,pn) = List.hd op_new_out
in let id_node_out = DG.nodefoldoutedges graph (fun y a -> y::a) id_node []
in let op_changed = IdtMap.add t {op_node with children = [id_node.id]} (IdtMap.remove t tree.treeNodes)
in let tree2 =
{tree with
treeNodes = IdtMap.add id_node.id {node = id_node; allDone = true; number = op_node.number; children = op_node.children} op_changed;
treeEdges = IdtMap.add cn.nameforudg {edge = (cn,id_node.id,pn); edgeway = Cross; used = true} tree.treeEdges}
in let rec add_id_outes edge_list tr=
match edge_list with
x::tail -> let (cx,tx,px) = x.edge
in let (cn,tn,pn) = List.hd (List.filter (fun (_,tt,_) -> tt.id==tx) id_node_out)
in let edges =
IdtMap.add cn.nameforudg {x with edge = (cn,tn.id,pn)} (IdtMap.remove cx.nameforudg tr.treeEdges)
in let t_n = findnode tx tr
in let n = DG.findnode tx graph
in let nodes =
IdtMap.add tx {node = n; number = t_n.number; allDone = true; children = t_n.children} (IdtMap.remove tx tr.treeNodes)
in add_id_outes tail {tr with treeEdges = edges; treeNodes = nodes}
| _ -> tr
in let tree22 = add_id_outes (List.filter (fun x -> x.edgeway == Cross || x.edgeway == Forward) op_old_out) tree2
in let tree3 = add_id_outes (List.filter (fun x -> x.edgeway == Normal || x.edgeway == Backward) op_old_out) tree22
in let id_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
in let inp_or = List.filter (fun (cx,_,_) -> cx.sourceid != op_gnode.id) id_inp
in let (co,_,po) = List.hd inp_or
in let or_changed = if hasnode co.sourceid tree3
then
let or_node = findnode co.sourceid tree3
in IdtMap.add co.sourceid {or_node with children = id_node.id::or_node.children} tree3.treeNodes
else tree3.treeNodes
in let tree4 =
{tree3 with
treeNodes = or_changed;
treeEdges = IdtMap.add co.nameforudg {edge = (co,id_node.id,po); used = true; edgeway = Normal} tree3.treeEdges}
in let (added_nodes,tree5) =
if co.sourceid == c.sourceid
then ([id_node.id],tree4)
else let longOr = DG.findnode co.sourceid graph
in let (cm,_,pm) = List.hd (DG.nodefoldedges (fun y a -> y::a) longOr [])
in let nodes1 =
IdtMap.add longOr.id {node = longOr; number = op_node.number; allDone = true; children = [id_node.id]} tree4.treeNodes
in let node = findnode cm.sourceid tree4
in let nodes =
IdtMap.add cm.sourceid {node with children = longOr.id::node.children} (IdtMap.remove cm.sourceid nodes1)
in let edges = IdtMap.add cm.nameforudg {edge = (cm,longOr.id,pm); used = true; edgeway = Normal} tree4.treeEdges
in ([id_node.id;longOr.id],{tree4 with treeEdges = edges; treeNodes = nodes})
in let (next_edge_id,next_t) =
let rec ne cyc =
match cyc with
x::y::tail -> if x == t
then let filterid = edgefilter tree5 (fun _ x1 -> let (cx,tx,_)=x1.edge in tx ==y && cx.sourceid == id_node.id && x1.edgeway == Normal)
in (List.hd (List.map (fun x2 -> let (cx,_,_) = x2.edge in cx.nameforudg) filterid ),y)
else ne (y::tail)
| x::tail -> if x == t
then let filterid = edgefilter tree5 (fun _ x2 -> let (cx,tx,_)=x2.edge in tx ==(List.hd (List.rev cycle)) && cx.sourceid == id_node.id && x2.edgeway == Backward)
in (List.hd (List.map (fun x1 -> let (cx,_,_) = x1.edge in cx.nameforudg) filterid),(List.hd (List.rev cycle)))
else ne tail
| _ -> (NewName.invalid_id,NewName.invalid_id)
in ne (List.rev cycle)
in let rec split cyc seen =
match cyc with
x::tail -> if x == t
then (List.rev seen,tail)
else split tail (x::seen)
| _ -> ([],List.rev seen)
in let (f,s) = split cycle []
in let cyc = List.concat [f;added_nodes;s]
in let node = DG.findnode next_t graph
in let desc = nodedesc node.nname
in if ns_inclvalue desc.outputtype Boolean
then rearrange_treeId tree5 (GrbTrDtoCOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid
else rearrange_treeId tree5 (GrbTrPassOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid
)
| Backward -> (match node.nname with
And -> rearrange_treeMUX tree gr edge_id cycle
| Or -> rearrange_treeFuse tree gr edge_id cycle
| _ -> let op_gnode = DG.findnode t graph
in let op_node = findnode t tree
in let _ = report2 "Or over OP backward"
in let op_new_out = DG.nodefoldoutedges graph (fun y a -> y::a) op_gnode []
in let op_old_out = edgefilter tree (fun _ x -> let (cx,_,_) = x.edge in cx.sourceid==t)
in let (cn,id_node,pn) = List.hd op_new_out
in let id_node_out = DG.nodefoldoutedges graph (fun y a -> y::a) id_node []
in let op_changed = IdtMap.add t {op_node with children = [id_node.id]} (IdtMap.remove t tree.treeNodes)
in let tree2 =
{tree with
treeNodes = IdtMap.add id_node.id {node = id_node; allDone = true; number = op_node.number; children = op_node.children} op_changed;
treeEdges = IdtMap.add cn.nameforudg {edge = (cn,id_node.id,pn); edgeway = Normal; used = true} tree.treeEdges}
in let rec add_id_outes edge_list tr=
match edge_list with
x::tail -> let (cx,tx,px) = x.edge
in let (cnn,tn,pnn) = List.hd (List.filter (fun (_,tt,_) -> tt.id==tx) id_node_out)
in let edges = IdtMap.add cnn.nameforudg {x with edge = (cnn,tn.id,pnn)} (IdtMap.remove cx.nameforudg tr.treeEdges)
in let t_n = findnode tx tr
in let n = DG.findnode tx graph
in let nodes = IdtMap.add tx {node = n; number = t_n.number; allDone = true; children = t_n.children} (IdtMap.remove tx tr.treeNodes)
in add_id_outes tail {tr with treeEdges = edges; treeNodes = nodes}
| _ -> tr
in let tree3 = add_id_outes op_old_out tree2
in let id_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
in let inp_or = List.filter (fun (cx,_,_) -> cx.sourceid != op_gnode.id) id_inp
in let (co,_,po) = List.hd inp_or
in let or_changed = if hasnode co.sourceid tree3
then
let or_node = findnode co.sourceid tree3
in IdtMap.add co.sourceid {or_node with children = id_node.id::or_node.children} tree3.treeNodes
else tree3.treeNodes
in let tree4 =
{tree3 with
treeNodes = or_changed;
treeEdges = IdtMap.add co.nameforudg {edge = (co,id_node.id,po); used = true; edgeway = Backward} tree3.treeEdges}
in let (added_nodes,tree5) =
if co.sourceid == c.sourceid
then ([],tree4)
else let longOr = DG.findnode co.sourceid graph
in let (cm,_,pm) = List.hd (DG.nodefoldedges (fun y a -> y::a) longOr [])
in let nodes1 =
IdtMap.add longOr.id {node = longOr; number = op_node.number; allDone = true; children = [id_node.id]} tree4.treeNodes
in let node = findnode cm.sourceid tree4
in let nodes =
IdtMap.add cm.sourceid {node with children = longOr.id::node.children} (IdtMap.remove cm.sourceid nodes1)
in let edges = IdtMap.add cm.nameforudg {edge = (cm,longOr.id,pm); used = true; edgeway = Normal} tree4.treeEdges
in ([longOr.id],{tree4 with treeEdges = edges; treeNodes = nodes})
in let (next_edge_id,next_t) =
let rec ne cyc =
match cyc with
x::y::tail -> if x == t
then
let filterid = edgefilter tree5 (fun _ x -> let (cx,tx,_)=x.edge in tx ==y && cx.sourceid == id_node.id && x.edgeway == Normal)
in (List.hd (List.map (fun x -> let (cx,_,_) = x.edge in cx.nameforudg) filterid),y)
else ne (y::tail)
| x::tail -> if x == t
then
let filterid = (edgefilter tree5 (fun _ x -> let (cx,tx,_)=x.edge in tx ==(List.hd (List.rev cycle)) && cx.sourceid == id_node.id && x.edgeway == Backward))
in (List.hd (List.map (fun x -> let (cx,_,_) = x.edge in cx.nameforudg) filterid),(List.hd (List.rev cycle)))
else ne tail
| _ -> (NewName.invalid_id,NewName.invalid_id)
in ne (List.rev cycle)
in let rec split cyc seen =
match cyc with
x::tail -> if x == t
then (List.rev seen,tail)
else split tail (x::seen)
| _ -> (List.rev seen,[])
in let (f,s) = split cycle []
in let cyc = List.concat [added_nodes;f;[id_node.id];s]
in let node = DG.findnode next_t graph
in let desc = nodedesc node.nname
in if ns_inclvalue desc.outputtype Boolean
then rearrange_treeId tree5 (GrbTrDtoCOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid
else rearrange_treeId tree5 (GrbTrPassOverId.Tr.umake graph (Right next_edge_id)) next_edge_id cyc c.sourceid)