[m-rev.] for review: Add synonyms for digraph sc, tc, rtc.

Peter Wang novalazy at gmail.com
Thu Jan 19 12:05:32 AEDT 2023


library/digraph.m:
    Add non-abbreviated synonyms for digraph.sc, digraph.tc, and
    digraph.rtc.

NEWS:
    Announce additions.

diff --git a/NEWS b/NEWS
index fcb77a6e9..7a7f43b89 100644
--- a/NEWS
+++ b/NEWS
@@ -156,7 +156,14 @@ Changes to the Mercury standard library
    - The `digraph_key(T)` type is now an instance of the `uenum` typeclass,
      and is no longer an instance of the `enum` typeclass.
 
-* We have fixed the implementations of `digraph.tc` and `digraph.rtc`.
+* The following functions have been added:
+
+    - func `symmetric_closure/1`            (synonym for `sc/1`)
+    - func `transitive_closure/1`           (synonym for `tc/1`)
+    - func `reflexive_transitive_closure/1` (synonym for `rtc/1`)
+
+* We have fixed and improved the implementations of transitive closure and
+  reflexive transitive closure.
 
 ### Changes to the `enum` module
 
diff --git a/library/digraph.m b/library/digraph.m
index fb54b00f0..6210662f5 100644
--- a/library/digraph.m
+++ b/library/digraph.m
@@ -334,11 +334,19 @@
 :- func sc(digraph(T)) = digraph(T).
 :- pred sc(digraph(T)::in, digraph(T)::out) is det.
 
+    % A synonym for sc/1.
+    %
+:- func symmetric_closure(digraph(T)) = digraph(T).
+
     % tc(G, TC) is true if TC is the transitive closure of G.
     %
 :- func tc(digraph(T)) = digraph(T).
 :- pred tc(digraph(T)::in, digraph(T)::out) is det.
 
+    % A synonym for tc/1.
+    %
+:- func transitive_closure(digraph(T)) = digraph(T).
+
     % rtc(G, RTC) is true if RTC is the reflexive transitive closure of G.
     %
     % RTC is the reflexive closure of the transitive closure of G,
@@ -347,6 +355,10 @@
 :- func rtc(digraph(T)) = digraph(T).
 :- pred rtc(digraph(T)::in, digraph(T)::out) is det.
 
+    % A synonym for rtc/1.
+    %
+:- func reflexive_transitive_closure(digraph(T)) = digraph(T).
+
     % traverse(G, ProcessVertex, ProcessEdge, !Acc) will traverse the digraph G
     % - calling ProcessVertex for each vertex in the digraph, and
     % - calling ProcessEdge for each edge in the digraph.
@@ -1071,20 +1083,24 @@ atsort_loop([X | Xs], GInv, !.Vis, !ATsort) :-
 
 %---------------------------------------------------------------------------%
 
-sc(G) = Sc :-
-    digraph.sc(G, Sc).
+sc(G) = symmetric_closure(G).
 
 sc(G, Sc) :-
+    Sc = symmetric_closure(G).
+
+symmetric_closure(G) = Sc :-
     digraph.inverse(G, GInv),
     digraph.to_key_assoc_list(GInv, GInvList),
     digraph.add_assoc_list(GInvList, G, Sc).
 
 %---------------------------------------------------------------------------%
 
-tc(G) = Tc :-
-    digraph.tc(G, Tc).
+tc(G) = transitive_closure(G).
 
 tc(G, Tc) :-
+    Tc = transitive_closure(G).
+
+transitive_closure(G) = Tc :-
     simple_tc_main(G, Tc).
 
 %---------------------------------------------------------------------------%
@@ -1314,20 +1330,19 @@ add_predecessor(Y, X, !Map) :-
 
 %---------------------------------------------------------------------------%
 
-rtc(G) = Rtc :-
-    digraph.rtc(G, Rtc).
+rtc(G) = reflexive_transitive_closure(G).
 
 rtc(G, Rtc) :-
-    tc(G, Tc),
-    rc(Tc, Rtc).
+    Rtc = reflexive_transitive_closure(G).
 
-    % Reflexive closure.
-    %
-:- pred rc(digraph(T)::in, digraph(T)::out) is det.
+reflexive_transitive_closure(G) =
+    reflexive_closure(transitive_closure(G)).
 
-rc(G, RC) :-
+:- func reflexive_closure(digraph(T)) = digraph(T).
+
+reflexive_closure(G) = Rc :-
     digraph.keys(G, Keys),
-    list.foldl(add_reflexive, Keys, G, RC).
+    list.foldl(add_reflexive, Keys, G, Rc).
 
 :- pred add_reflexive(digraph_key(T)::in,
     digraph(T)::in, digraph(T)::out) is det.
-- 
2.39.0



More information about the reviews mailing list