Topological sort: Difference between revisions
→{{header|ATS}}
Line 526:
in
abstype
assume
fn
{n : nat}
{b : int | b == 0 || b == 1}
Line 538:
fn
marks_set_at
{n : int}
{i : nat | i < n}
Line 549:
fn
marks_get_at
{n : int}
{i : nat | i < n}
Line 559:
fn
marks_setall
{n : int}
{b : int | b == 0 || b == 1}
Line 577:
end
overload [] with
overload [] with
overload setall with
end
Line 592:
entries of each sublist forms the list of dependencies of the first
entry. Thus this is a kind of association list. *)
typedef
typedef
typedef
{n : int}
{i : nat | i <= n}
Line 607:
make_char_skipper
(match : char -<> bool)
:<>
let
fun
Line 679:
i : size_t i)
:<!wrt> [j : int | i <= j; j <= n]
@(
let
fun
loop {i : nat | i <= n}
.<n - i>.
(desc :
i : size_t i)
:<!wrt> [j : int | i <= j; j <= n]
@(
let
val i = skip_spaces (text, n, i)
Line 732:
fn
read_depdesc ()
:
let
val text = read_to_string ()
Line 747:
(* An ordered list of the node names. *)
typedef
(* A more efficient representation for nodes: integers in 0..n. *)
typedef
(* A collection of directed edges. *)
typedef
(* An internal representation of data for a topological sort. *)
typedef
'{
n = size_t n, (* The number of nodes. *)
edges =
tempmarks =
permmarks =
}
fn
collect_nodenames
(desc :
:<!wrt> [n : nat]
@(
size_t n) =
let
Line 777:
.<m>.
(row : list (String1, m),
names : &
n : &size_t n0 >> size_t n1)
:<!wrt> #[n1 : int | n0 <= n1]
Line 802:
.<m>.
(desc : list (List1 String1, m),
names : &
n : &size_t n0 >> size_t n1)
:<!wrt> #[n1 : int | n0 <= n1]
Line 824:
nodename_number
{n : int}
(nodenames :
name : String1)
:<> Option (
let
fun
loop {i : nat | i <= n}
.<n - i>.
(names :
i : size_t i)
:<> Option (
case+ names of
| NIL => None ()
Line 849:
fn
add_edge {n : int}
(edges :
from :
to :
:<!refwrt> void =
(* This implementation does not store duplicate edges. *)
let
val old_edges = edges[from]
implement list_find$pred<
in
case+ list_find_opt<
| ~ None_vt () => edges[from] := to :: old_edges
| ~ Some_vt _ => ()
Line 867:
{n : int}
{m : int}
(edges :
n : size_t n,
desc :
nodenames :
:<!refwrt> void =
let
Line 893:
{m1 : nat}
.<m1>.
(headnum :
lst : list (String1, m1))
:<!refwrt> void =
Line 929:
fn
topodata_make
(desc :
:<!refwrt> [n : nat]
@(
let
val @(nodenames, n) = collect_nodenames desc
Line 939:
prval [n : int] EQINT () = eqint_make_guint n
val edges = arrayref_make_elt<List0 (
val () = fill_edges {n} (edges, n, desc, nodenames)
val tempmarks =
and permmarks =
val topo =
Line 963:
*)
(* What return values are made from. *)
datatype toporesult (a : t@ype, n : int) =
| {0 <= n}
Topo_SUCCESS (a, n) of list (a, n)
| Topo_CYCLE (a, n) of List1 a
typedef toporesult (a : t@ype) = [n : int] toporesult (a, n)
fn
find_unmarked_node
{n : int}
(topo :
:<!ref> Option (
let
val n = topo.n
Line 979 ⟶ 986:
.<n - i>.
(i : size_t i)
:<!ref> Option (
if i = n then
None ()
Line 992 ⟶ 999:
fun
visit {n : int}
(topo :
nodenum :
accum : List0 (
: toporesult (nodenum n) =
(* Probably it is cumbersome to include a proof this routine
terminates. Thus I will not try to
let
val
and edges = topo.edges
and tempmarks = topo.tempmarks
and permmarks = topo.permmarks
in
if permmarks[nodenum] = 1 then
else if tempmarks[nodenum] = 1 then
val () = assertloc (isneqz path)
in▼
Topo_CYCLE (list_vt2t (reverse path))
else
let
Line 1,013 ⟶ 1,026:
{k : nat}
.<k>.
(topo :
to_visit : list (
accum : List0 (
: toporesult (nodenum n) =
case+ to_visit of
| NIL =>
| node_to_visit :: tail =>
begin
case+ visit (topo, node_to_visit, accum, path) of
|
| other => other
end
in
tempmarks[nodenum] := 1;
case+ recursive_visits (topo, edges[nodenum], accum
|
begin
tempmarks[nodenum] := 0;
permmarks[nodenum] := 1;
end
| other => other
end
end
Line 1,041 ⟶ 1,057:
topological_sort
{n : int}
(topo :
: toporesult (nodenum n, n) =
let
prval () = lemma_arrayref_param (topo.edges)
fun
sort (accum : List0 (
:
case+ find_unmarked_node topo of
| None () =>
Line 1,056 ⟶ 1,071:
val () = assertloc (i2sz (length accum) = topo.n)
in
end
| Some nodenum =>
begin
case+ visit (topo, nodenum, accum, NIL) of
|
|
end
Line 1,081 ⟶ 1,096:
fn
find_a_valid_order
(desc :
▲ : Option (List0 String1) =
let
val @(topo, nodenames) =
case+ topological_sort topo of▼
| Some valid_order =>▼
▲ let
val nodenames_array =▼
arrayref_make_list<String1> (sz2i (topo.n), nodenames)▼
▲ prval [n : int] EQINT () = eqint_make_guint (topo.n)
▲ in
macdef map =
▲ case+ topological_sort topo of
Topo_SUCCESS (list_vt2t (map valid_order))
| Topo_CYCLE cycle =>
Topo_CYCLE (list_vt2t (map cycle))
end
Line 1,112 ⟶ 1,127:
in
case+ find_a_valid_order desc of
| Topo_SUCCESS valid_order =>
| Topo_CYCLE cycle =>
let
val last = list_last cycle
val cycl = list_vt2t (reverse (last :: cycle))
▲ in
println! ("COMPILATION CYCLE: ", cycl : List0 string)
end
end
Line 1,142 ⟶ 1,164:
ieee, dware, dw05, dw06, dw07, gtech, dw01, dw04, dw02, std_cell_lib, synopsys, std, dw03, ramlib, des_system_lib
</pre>
AND ...
Data fed to standard input:
<pre>
a b; b d; d a e; e a;
</pre>
Data from standard output:
<pre>
COMPILATION CYCLE: b, d, e, a, b
</pre>
=={{header|Bracmat}}==
|