let rearrange_treeId tree gr edge_id cycle or_id=
let delete_or_inputs () =
let new_gr = graph_from_tree tree
in let or_node = findnode or_id tree
in let or_gnode = DG.findnode or_id new_gr
in let or_inp = DG.nodefoldedges (fun a y -> a::y) or_gnode []
in let rec delete_or_inp inplist tree1 =
match inplist with
(cx,tx,px)::tail -> let g = GrbTrCutStrictCycle.Tr.umake (graph_from_tree tree1) (Right cx.nameforudg)
in (match g with
Right _ -> delete_or_inp tail tree1
| Left gra -> let _ = report2 "kustutasin serva"
in let new_or = (DG.findnode or_id gra)
in let or_new_inp = DG.nodefoldedges (fun a y -> a::y) new_or []
in let new_inp =
List.filter (fun (cc,_,_)->not (hasnode cc.sourceid tree1)) or_new_inp
in let (cn,tn,pn) = List.hd new_inp
in let node = DG.findnode cn.sourceid gra
in let t1 =
{tree1 with
treeEdges = IdtMap.remove cx.nameforudg tree1.treeEdges}
in let t2 =
{t1 with
treeEdges = IdtMap.add cn.nameforudg {edge = (cn,tn.id,pn); edgeway = Unknown; used = true} t1.treeEdges}
in let t3 =
{t2 with
treeNodes = IdtMap.add cn.sourceid {node = node; allDone = true; children = [or_id]; number = NodeNumber.invalid_num} t2.treeNodes}
in let t4 =
{t3 with
treeNodes = IdtMap.add or_id {or_node with node = new_or} (IdtMap.remove or_id t3.treeNodes)}
in delete_or_inp tail t4
)
| _ -> tree1
in let tree2 = delete_or_inp or_inp tree
in (new_tree tree2,[])
in match gr with
Right a -> let graph = graph_from_tree tree
in let _ = report2 ("ID teisenduse viga: "^a)
in let edge = findedge edge_id tree
in let (c,t,p) = edge.edge
in let or_node = or_id
in let rec try_remove edges gra =
match edges with
(co,_,_)::ta -> let h = GrbTrCutStrictCycle.Tr.umake gra (Right co.nameforudg)
in (match h with
Right _ -> try_remove ta gra
| Left ggm -> let _ = report2 "kustutasin serva" in try_remove ta ggm)
| _ -> gra
in let (g,second_node) =
if (is_MUX t tree && has_one_MUX cycle tree && has_one_or cycle tree)
then
let id_node1 = DG.findnode c.sourceid graph
in let _ = report2 "Or -> Id -> MUX erijuht, kustuta Or sisendserv"
in let id_node_inp1 = DG.nodefoldedges (fun y a -> y::a) id_node1 []
in let (or_id2,before_or,graph2,no_longor) =
let id_bool_inp = List.filter (fun (_,_,px) -> px == PortSingleB) id_node_inp1
in let (cx,_,_) = List.hd id_bool_inp
in if cx.sourceid == or_id
then
let before_or2 =
let rec find_or_inp cyc =
match cyc with
x::tail -> if x == or_id
then List.hd tail
else find_or_inp tail
| _ -> NewName.invalid_id
in find_or_inp cycle
in (or_id,before_or2,graph,true)
else
let before_or2 =
let rec find_or_inp cyc =
match cyc with
x::tail -> if x == or_id
then List.hd tail
else find_or_inp tail
| _ -> NewName.invalid_id
in find_or_inp cycle
in (or_id,before_or2,graph,false)
in let mkcnstlblmap d =
RLMap.fold (fun rl k m ->
List.fold_right (fun i mm -> RLMMap.add (rl,i) i mm
) (intfromto 1 k) m
) d RLMMap.empty
in if no_longor
then
let id_node = DG.findnode c.sourceid graph2
in let id_node_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
in let id_inp_from_op = List.filter (fun (cx,_,_) -> cx.sourceid != or_id2) id_node_inp
in let (cop,_,pop) = List.hd id_inp_from_op
in let op_node = DG.findnode cop.sourceid graph2
in let op_node_inp = DG.nodefoldedges (fun y a -> y::a) op_node []
in let op_node_from_or = List.filter (fun (cx,_,_) -> cx.sourceid == or_id2) op_node_inp
in let is_or_op = not (List.length op_node_from_or == 0)
in let rec add_inp inp_list not_source target_id gr1 =
match inp_list with
(cx,tx,px)::tail -> if cx.sourceid == not_source
then add_inp tail not_source target_id gr1
else let gm = DG.addedge ({cx with nameforudg = NewName.get ()}, target_id, px) gr1
in add_inp tail not_source target_id gm
| _ -> gr1
in let ornode = DG.findnode or_id2 graph2
in let ornode_inp = DG.nodefoldedges (fun y a -> y::a) ornode []
in let new_or_id = NewName.get ()
in let _ = report2 ("uus or "^(NewName.to_string new_or_id))
in let new_id_id1 = NewName.get ()
in let false_id = NewName.get ()
in let mux_node = DG.findnode t graph2
in let mux_node_inp = DG.nodefoldedges (fun y a -> y::a) mux_node []
in let (cid,_,pid) = List.hd (List.filter (fun (_,_,px) -> px == PortSingleB) id_node_inp)
in let (graph3,new_op_id) = if is_or_op
then let (corop,_,porop) = List.hd op_node_from_or
in let new_gr = ref graph2
in let new_op_id = NewName.get ()
in
new_gr := DG.addnode {op_node with inputs = PortMap.empty; id = new_op_id} !new_gr;
new_gr := add_inp op_node_inp or_id2 new_op_id !new_gr;
new_gr := DG.addedge ({corop with sourceid = new_or_id; nameforudg = NewName.get ()}, new_op_id, porop) !new_gr;
(!new_gr,new_op_id)
else (graph2,op_node.id)
in let new_gr = ref graph3
in
new_gr := DG.remedge c.nameforudg !new_gr;
new_gr := DG.remnode mux_node.id !new_gr;
new_gr := DG.addnode {ornode with inputs = PortMap.empty; id=new_or_id} !new_gr;
new_gr := DG.addnode {id_node with inputs = PortMap.empty; id=new_id_id1} !new_gr;
new_gr := DG.addnode {mux_node with inputs = PortMap.empty} !new_gr;
new_gr := add_inp mux_node_inp id_node.id mux_node.id !new_gr;
new_gr := add_inp (List.filter (fun (cx,_,_) -> cx.sourceid != op_node.id) id_node_inp) or_id2 new_id_id1 !new_gr;
new_gr := add_inp ornode_inp before_or new_or_id !new_gr;
new_gr := DG.addedge ({c with sourceid=new_id_id1},t,p) !new_gr;
new_gr := DG.addedge ({cop with sourceid =new_op_id; nameforudg = NewName.get ()}, new_id_id1,pop) !new_gr;
new_gr := DG.addedge ({cid with sourceid = new_or_id; nameforudg = NewName.get ()}, new_id_id1, pid) !new_gr;
if (List.length ornode_inp) == 1
then
begin
new_gr := DG.addnode {nname=False; id = false_id; inputs = PortMap.empty; inside=RLMap.empty; updims=RLMap.empty; otherdims=Array.of_list []} !new_gr;
new_gr := DG.addedge ({sourceid=false_id; nameforudg = NewName.get ();lblmap = mkcnstlblmap ornode.inside},new_or_id,PortUnstrB) !new_gr;
end
else
begin
end;
(Left !new_gr,mux_node.id)
else
let id_node = DG.findnode c.sourceid graph2
in let id_node_inp = DG.nodefoldedges (fun y a -> y::a) id_node []
in let id_inp_from_op = List.filter (fun (_,_,px) -> px!=PortSingleB) id_node_inp
in let (cop,_,pop) = List.hd id_inp_from_op
in let op_node = DG.findnode cop.sourceid graph2
in let op_node_inp = DG.nodefoldedges (fun y a -> y::a) op_node []
in let op_node_from_or = List.filter (fun (cx,_,_) -> cx.sourceid == or_id2) op_node_inp
in let (corop,_,porop) = List.hd op_node_from_or
in let ornode = DG.findnode or_id2 graph2
in let rec add_inp inp_list not_source target_id gr1 =
match inp_list with
(cx,tx,px)::tail -> if cx.sourceid == not_source
then add_inp tail not_source target_id gr1
else let gm = DG.addedge ({cx with nameforudg = NewName.get ()}, target_id, px) gr1
in add_inp tail not_source target_id gm
| _ -> gr1
in let ornode_inp = DG.nodefoldedges (fun y a -> y::a) ornode []
in let new_or_id = NewName.get ()
in let _ = report2 ("uus or "^(NewName.to_string new_or_id))
in let new_id_id1 = NewName.get ()
in let false_id = NewName.get ()
in let new_longor_id = NewName.get ()
in let new_op_id = NewName.get ()
in let mux_node = DG.findnode t graph2
in let mux_node_inp = DG.nodefoldedges (fun y a -> y::a) mux_node []
in let (cid,_,pid) = List.hd (List.filter (fun (_,_,px) -> px == PortSingleB) id_node_inp)
in let longor_node = DG.findnode cid.sourceid graph2
in let (clongor,_,plongor) = List.hd (DG.nodefoldedges (fun y a -> y::a) longor_node [])
in let new_gr = ref graph2
in
new_gr := DG.remedge c.nameforudg !new_gr;
new_gr := DG.remnode mux_node.id !new_gr;
new_gr := DG.addnode {ornode with inputs = PortMap.empty; id=new_or_id} !new_gr;
new_gr := DG.addnode {longor_node with inputs = PortMap.empty; id=new_longor_id} !new_gr;
new_gr := DG.addnode {id_node with inputs = PortMap.empty; id=new_id_id1} !new_gr;
new_gr := DG.addnode {op_node with inputs = PortMap.empty; id =new_op_id} !new_gr;
new_gr := DG.addnode {mux_node with inputs = PortMap.empty} !new_gr;
new_gr := add_inp mux_node_inp id_node.id mux_node.id !new_gr;
new_gr := add_inp op_node_inp or_id2 new_op_id !new_gr;
new_gr := DG.addedge ({corop with sourceid = new_or_id; nameforudg = NewName.get ()}, new_op_id, porop) !new_gr;
new_gr := DG.addedge ({cop with sourceid =new_op_id; nameforudg = NewName.get ()}, new_id_id1,pop) !new_gr;
new_gr := add_inp (List.filter (fun (cx,_,_) -> cx.sourceid != op_node.id) id_node_inp) longor_node.id new_id_id1 !new_gr;
new_gr := add_inp ornode_inp before_or new_or_id !new_gr;
new_gr := DG.addedge ({c with sourceid=new_id_id1},t,p) !new_gr;
new_gr := DG.addedge ({cid with sourceid = new_longor_id; nameforudg = NewName.get ()}, new_id_id1, pid) !new_gr;
new_gr := DG.addedge ({clongor with sourceid = new_or_id; nameforudg = NewName.get ()}, new_longor_id, plongor) !new_gr;
if (List.length ornode_inp) == 1
then
begin
new_gr := DG.addnode {nname=False; id = false_id; inputs = PortMap.empty; inside=RLMap.empty; updims=RLMap.empty; otherdims=Array.of_list []} !new_gr;
new_gr := DG.addedge ({sourceid=false_id; nameforudg = NewName.get ();lblmap = mkcnstlblmap ornode.inside},new_or_id,PortUnstrB) !new_gr;
end
else
begin
end;
(Left !new_gr,mux_node.id)
else
if (has_many_MUXOr cycle tree)
then if is_MUX (List.hd (List.rev cycle)) tree
then let edge_id2 = find_edge_id (List.hd (List.rev cycle)) (List.hd (List.tl (List.rev cycle))) tree
in let (cm,target_node_id,p) = (findedge edge_id2 tree).edge
in let target_node = findnode target_node_id tree
in let graph_node = target_node.node
in if graph_node.nname == ShortMux
then (GrbTrFuseTwoAndOr.Tr.umake graph (Right edge_id2),cm.sourceid)
else let desc = nodedesc graph_node.nname
in if ns_inclvalue desc.outputtype Boolean
then (GrbTrMoveDtoCMux.Tr.umake graph (Right edge_id2),cm.sourceid)
else (GrbTrMoveOverMux.Tr.umake graph (Right edge_id2),cm.sourceid)
else
let bool_or = not (has_MUX cycle tree)
in if bool_or
then
if is_OR (List.hd (List.rev cycle)) tree
then
let edge_id2 = find_edge_id (List.hd (List.rev cycle)) (List.hd (List.tl (List.rev cycle))) tree
in let edge_2 = findedge edge_id2 tree
in let (cm,tt,_) = edge_2.edge
in match (findnode tt tree).node.nname with
And -> (GrbTrMoveOverOr.Tr.umake graph (Right edge_id2),cm.sourceid)
| Or -> (GrbTrMoveOverOr.Tr.umake graph (Right edge_id2),cm.sourceid)
| LongOr -> (GrbTrMoveOverOr.Tr.umake graph (Right edge_id2),cm.sourceid)
| _ -> let gg = GrbTrMoveOverOr.Tr.umake graph (Right edge_id2)
in match gg with
Right a -> (Right a,NewName.invalid_id)
| Left gr_id -> let next_edge_target =
let rec other cyc =
match cyc with
x::y::tail -> if x == tt then y else other (y::tail)
| x::tail -> if x == tt then List.hd (List.rev cycle) else other tail
| _ -> NewName.invalid_id
in other (List.rev cycle)
in let next_edge_id = find_edge_id tt next_edge_target tree
in let node = DG.findnode next_edge_target gr_id
in let desc = nodedesc node.nname
in if ns_inclvalue desc.outputtype Boolean
then (GrbTrDtoCOverId.Tr.umake gr_id (Right next_edge_id),cm.sourceid)
else (GrbTrPassOverId.Tr.umake gr_id (Right next_edge_id),cm.sourceid)
else
let (other_or,end_n) =
let rec oo cyc =
match cyc with
x::y::tail -> if is_OR x tree && x != or_node then (x,y) else oo (y::tail)
| x::tail -> if is_OR x tree && x!=or_node then (x,(List.hd (List.rev cycle))) else oo tail
| _ -> (NewName.invalid_id,NewName.invalid_id)
in oo (List.rev cycle)
in match (findnode end_n tree).node.nname with
And -> (GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree)),other_or)
| Or -> (GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree)),other_or)
| LongOr -> (GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree)),other_or)
| _ -> let gg = GrbTrMoveOverOr.Tr.umake graph (Right (find_edge_id other_or end_n tree))
in match gg with
Right a -> (Right a,NewName.invalid_id)
| Left gr_id -> let next_edge_target =
let rec other cyc =
match cyc with
x::y::tail -> if x == end_n then y else other (y::tail)
| x::tail -> if x == end_n then List.hd (List.rev cycle) else other tail
| _ -> NewName.invalid_id
in other (List.rev cycle)
in let next_edge_id = find_edge_id end_n next_edge_target tree
in let node = DG.findnode next_edge_target gr_id
in let desc = nodedesc node.nname
in if ns_inclvalue desc.outputtype Boolean
then (GrbTrDtoCOverId.Tr.umake gr_id (Right next_edge_id),other_or)
else (GrbTrPassOverId.Tr.umake gr_id (Right next_edge_id),other_or)
else let edge_id23 = upper_mux_edge cycle tree
in let _ = report2 "teisenda teine MUX"
in let edge_id2 = if edge_id23==NewName.invalid_id
then (find_edge_id (List.hd (List.rev cycle)) (List.hd (List.tl (List.rev cycle))) tree)
else edge_id23
in let (cm,target_node_id,p) = (findedge edge_id2 tree).edge
in let target_node = findnode target_node_id tree
in let graph_node = target_node.node
in if graph_node.nname == ShortMux
then (GrbTrFuseTwoAndOr.Tr.umake graph (Right edge_id2),cm.sourceid)
else let desc = nodedesc graph_node.nname
in if ns_inclvalue desc.outputtype Boolean
then (GrbTrMoveDtoCMux.Tr.umake graph (Right edge_id2),cm.sourceid)
else (GrbTrMoveOverMux.Tr.umake graph (Right edge_id2),cm.sourceid)
else let before_or =
let rec next (x::y::t) =
if x == or_node then y else next (y::t)
in if (List.hd (List.rev cycle))==or_node then List.hd cycle else next cycle
in (GrbTrCutStrictCycle.Tr.umake graph (Right (find_edge_id before_or or_node tree)),NewName.invalid_id)
in let gg1 = match g with
Right _ -> graph_from_tree tree
| Left gg5 -> gg5
in let gg2 = if DG.hasnode or_id gg1
then try_remove (DG.nodefoldedges (fun y a -> y::a) (DG.findnode or_id gg1) []) gg1
else gg1
in let gg3 = if DG.hasnode second_node gg2
then try_remove (DG.nodefoldedges (fun y a -> y::a) (DG.findnode second_node gg2) []) gg2
else gg1
in let gra2 = match (GrbTrRemoveDead.Tr.umake gg3 (Right NewName.invalid_id)) with
Right _ -> gg3
| Left ggm -> ggm
in let gg = gra2
in let t = createTree gg;
in let be = findBeginnings (nodelist gg)
in let _ = NodeNumber.refresh (NodeNumber.from_int 1)
in let tree2 = depth t be
in (tree2,[])
| Left graph ->
let edge = findedge edge_id tree
in match edge.edgeway with
Normal -> let (c,t,p) = edge.edge
in if c.sourceid == List.hd (List.rev cycle)
then
let _ = report2 "Id sisendserv on back"
in delete_or_inputs ()
else
let op_node = findnode t tree
in let _ = report2 "Id normal"
in let op_gnode = DG.findnode t graph
in let desc = nodedesc (DG.findnode t graph).nname
in let op_inp = DG.nodefoldedges (fun y a -> y::a) op_gnode []
in let op_tinp = edgefilter tree (fun _ x -> let (_,ta,_) = x.edge in t == ta)
in let op_id_inp = List.map (fun (cx,_,_)-> cx.nameforudg) op_inp
in let op_id_tinp = List.map (fun x -> let (cx,_,_)=x.edge in cx.nameforudg) op_tinp
in if ns_inclvalue desc.outputtype Boolean
then
let (c_out,and_node,p_out) = List.hd (DG.nodefoldoutedges graph (fun y a -> y::a) op_gnode [])
in let op_tout = edgefilter tree (fun _ x -> let (ca,ta,_) = x.edge in ca.sourceid == t)
in let and_out = DG.nodefoldoutedges graph (fun y a -> y::a) and_node []
in let rec add_and_out edgelist tr=
match edgelist with
x::tail -> let (cx,tx,px) = x.edge
in let (cxx,_,pxx) = List.hd (List.filter (fun (_,tt,_) -> tt.id ==tx) and_out)
in let edges =
IdtMap.add cxx.nameforudg {edge = (cxx,tx,pxx); used = true; edgeway = x.edgeway} (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_and_out tail {tr with treeNodes = nodes; treeEdges = edges}
| _ -> tr
in let tree2 = {tree with
treeNodes = IdtMap.add t {op_node with node = op_gnode; children = [and_node.id]} (IdtMap.remove t tree.treeNodes);
treeEdges =IdtMap.remove c.nameforudg tree.treeEdges}
in let ttt = {tree2 with
treeEdges = IdtMap.add c_out.nameforudg {edge = (c_out,and_node.id,p_out); edgeway = Cross; used = true} tree2.treeEdges;
treeNodes =IdtMap.add and_node.id {node = and_node; allDone = true; number = op_node.number; children= op_node.children} tree2.treeNodes}
in let added_and = add_and_out op_tout ttt
in let and_or_inp = List.filter (fun (cx,_,_) -> cx.nameforudg != c_out.nameforudg) (DG.nodefoldedges (fun y a -> y::a) and_node [])
in let (ca,ta,pa) = List.hd and_or_inp
in let or_node = findnode ca.sourceid added_and
in let new_nodes =IdtMap.add ca.sourceid {or_node with children = ta.id::or_node.children} (IdtMap.remove ca.sourceid added_and.treeNodes)
in let tree3 = {added_and with treeNodes = new_nodes; treeEdges = IdtMap.add ca.nameforudg {edge =(ca,ta.id,pa); edgeway = Normal; used = true} added_and.treeEdges}
in let op_new_inp = List.hd (List.filter (fun x -> not (List.mem x op_id_tinp)) op_id_inp)
in let (cn,tn,pn) = DG.findedge op_new_inp graph
in let old_op = findnode cn.sourceid tree3
in let nnodes = IdtMap.add cn.sourceid {old_op with children = tn.id::old_op.children} (IdtMap.remove cn.sourceid tree3.treeNodes)
in let tree4 = {tree3 with treeNodes = nnodes; treeEdges = IdtMap.add cn.nameforudg {edge = (cn,tn.id,pn); edgeway = Normal; used = true} tree3.treeEdges}
in let rec split cyc seen =
match cyc with
x::tail -> if x == c.sourceid
then if seen == [] then ([],(List.rev (List.tl (List.rev tail)))) else (List.rev (List.tl seen),tail)
else split tail (x::seen)
| _ -> (List.rev seen,[])
in let (f,s) = split cycle []
in let cyc = List.concat [f;[and_node.id];s]
in (rearrange tree4 (List.hd (List.rev cyc)) cyc,cyc)
else
let op_new_inp = List.filter (fun x -> not (List.mem x op_id_tinp)) op_id_inp
in let tree2 = {tree with
treeNodes = IdtMap.add t {op_node with node = op_gnode} (IdtMap.remove t tree.treeNodes);
treeEdges =IdtMap.remove c.nameforudg tree.treeEdges}
in let bool_inp =
List.filter (fun x -> let (cx,_,_) = DG.findedge x graph in ns_inclvalue (nodedesc (DG.findnode cx.sourceid graph).nname).outputtype Boolean ) op_new_inp
in let from_op_inp = List.filter (fun x -> not (List.mem x bool_inp)) op_new_inp
in let (cc,tt,pp) = DG.findedge (List.hd from_op_inp) graph
in let sour = findnode cc.sourceid tree2
in let sour_added =IdtMap.add cc.sourceid {sour with children = List.concat [sour.children;[tt.id]]} (IdtMap.remove cc.sourceid tree2.treeNodes)
in let tree3 =
{tree2 with
treeNodes = sour_added;
treeEdges =IdtMap.add cc.sourceid {edge=(cc,tt.id,pp); edgeway = Cross; used = true} tree2.treeEdges}
in let (cn,_,pn) = DG.findedge (List.hd bool_inp) graph
in let and_node = DG.findnode cn.sourceid graph
in let tree4 =
{tree3 with
treeNodes =IdtMap.add and_node.id {node = and_node; allDone = true; number = op_node.number; children = [op_gnode.id]} tree3.treeNodes;
treeEdges =IdtMap.add cn.nameforudg {edge= (cn,op_gnode.id,pn); edgeway = Normal; used = true} tree3.treeEdges}
in let and_inp = DG.nodefoldedges (fun y a -> y::a) and_node []
in let lor_id =
let rec orid cyc =
match cyc with
x::y::tail -> if x == c.sourceid then y else orid (y::tail)
| x::tail -> if x == c.sourceid then List.hd cycle else orid tail
| _ -> NewName.invalid_id
in orid cycle
in let and_inp_or = List.filter (fun (cx,_,_) -> cx.sourceid ==lor_id) and_inp
in let (cand,_,pand) = List.hd and_inp_or
in let lor_node = findnode lor_id tree4
in let lor_added =
IdtMap.add lor_id {lor_node with children = and_node.id::lor_node.children} (IdtMap.remove lor_id tree4.treeNodes)
in let tree5 =
{tree4 with
treeNodes=lor_added;
treeEdges =IdtMap.add cand.nameforudg {edge =(cand, and_node.id,pand); edgeway = Normal; used = true} (tree4.treeEdges)}
in let tree6 =if (List.length and_inp) > 1
then
let and_other_inp = List.filter (fun (cx,_,_) -> (cx.nameforudg != cand.nameforudg)) and_inp
in let (coth,_,poth) = List.hd and_other_inp
in let tree_edge = find_edge_id coth.sourceid op_gnode.id tree
in let coth_node = findnode coth.sourceid tree5
in let coth_added =
IdtMap.add coth.sourceid {coth_node with children = List.concat [coth_node.children; [and_node.id]]} (IdtMap.remove coth.sourceid tree5.treeNodes)
in {tree5 with
treeNodes=coth_added;
treeEdges =IdtMap.add coth.nameforudg {edge = (coth,and_node.id,poth); edgeway = (findedge tree_edge tree).edgeway; used = true} (IdtMap.remove tree_edge tree5.treeEdges)}
else let tree_edge = find_edge_id or_id op_gnode.id tree
in if tree_edge != cand.nameforudg
then {tree5 with
treeNodes=tree5.treeNodes;
treeEdges =(IdtMap.remove tree_edge tree5.treeEdges)}
else tree5
in let rec split cyc seen =
match cyc with
x::tail -> if x == c.sourceid
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;[and_node.id];s]
in (tree6,cyc)
| Backward -> let _ = report2 "Id back"
in delete_or_inputs ()