diff --git a/library/dgraphs.yap b/library/dgraphs.yap index ed9687de4..d66ead6aa 100644 --- a/library/dgraphs.yap +++ b/library/dgraphs.yap @@ -14,10 +14,13 @@ dgraph_del_edges/3, dgraph_del_vertex/3, dgraph_del_vertices/3, + dgraph_edge/3, dgraph_edges/2, dgraph_vertices/2, - dgraph_neighbors/2, - dgraph_neighbours/2, + dgraph_to_ugraph/2, + ugraph_to_dgraph/2, + dgraph_neighbors/3, + dgraph_neighbours/3, dgraph_complement/2, dgraph_transpose/2, dgraph_compose/3, @@ -43,7 +46,7 @@ ord_union/3, ord_subtract/3, ord_del_element/3, - ord_member/2]). + ord_memberchk/2]). dgraph_new(Vertices) :- rb_new(Vertices). @@ -65,7 +68,7 @@ dgraph_add_edges(Edges) --> all_vertices_in_edges(SortedEdges,Vertices), sort(Vertices,SortedVertices) }, - dgraph_add_egdes(SortedVertices,SortedEdges). + dgraph_add_edges(SortedVertices,SortedEdges). all_vertices_in_edges([],[]). all_vertices_in_edges([V1-V2|Edges],[V1,V2|Vertices]) :- @@ -79,14 +82,14 @@ edges2graphl([V|Vertices], SortedEdges, [V-[]|GraphL]) :- edges2graphl(Vertices, SortedEdges, GraphL). -dgraph_add_egdes([],[]) --> []. -dgraph_add_egdes([V|Vs],[V-V1|Es]) --> !, +dgraph_add_edges([],[]) --> []. +dgraph_add_edges([V|Vs],[V-V1|Es]) --> !, { get_extra_children(Es,V,Children,REs) }, dgraph_update_vertex(V,[V1|Children]), - dgraph_add_egdes(Vs,REs). -dgraph_add_egdes([V|Vs],Es) --> !, + dgraph_add_edges(Vs,REs). +dgraph_add_edges([V|Vs],Es) --> !, dgraph_update_vertex(V,[]), - dgraph_add_egdes(Vs,Es). + dgraph_add_edges(Vs,Es). get_extra_children([V-C|Es],V,[C|Children],REs) :- !, get_extra_children(Es,V,Children,REs). @@ -266,7 +269,7 @@ transit_graph2([GC|GrandChildren], V, G, [V-GC|NewEdges], MoreEdges) :- is_edge(V1,V2,G) :- rb_lookup(V1,Children,G), - ord_member(Children, V2). + ord_memberchk(V2, Children). dgraph_symmetric_closure(G,S) :- dgraph_edges(G, Edges), @@ -328,3 +331,15 @@ close_links([l(V,A,A,S,E)|Links], RQ, RQ0) :- close_links(Links, RQ1, RQ0). +ugraph_to_dgraph(UG, DG) :- + ord_list_to_rbtree(UG, DG). + +dgraph_to_ugraph(DG, UG) :- + rb_visit(DG, UG). + + +dgraph_edge(N1, N2, G) :- + rb_lookup(N1, Ns, G), + ord_memberchk(N2, Ns). + + diff --git a/library/rbtrees.yap b/library/rbtrees.yap index e87659dd9..765aac38c 100644 --- a/library/rbtrees.yap +++ b/library/rbtrees.yap @@ -43,7 +43,7 @@ rb_in/3 ]). -:- meta_predicate rb_map(+,:,-), rb_apply(+,+,:,-). +:- meta_predicate rb_map(+,:,-), rb_partial_map(+,+,:,-), rb_apply(+,+,:,-). % create an empty tree. rb_new(t(Nil,Nil)) :- Nil = black([],[],[],[]). @@ -188,9 +188,11 @@ apply(black(Left,Key0,Val0,Right), Key, Goal, black(NewLeft,Key0,Val,NewRight)) ; Cmp == (>) -> NewRight = Right, + Val = Val0, apply(Left, Key, Goal, NewLeft) ; NewLeft = Left, + Val = Val0, apply(Right, Key, Goal, NewRight) ). apply(red(Left,Key0,Val0,Right), Key, Goal, red(NewLeft,Key0,Val,NewRight)) :- @@ -202,9 +204,11 @@ apply(red(Left,Key0,Val0,Right), Key, Goal, red(NewLeft,Key0,Val,NewRight)) :- ; Cmp == (>) -> NewRight = Right, + Val = Val0, apply(Left, Key, Goal, NewLeft) ; NewLeft = Left, + Val = Val0, apply(Right, Key, Goal, NewRight) ). @@ -635,15 +639,31 @@ clone(black(L,K,_,R),black(NL,K,NV,NR),NsF,Ns0) :- clone(R,NR,Ns1,Ns0). rb_partial_map(t(Nil,T0), Map, Goal, t(Nil,TF)) :- - partial_map(T0, Map, [], Goal, TF). + partial_map(T0, Map, [], Nil, Goal, TF). rb_partial_map(t(Nil,T0), Map, Map0, Goal, t(Nil,TF)) :- - rb_partial_map(T0, Map, Map0, Goal, TF). + rb_partial_map(T0, Map, Map0, Nil, Goal, TF). -partial_map(T,[],[],_,T) :- !. -partial_map(black([],[],[],[]),Map,Map,_,black([],[],[],[])) :- !. -partial_map(red(L,K,V,R),Map,MapF,Goal,red(NL,K,NV,NR)) :- - partial_map(L,Map,MapI,Goal,NL), +partial_map(T,[],[],_,_,T) :- !. +partial_map(black([],_,_,_),Map,Map,Nil,_,Nil) :- !. +partial_map(red(L,K,V,R),Map,MapF,Nil,Goal,red(NL,K,NV,NR)) :- + partial_map(L,Map,MapI,Nil,Goal,NL), + ( + Map == [] -> + NR = R, NV = V + ; + MapI = [K1|MapR], + ( + K == K1 -> + once(call(Goal,V,NV)), + Map2 = MapR + ; + Map2 = [K1|MapR], NV = V + ), + partial_map(R,Map2,MapF,Nil,Goal,NR) + ). +partial_map(black(L,K,V,R),Map,MapF,Nil,Goal,black(NL,K,NV,NR)) :- + partial_map(L,Map,MapI,Nil,Goal,NL), ( MapI == [] -> NR = R, NV = V @@ -655,25 +675,9 @@ partial_map(red(L,K,V,R),Map,MapF,Goal,red(NL,K,NV,NR)) :- Map2 = MapR ; Map2 = [K1|MapR], NV = V - ) - ), - partial_map(R,Map2,MapF,Goal,NR). -partial_map(black(L,K,V,R),Map,MapF,Goal,black(NL,K,NV,NR)) :- - partial_map(L,Map,MapI,Goal,NL), - ( - MapI == [] -> - NR = R, NV = V - ; - MapI = [K1|MapR], - ( - K == K1 -> - once(call(Goal,V,NV)), - Map2 = MapR - ; - Map2 = [K1|MapR], NV = V - ) - ), - partial_map(R,Goal,Map2,MapF,NR). + ), + partial_map(R,Map2,MapF,Nil,Goal,NR) + ). % diff --git a/library/undgraphs.yap b/library/undgraphs.yap index a248b876f..1f211ea41 100644 --- a/library/undgraphs.yap +++ b/library/undgraphs.yap @@ -14,11 +14,13 @@ undgraph_del_edges/3, undgraph_del_vertex/3, undgraph_del_vertices/3, + undgraph_edge/3, undgraph_edges/2, undgraph_vertices/2, - undgraph_neighbors/2, - undgraph_neighbours/2, - undgraph_complement/2]). + undgraph_neighbors/3, + undgraph_neighbours/3, + undgraph_complement/2, + dgraph_to_undgraph/2]). :- use_module( library(dgraphs), [ @@ -31,11 +33,13 @@ dgraph_del_edges/3, dgraph_del_vertex/3, dgraph_del_vertices/3, + dgraph_edge/3, dgraph_edges/2, dgraph_vertices/2, - dgraph_neighbors/2, - dgraph_neighbours/2, - dgraph_complement/2]). + dgraph_neighbors/3, + dgraph_neighbours/3, + dgraph_complement/2, + dgraph_symmetric_closure/2]). :- use_module(library(ordsets), [ ord_del_element/3, @@ -43,7 +47,9 @@ ord_subtract/3]). :- use_module(library(rbtrees), - [ rb_delete/4]). + [ rb_delete/4, + rb_partial_map/4 + ]). undgraph_new(Vertices) :- dgraph_new(Vertices). @@ -54,7 +60,7 @@ undgraph_add_edge(V1,V2,Vs0,Vs2) :- undgraph_add_edges(Edges) --> { dup_edges(Edges, DupEdges) }, - dgraph_add_edges(Edges). + dgraph_add_edges(DupEdges). dup_edges([],[]). dup_edges([E1-E2|Edges], [E1-E2,E2-E1|DupEdges]) :- @@ -84,10 +90,22 @@ undgraph_vertices(Vs,Vertices) :- undgraph_neighbours(V,Vertices,Children) :- dgraph_neighbours(V,Vertices,Children0), - ord_del_element(V,Children0,Children). + ( + ord_del_element(Children0,V,Children) + -> + true + ; + Children = Children0 + ). undgraph_neighbors(V,Vertices,Children) :- dgraph_neighbors(V,Vertices,Children0), - ord_del_element(V,Children0,Children). + ( + ord_del_element(Children0,V,Children) + -> + true + ; + Children = Children0 + ). undgraph_complement(Vs0,VsF) :- dgraph_complement(Vs0,VsF). @@ -104,7 +122,13 @@ undgraph_del_edges(Edges) --> undgraph_del_vertex(V, Vs0, Vsf) :- rb_delete(Vs0, V, BackEdges, Vsi), - ord_del_element(BackEdges,V,RealBackEdges), + ( + ord_del_element(BackEdges,V,RealBackEdges) + -> + true + ; + BackEdges = RealBackEdges + ), rb_partial_map(Vsi, RealBackEdges, del_edge(V), Vsf). undgraph_del_vertices(Vs) --> @@ -127,7 +151,13 @@ delete_remaining_edges(SortedVs, TrueBackEdges, Vs0,Vsf) :- del_edges(ToRemove,E0,E) :- ord_subtract(E0,ToRemove,E). -del_edges(ToRemove,E0,E) :- +del_edge(ToRemove,E0,E) :- ord_del_element(E0,ToRemove,E). +dgraph_to_undgraph(G, U) :- + dgraph_symmetric_closure(G, U). + +undgraph_edge(N1, N2, G) :- + dgraph_edge(N1, N2, G). +