Skip to content

Commit c13294b

Browse files
committed
wip
1 parent 1475c24 commit c13294b

File tree

13 files changed

+337
-186
lines changed

13 files changed

+337
-186
lines changed

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ rayon = "1.10.0"
1616
itertools = "0.14.0"
1717

1818
[profile.release]
19-
strip = true # Supprime les symboles de débogage
20-
lto = true # Optimisation inter-procédurale (Link-Time Optimization)
19+
#strip = true # Supprime les symboles de débogage
20+
#lto = true # Optimisation inter-procédurale (Link-Time Optimization)
21+
22+
#profile mode
23+
#debug = true

examples/bottleneck-2-free.pdf

0 Bytes
Binary file not shown.

examples/bottleneck-2-staged.pdf

1 Byte
Binary file not shown.

src/coef.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
11
use std::fmt;
2+
use std::hash::{Hash, Hasher};
23
use std::iter::Sum;
34
use std::ops::{Add, AddAssign, Sub};
45

5-
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
6+
pub type coef = u8;
7+
8+
#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord)]
69
pub enum Coef {
7-
Value(u16),
10+
Value(coef),
811
Omega,
912
}
13+
14+
impl Hash for Coef {
15+
fn hash<H: Hasher>(&self, state: &mut H) {
16+
self.as_coef().hash(state);
17+
}
18+
}
19+
1020
impl Coef {
11-
pub(crate) fn round_up(&self, max_finite_value: u16) -> Coef {
21+
pub(crate) fn round_up(&self, max_finite_value: coef) -> Coef {
1222
match self {
1323
Coef::Value(x) if *x > max_finite_value => Coef::Omega,
1424
_ => *self,
1525
}
1626
}
27+
28+
pub fn as_coef(&self) -> coef {
29+
match self {
30+
Coef::Value(v) => *v,
31+
Coef::Omega => coef::MAX, // associate 42 as the value of Omega
32+
}
33+
}
1734
}
1835

1936
pub const C0: Coef = Coef::Value(0);

src/flow.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
1-
use crate::coef::{Coef, C0, C1, OMEGA};
1+
use crate::coef::{coef, Coef, C0, C1, OMEGA};
22
use crate::graph::Graph;
3-
use crate::nfa;
43
use crate::partitions;
54
use crate::sheep;
65
use crate::sheep::Sheep;
76
use itertools::Itertools;
87
use std::fmt;
8+
use std::hash::{Hash, Hasher};
99
use std::iter::Sum;
1010
use std::ops::{Add, AddAssign, Mul, Sub};
1111
use std::{collections::HashSet, vec::Vec}; // Import the itertools crate for multi_cartesian_product
12-
1312
pub type Domain = Vec<Coef>;
1413

15-
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
14+
#[derive(Eq, PartialEq, Clone, Debug)]
1615
pub struct Flow {
1716
pub nb_rows: usize,
1817
pub nb_cols: usize,
1918
//size is nb_rows * nb_cols
2019
entries: Vec<Coef>,
2120
}
2221

22+
impl Hash for Flow {
23+
fn hash<H: Hasher>(&self, state: &mut H) {
24+
self.entries.hash(state);
25+
}
26+
}
27+
2328
impl PartialOrd for Flow {
2429
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
2530
let self_is_smaller_than_other =
@@ -176,7 +181,7 @@ impl Flow {
176181
let i0 = i * dim;
177182
for j in 0..dim {
178183
//invariant k = i * dim + j
179-
let mut resultk: u16 = 0;
184+
let mut resultk: coef = 0;
180185
let mut li = i0;
181186
let mut lj = j;
182187
let mut is_omega = false;
@@ -318,7 +323,7 @@ impl Flow {
318323
///computes the preimage of a target set of states
319324
/// that is the maximal ideal from which there exists a path to the target states
320325
/// finite coordinates are summed up...
321-
pub fn pre_image(&self, target: &[nfa::State]) -> Sheep {
326+
pub fn pre_image(&self, target: &[usize]) -> Sheep {
322327
Sheep::from_vec(
323328
(0..self.nb_rows)
324329
.map(|i| target.iter().map(|&j| self.get(&i, &j)).sum::<Coef>())
@@ -453,6 +458,10 @@ impl Flow {
453458
fn is_empty(&self) -> bool {
454459
self.nb_cols == 0 && self.nb_rows == 0
455460
}
461+
462+
pub(crate) fn is_idempotent(&self) -> bool {
463+
self * self == *self
464+
}
456465
}
457466

458467
impl fmt::Display for Flow {

src/ideal.rs

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::coef::{Coef, C0, OMEGA};
1+
use crate::coef::{coef, Coef, C0, OMEGA};
22
use crate::memoizer::Memoizer;
3+
use crate::partitions;
34
use crate::sheep::Sheep;
4-
use crate::{coef, partitions};
55
use cached::proc_macro::cached;
66
use itertools::Itertools;
77
use log::debug;
@@ -157,12 +157,13 @@ impl Ideal {
157157
changed
158158
}
159159

160+
/*
160161
pub(crate) fn restrict_to_preimage_of(
161162
&mut self,
162163
safe_target: &Ideal,
163164
edges: &crate::graph::Graph,
164165
dim: usize,
165-
max_finite_value: u16,
166+
max_finite_value: coef,
166167
) -> bool {
167168
let mut changed = false;
168169
let mut new_sheeps = Ideal::new();
@@ -195,7 +196,7 @@ impl Ideal {
195196
debug!("new ideal\n{}", self);
196197
}
197198
changed
198-
}
199+
}*/
199200

200201
/// Compute the safe-pre-image of the ideal by a graph.
201202
/// Unsafe is:
@@ -234,7 +235,7 @@ impl Ideal {
234235
pub(crate) fn safe_pre_image(
235236
&self,
236237
edges: &crate::graph::Graph,
237-
maximal_finite_coordinate: u16,
238+
maximal_finite_coordinate: coef,
238239
) -> Ideal {
239240
debug!("safe_pre_image\nself\n{}\nedges\n{}", self, edges);
240241
let dim = edges.dim();
@@ -253,7 +254,7 @@ impl Ideal {
253254

254255
//compute for every j the maximal finite coef appearing at index j, if exists
255256
//omega are turned to 1
256-
let max_finite_coordsj: Vec<u16> = (0..dim)
257+
let max_finite_coordsj: Vec<coef> = (0..dim)
257258
.map(|j: usize| {
258259
self.0
259260
.iter()
@@ -288,10 +289,10 @@ impl Ideal {
288289
max_finite_coordsi.get(i).unwrap(),
289290
is_omega_possible.get(i).unwrap(),
290291
) {
291-
(0, false) => vec![coef::Coef::Value(0)],
292+
(0, false) => vec![Coef::Value(0)],
292293
(0, true) => vec![OMEGA],
293-
(&c, false) => vec![coef::Coef::Value(c)],
294-
(&c, true) => vec![OMEGA, coef::Coef::Value(c)],
294+
(&c, false) => vec![Coef::Value(c)],
295+
(&c, true) => vec![OMEGA, Coef::Value(c)],
295296
}
296297
})
297298
.collect::<Vec<_>>();
@@ -317,11 +318,12 @@ impl Ideal {
317318
}
318319

319320
/* naive exponential impl of get_intersection_with_safe_ideal*/
321+
/*
320322
fn get_intersection_with_safe_ideal(
321323
sheep: &Sheep,
322324
edges: &crate::graph::Graph,
323325
safe_target: &Ideal,
324-
maximal_finite_value: u16,
326+
maximal_finite_value: coef,
325327
) -> Ideal {
326328
/*
327329
println!(
@@ -361,7 +363,7 @@ impl Ideal {
361363
}
362364
result.minimize();
363365
result
364-
}
366+
}*/
365367

366368
#[allow(dead_code)]
367369
//below is a sad story: an optimized version of safe_pre_image which is extremely slow
@@ -370,7 +372,7 @@ impl Ideal {
370372
candidate: &Sheep,
371373
edges: &crate::graph::Graph,
372374
accumulator: &mut Ideal,
373-
maximal_finite_coordinate: u16,
375+
maximal_finite_coordinate: coef,
374376
) {
375377
if accumulator.contains(candidate) {
376378
//println!("{} already in ideal", candidate);
@@ -440,7 +442,7 @@ impl Ideal {
440442
&self,
441443
candidate: &Sheep,
442444
edges: &crate::graph::Graph,
443-
maximal_finite_coordinate: u16,
445+
maximal_finite_coordinate: coef,
444446
) -> bool {
445447
let dim = edges.dim() as usize;
446448

@@ -482,7 +484,7 @@ impl Ideal {
482484
dim: usize,
483485
dom: &Sheep,
484486
edges: &crate::graph::Graph,
485-
max_finite_value: u16,
487+
max_finite_value: coef,
486488
) -> Ideal {
487489
let mut ideal = Ideal::new();
488490
let choices = (0..dom.len())
@@ -511,37 +513,39 @@ impl Ideal {
511513
ideal
512514
}
513515

514-
pub(crate) fn round_down(&mut self, upper_bound: u16, dim: usize) {
516+
/// Removes sheep with precision >.
517+
pub(crate) fn round_down(&mut self, maximal_finite_value: coef, dim: usize) {
515518
let to_remove: Vec<Sheep> = self
516519
.0
517520
.iter()
518-
.filter(|s| s.some_finite_coordinate_is_larger_than(upper_bound))
521+
.filter(|s| s.some_finite_coordinate_is_larger_than(maximal_finite_value))
519522
.cloned()
520523
.collect();
521524
for mut sheep in to_remove {
522525
self.0.remove(&sheep);
523-
sheep.round_down(upper_bound, dim);
526+
sheep.round_down(maximal_finite_value, dim);
524527
self.0.insert(sheep);
525528
}
526529
}
527530

531+
/*
528532
fn is_safe(
529533
sheep: &Sheep,
530534
edges: &crate::graph::Graph,
531535
safe_target: &Ideal,
532536
dim: usize,
533-
max_finite_value: u16,
537+
max_finite_value: coef,
534538
) -> bool {
535539
let image: Ideal = Self::get_image(dim, sheep, edges, max_finite_value);
536540
let result = image.sheeps().all(|other| safe_target.contains(other));
537541
result
538-
}
542+
}*/
539543
}
540544

541545
#[cached]
542546
fn get_choices(dim: usize, value: Coef, successors: Vec<usize>) -> Vec<Sheep> {
543547
//println!("get_choices({}, {:?}, {:?})", dim, value, successors);
544-
//assert!(value == OMEGA || value <= Coef::Value(dim as u16));
548+
//assert!(value == OMEGA || value <= Coef::Value(dim as coef));
545549
match value {
546550
C0 => vec![Sheep::new(dim, C0)],
547551
OMEGA => {
@@ -552,7 +556,7 @@ fn get_choices(dim: usize, value: Coef, successors: Vec<usize>) -> Vec<Sheep> {
552556
vec![Sheep::from_vec(base)]
553557
}
554558
Coef::Value(c) => {
555-
let transports: Vec<Vec<u16>> = partitions::get_transports(c, successors.len());
559+
let transports: Vec<Vec<coef>> = partitions::get_transports(c, successors.len());
556560
let mut result: Vec<Sheep> = Vec::new();
557561
for transport in transports {
558562
let mut vec = vec![C0; dim];
@@ -668,7 +672,7 @@ mod test {
668672
let edges = crate::graph::Graph::from_vec(dim, vec![(0, 1), (0, 2)]);
669673
let ideal = Ideal::from_vecs(&[&[C0, C1, C0], &[C0, C0, C1]]);
670674
let candidate = Sheep::from_vec(vec![C1, C0, C0]);
671-
assert!(ideal.is_safe_with_roundup(&candidate, &edges, dim as u16));
675+
assert!(ideal.is_safe_with_roundup(&candidate, &edges, dim as coef));
672676
}
673677

674678
#[test]
@@ -678,7 +682,7 @@ mod test {
678682
let edges = crate::graph::Graph::from_vec(dim, vec![(0, 1), (0, 2)]);
679683
let ideal = Ideal::from_vecs(&[&[C0, c4, C0], &[C0, C0, c4]]);
680684
let candidate = Sheep::from_vec(vec![c4, C0, C0]);
681-
assert!(!ideal.is_safe_with_roundup(&candidate, &edges, dim as u16));
685+
assert!(!ideal.is_safe_with_roundup(&candidate, &edges, dim as coef));
682686
}
683687

684688
#[test]
@@ -688,7 +692,7 @@ mod test {
688692
let edges = crate::graph::Graph::from_vec(dim, vec![(0, 1), (0, 2)]);
689693
let ideal = Ideal::from_vecs(&[&[C0, c3, C0], &[C0, C2, C1], &[C0, C1, C2], &[C0, C0, c3]]);
690694
let candidate = Sheep::from_vec(vec![c3, C0, C0]);
691-
assert!(ideal.is_safe_with_roundup(&candidate, &edges, dim as u16));
695+
assert!(ideal.is_safe_with_roundup(&candidate, &edges, dim as coef));
692696
}
693697

694698
#[test]
@@ -699,7 +703,7 @@ mod test {
699703
let edges = crate::graph::Graph::from_vec(3, vec![(0, 1), (0, 2)]);
700704
let ideal = Ideal::from_vecs(&[&[C0, c3, C0], &[C0, C0, c3]]);
701705
let candidate = Sheep::from_vec(vec![c4, C0, C0]);
702-
assert!(!ideal.is_safe_with_roundup(&candidate, &edges, dim as u16));
706+
assert!(!ideal.is_safe_with_roundup(&candidate, &edges, dim as coef));
703707
}
704708

705709
#[test]
@@ -711,7 +715,7 @@ mod test {
711715
);
712716
let ideal0 = Ideal::from_vecs(&[&[C0, C1, C2, OMEGA]]);
713717

714-
let pre_image0 = ideal0.safe_pre_image(&edges, dim as u16);
718+
let pre_image0 = ideal0.safe_pre_image(&edges, dim as coef);
715719
assert_eq!(
716720
pre_image0,
717721
Ideal::from_vecs(&[&[C0, C1, C1, OMEGA], &[C0, C0, C2, OMEGA]]),
@@ -726,7 +730,7 @@ mod test {
726730
vec![(0, 0), (1, 1), (1, 2), (2, 2), (2, 3), (3, 3)],
727731
);
728732
let ideal1 = Ideal::from_vecs(&[&[OMEGA, C1, C2, OMEGA], &[OMEGA, C2, C1, OMEGA]]);
729-
let pre_image1 = ideal1.safe_pre_image(&edges, dim as u16);
733+
let pre_image1 = ideal1.safe_pre_image(&edges, dim as coef);
730734
assert_eq!(
731735
pre_image1,
732736
Ideal::from_vecs(&[
@@ -755,7 +759,7 @@ mod test {
755759
&[C0, OMEGA, C0, C0],
756760
&[OMEGA, C0, C0, C0],
757761
]);
758-
let pre_image0 = ideal0.safe_pre_image(&edges, dim as u16);
762+
let pre_image0 = ideal0.safe_pre_image(&edges, dim as coef);
759763
assert_eq!(pre_image0, Ideal::from_vecs(&[&[C0, C0, OMEGA, C0]]));
760764
}
761765

@@ -779,7 +783,7 @@ mod test {
779783
(5, 5),
780784
],
781785
);
782-
let pre_image0 = ideal0.safe_pre_image(&edges, dim as u16);
786+
let pre_image0 = ideal0.safe_pre_image(&edges, dim as coef);
783787
assert_eq!(
784788
pre_image0,
785789
Ideal::from_vecs(&[&[OMEGA, OMEGA, OMEGA, C0, OMEGA, C0]])
@@ -811,7 +815,7 @@ mod test {
811815
6,
812816
vec![(0, 0), (1, 2), (1, 3), (3, 4), (2, 5), (4, 4), (5, 5)],
813817
);
814-
let pre_image0 = ideal0.safe_pre_image(&edges, dim as u16);
818+
let pre_image0 = ideal0.safe_pre_image(&edges, dim as coef);
815819
assert_eq!(
816820
pre_image0,
817821
Ideal::from_vecs(&[&[OMEGA, C1, C0, OMEGA, OMEGA, C0]])
@@ -829,7 +833,7 @@ mod test {
829833
&[C0, OMEGA, C0, OMEGA, OMEGA],
830834
]);
831835
let candidate = Sheep::from_vec(vec![c5, C0, C0, C0, C0]);
832-
assert!(!ideal.is_safe_with_roundup(&candidate, &edges, dim as u16));
836+
assert!(!ideal.is_safe_with_roundup(&candidate, &edges, dim as coef));
833837
}
834838

835839
#[test]
@@ -854,7 +858,7 @@ mod test {
854858
&[OMEGA, C0, C0, C0, C0],
855859
]);
856860
let edges = crate::graph::Graph::from_vec(dim, vec![(0, 1), (0, 2), (0, 4)]);
857-
let pre_image0 = ideal0.safe_pre_image(&edges, dim as u16);
861+
let pre_image0 = ideal0.safe_pre_image(&edges, dim as coef);
858862
assert_eq!(pre_image0, Ideal::from_vecs(&[&[C2, C0, C0, C0, C0]]));
859863
}
860864
}

0 commit comments

Comments
 (0)