use ReferenceMatrix for topological sort

This commit is contained in:
Folkert 2022-05-20 13:02:28 +02:00
parent 8c358332c8
commit c190bfa2fe
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
5 changed files with 24 additions and 15 deletions

1
Cargo.lock generated
View file

@ -3474,7 +3474,6 @@ dependencies = [
"roc_types", "roc_types",
"target-lexicon", "target-lexicon",
"tempfile", "tempfile",
"ven_graph",
] ]
[[package]] [[package]]

View file

@ -26,7 +26,6 @@ roc_collections = { path = "../compiler/collections" }
roc_target = { path = "../compiler/roc_target" } roc_target = { path = "../compiler/roc_target" }
roc_error_macros = { path = "../error_macros" } roc_error_macros = { path = "../error_macros" }
bumpalo = { version = "3.8.0", features = ["collections"] } bumpalo = { version = "3.8.0", features = ["collections"] }
ven_graph = { path = "../vendor/pathfinding" }
target-lexicon = "0.12.3" target-lexicon = "0.12.3"
clap = { version = "3.1.15", default-features = false, features = ["std", "color", "suggestions", "derive"] } clap = { version = "3.1.15", default-features = false, features = ["std", "color", "suggestions", "derive"] }

View file

@ -5,7 +5,6 @@ use roc_mono::layout::UnionLayout;
use roc_std::RocDec; use roc_std::RocDec;
use roc_target::TargetInfo; use roc_target::TargetInfo;
use std::convert::TryInto; use std::convert::TryInto;
use ven_graph::topological_sort;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct TypeId(usize); pub struct TypeId(usize);
@ -52,16 +51,28 @@ impl Types {
} }
pub fn sorted_ids(&self) -> Vec<TypeId> { pub fn sorted_ids(&self) -> Vec<TypeId> {
// TODO: instead use the bitvec matrix type we use in the Roc compiler - use roc_collections::{ReferenceMatrix, TopologicalSort};
// it's more efficient and also would bring us one step closer to dropping
// the dependency on this topological_sort implementation! let mut matrix = ReferenceMatrix::new(self.by_id.len());
topological_sort(self.ids(), |id| match self.deps.get(id) {
Some(dep_ids) => dep_ids.to_vec(), for type_id in self.ids() {
None => Vec::new(), for dep in self.deps.get(&type_id).iter().flat_map(|x| x.iter()) {
}) matrix.set_row_col(type_id.0, dep.0, true);
.unwrap_or_else(|err| { }
unreachable!("Cyclic type definitions: {:?}", err); }
})
match matrix.topological_sort_into_groups() {
TopologicalSort::Groups { groups } => groups
.into_iter()
.flatten()
.rev()
.map(|n| TypeId(n as usize))
.collect(),
TopologicalSort::HasCycles {
groups: _,
nodes_in_cycle,
} => unreachable!("Cyclic type definitions: {:?}", nodes_in_cycle),
}
} }
pub fn iter(&self) -> impl ExactSizeIterator<Item = &RocType> { pub fn iter(&self) -> impl ExactSizeIterator<Item = &RocType> {

View file

@ -10,7 +10,7 @@ mod vec_map;
mod vec_set; mod vec_set;
pub use all::{default_hasher, BumpMap, ImEntry, ImMap, ImSet, MutMap, MutSet, SendMap}; pub use all::{default_hasher, BumpMap, ImEntry, ImMap, ImSet, MutMap, MutSet, SendMap};
pub use reference_matrix::{ReferenceMatrix, Sccs}; pub use reference_matrix::{ReferenceMatrix, Sccs, TopologicalSort};
pub use small_string_interner::SmallStringInterner; pub use small_string_interner::SmallStringInterner;
pub use vec_map::VecMap; pub use vec_map::VecMap;
pub use vec_set::VecSet; pub use vec_set::VecSet;

View file

@ -154,7 +154,7 @@ impl ReferenceMatrix {
} }
} }
#[allow(dead_code)] #[derive(Debug)]
pub enum TopologicalSort { pub enum TopologicalSort {
/// There were no cycles, all nodes have been partitioned into groups /// There were no cycles, all nodes have been partitioned into groups
Groups { groups: Vec<Vec<u32>> }, Groups { groups: Vec<Vec<u32>> },