Compare commits

..

No commits in common. "1e6f3ddbff436666f900094093f8b6c696139798" and "0c98a38e76289fb7ebc987406cb0fa4c15904734" have entirely different histories.

5 changed files with 481 additions and 1862 deletions

1336
src/lib.rs

File diff suppressed because it is too large Load diff

View file

@ -7,17 +7,24 @@ use otvec::Operation;
use util::{print_cond_catch_ctr, test_transform_cond, test_transform_cond_catch, CondCatchCtr}; use util::{print_cond_catch_ctr, test_transform_cond, test_transform_cond_catch, CondCatchCtr};
const ALL_SIZE: usize = 20; const ALL_SIZE: usize = 20;
const MIN_RANGE_LEN: usize = 1;
const TEST_SIZE: usize = 9;
const TEST_MIN_RANGE_LEN: usize = 1;
const VEC_SIZE: usize = 100; const VEC_SIZE: usize = 100;
fn testvec(len: usize) -> Vec<usize> { fn testvec(len: usize) -> Vec<usize> {
(0..len).collect::<Vec<_>>() (0..len).collect::<Vec<_>>()
} }
fn filter_to(size: usize, pos: usize, to: usize) -> usize {
if pos == to {
if to >= size - 1 {
filter_to(size, pos, 0)
} else {
filter_to(size, pos, to + 1)
}
} else {
to
}
}
fn t_ins_ins(size: usize, a_pos: usize, a_len: usize, b_pos: usize, b_len: usize) { fn t_ins_ins(size: usize, a_pos: usize, a_len: usize, b_pos: usize, b_len: usize) {
let input = testvec(size); let input = testvec(size);
let a = Operation::Ins { let a = Operation::Ins {
@ -76,7 +83,15 @@ fn t_mov_ins(size: usize, a_pos: usize, a_len: usize, a_to: usize, b_pos: usize,
test_transform_cond(&b, &a, &input); test_transform_cond(&b, &a, &input);
} }
fn t_mov_del(size: usize, a_pos: usize, a_len: usize, a_to: usize, b_pos: usize, b_len: usize) { fn t_mov_del(
size: usize,
a_pos: usize,
a_len: usize,
a_to: usize,
b_pos: usize,
b_len: usize,
ctr: Option<&CondCatchCtr>,
) {
let input = testvec(size); let input = testvec(size);
let a = Operation::Mov { let a = Operation::Mov {
pos: a_pos, pos: a_pos,
@ -87,31 +102,6 @@ fn t_mov_del(size: usize, a_pos: usize, a_len: usize, a_to: usize, b_pos: usize,
pos: b_pos, pos: b_pos,
n: b_len, n: b_len,
}; };
test_transform_cond(&a, &b, &input);
test_transform_cond(&b, &a, &input);
}
fn t_mov_mov_catch(
size: usize,
a_pos: usize,
a_len: usize,
a_to: usize,
b_pos: usize,
b_len: usize,
b_to: usize,
ctr: Option<&CondCatchCtr>,
) {
let input = testvec(size);
let a = Operation::Mov {
pos: a_pos,
n: a_len,
to: a_to,
};
let b = Operation::Mov {
pos: b_pos,
n: b_len,
to: b_to,
};
test_transform_cond_catch(&a, &b, &input, ctr); test_transform_cond_catch(&a, &b, &input, ctr);
test_transform_cond_catch(&b, &a, &input, ctr); test_transform_cond_catch(&b, &a, &input, ctr);
} }
@ -143,13 +133,9 @@ fn t_mov_mov(
#[test] #[test]
fn all_ins_ins() { fn all_ins_ins() {
(0..ALL_SIZE).into_par_iter().for_each(|a_pos| { (0..ALL_SIZE).into_par_iter().for_each(|a_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - a_pos)) (1..(ALL_SIZE - a_pos)).into_par_iter().for_each(|a_len| {
.into_par_iter()
.for_each(|a_len| {
(0..ALL_SIZE).into_par_iter().for_each(|b_pos| { (0..ALL_SIZE).into_par_iter().for_each(|b_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - b_pos)) (1..(ALL_SIZE - b_pos)).into_par_iter().for_each(|b_len| {
.into_par_iter()
.for_each(|b_len| {
t_ins_ins(ALL_SIZE, a_pos, a_len, b_pos, b_len); t_ins_ins(ALL_SIZE, a_pos, a_len, b_pos, b_len);
}); });
}); });
@ -160,13 +146,9 @@ fn all_ins_ins() {
#[test] #[test]
fn all_del_del() { fn all_del_del() {
(0..ALL_SIZE).into_par_iter().for_each(|a_pos| { (0..ALL_SIZE).into_par_iter().for_each(|a_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - a_pos)) (1..(ALL_SIZE - a_pos)).into_par_iter().for_each(|a_len| {
.into_par_iter()
.for_each(|a_len| {
(0..ALL_SIZE).into_par_iter().for_each(|b_pos| { (0..ALL_SIZE).into_par_iter().for_each(|b_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - b_pos)) (1..(ALL_SIZE - b_pos)).into_par_iter().for_each(|b_len| {
.into_par_iter()
.for_each(|b_len| {
t_del_del(ALL_SIZE, a_pos, a_len, b_pos, b_len); t_del_del(ALL_SIZE, a_pos, a_len, b_pos, b_len);
}); });
}); });
@ -177,13 +159,9 @@ fn all_del_del() {
#[test] #[test]
fn all_ins_del() { fn all_ins_del() {
(0..ALL_SIZE).into_par_iter().for_each(|a_pos| { (0..ALL_SIZE).into_par_iter().for_each(|a_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - a_pos)) (1..(ALL_SIZE - a_pos)).into_par_iter().for_each(|a_len| {
.into_par_iter()
.for_each(|a_len| {
(0..ALL_SIZE).into_par_iter().for_each(|b_pos| { (0..ALL_SIZE).into_par_iter().for_each(|b_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - b_pos)) (1..(ALL_SIZE - b_pos)).into_par_iter().for_each(|b_len| {
.into_par_iter()
.for_each(|b_len| {
t_ins_del(ALL_SIZE, a_pos, a_len, b_pos, b_len); t_ins_del(ALL_SIZE, a_pos, a_len, b_pos, b_len);
}); });
}); });
@ -194,17 +172,13 @@ fn all_ins_del() {
#[test] #[test]
fn all_mov_ins() { fn all_mov_ins() {
(0..ALL_SIZE).into_par_iter().for_each(|a_pos| { (0..ALL_SIZE).into_par_iter().for_each(|a_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - a_pos)) (1..(ALL_SIZE - a_pos)).into_par_iter().for_each(|a_len| {
.into_par_iter() (0..ALL_SIZE).into_par_iter().for_each(|a_to| {
.for_each(|a_len| { let a_to = filter_to(ALL_SIZE, a_pos, a_to);
(0..a_pos) let a_len = a_len.min(ALL_SIZE - a_pos.max(a_to));
.into_par_iter()
.chain((a_pos + a_len + 1)..=ALL_SIZE)
.for_each(|a_to| {
(0..ALL_SIZE).into_par_iter().for_each(|b_pos| { (0..ALL_SIZE).into_par_iter().for_each(|b_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - b_pos)) (1..(ALL_SIZE - b_pos)).into_par_iter().for_each(|b_len| {
.into_par_iter()
.for_each(|b_len| {
t_mov_ins(ALL_SIZE, a_pos, a_len, a_to, b_pos, b_len); t_mov_ins(ALL_SIZE, a_pos, a_len, a_to, b_pos, b_len);
}); });
}); });
@ -215,59 +189,17 @@ fn all_mov_ins() {
#[test] #[test]
fn all_mov_del() { fn all_mov_del() {
(0..ALL_SIZE).into_par_iter().for_each(|a_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - a_pos))
.into_par_iter()
.for_each(|a_len| {
(0..a_pos)
.into_par_iter()
.chain((a_pos + a_len + 1)..=ALL_SIZE)
.for_each(|a_to| {
(0..ALL_SIZE).into_par_iter().for_each(|b_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - b_pos))
.into_par_iter()
.for_each(|b_len| {
t_mov_del(ALL_SIZE, a_pos, a_len, a_to, b_pos, b_len);
});
});
});
});
});
}
// For development (non-parallel and panic-catching)
#[test]
fn dev_all_mov_mov() {
let ctr = CondCatchCtr::default(); let ctr = CondCatchCtr::default();
(0..TEST_SIZE).into_iter().for_each(|a_pos| {
(TEST_MIN_RANGE_LEN..=(TEST_SIZE - a_pos)) (0..ALL_SIZE).into_par_iter().for_each(|a_pos| {
.into_iter() (1..(ALL_SIZE - a_pos)).into_par_iter().for_each(|a_len| {
// .rev() (0..ALL_SIZE).into_par_iter().for_each(|a_to| {
.for_each(|a_len| { let a_to = filter_to(ALL_SIZE, a_pos, a_to);
(0..a_pos) let a_len = a_len.min(ALL_SIZE - a_pos.max(a_to));
.into_iter()
.chain((a_pos + a_len + 1)..=TEST_SIZE) (0..ALL_SIZE).into_par_iter().for_each(|b_pos| {
.for_each(|a_to| { (1..(ALL_SIZE - b_pos)).into_par_iter().for_each(|b_len| {
(0..TEST_SIZE).into_iter().for_each(|b_pos| { t_mov_del(ALL_SIZE, a_pos, a_len, a_to, b_pos, b_len, Some(&ctr));
(TEST_MIN_RANGE_LEN..=(TEST_SIZE - b_pos))
.into_iter()
// .rev()
.for_each(|b_len| {
(0..b_pos)
.into_iter()
.chain((b_pos + b_len + 1)..=TEST_SIZE)
.for_each(|b_to| {
t_mov_mov_catch(
TEST_SIZE,
a_pos,
a_len,
a_to,
b_pos,
b_len,
b_to,
Some(&ctr),
);
});
}); });
}); });
}); });
@ -276,114 +208,84 @@ fn dev_all_mov_mov() {
print_cond_catch_ctr(&ctr); print_cond_catch_ctr(&ctr);
} }
/*
#[test] #[test]
fn all_mov_mov() { fn all_mov_mov() {
(0..ALL_SIZE).into_par_iter().for_each(|a_pos| { (0..ALL_SIZE).into_par_iter().for_each(|a_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - a_pos)) (1..(ALL_SIZE - a_pos)).into_par_iter().for_each(|a_len| {
.into_par_iter() (0..ALL_SIZE).into_par_iter().for_each(|a_to| {
.for_each(|a_len| { let a_to = filter_to(ALL_SIZE, a_pos, a_to);
(0..a_pos) let a_len = a_len.min(ALL_SIZE - a_pos.max(a_to));
.into_par_iter()
.chain((a_pos + a_len + 1)..=ALL_SIZE)
.for_each(|a_to| {
(0..ALL_SIZE).into_par_iter().for_each(|b_pos| { (0..ALL_SIZE).into_par_iter().for_each(|b_pos| {
(MIN_RANGE_LEN..=(ALL_SIZE - b_pos)) (1..(ALL_SIZE - b_pos)).into_par_iter().for_each(|b_len| {
.into_par_iter() (0..ALL_SIZE).into_par_iter().for_each(|b_to| {
.for_each(|b_len| { let b_to = filter_to(ALL_SIZE, b_pos, b_to);
(0..b_pos) let b_len = b_len.min(ALL_SIZE - b_pos.max(b_to));
.into_par_iter()
.chain((b_pos + b_len + 1)..=ALL_SIZE)
.for_each(|b_to| {
t_mov_mov(
ALL_SIZE, a_pos, a_len, a_to, b_pos, b_len, b_to,
);
});
});
});
});
});
});
}
fn test_params() -> impl Strategy<Value = (usize, (usize, usize, usize), (usize, usize, usize))> { t_mov_mov(ALL_SIZE, a_pos, a_len, a_to, b_pos, b_len, b_to);
((MIN_RANGE_LEN + 1)..=VEC_SIZE) });
.prop_flat_map(|vec_size| (Just(vec_size), mov_params(vec_size), mov_params(vec_size))) });
} });
});
/// Parameters for a single test operation });
fn mov_params(vec_size: usize) -> impl Strategy<Value = (usize, usize, usize)> { });
(0..(vec_size - MIN_RANGE_LEN))
.prop_flat_map(move |pos| (Just(pos), MIN_RANGE_LEN..=(vec_size - pos)))
.prop_flat_map(move |(pos, len)| {
let rb = (pos + len + 1)..(vec_size + 1);
(
Just(pos),
Just(len),
match (pos > 0, rb.end > rb.start) {
(true, true) => Strategy::boxed((0..pos).prop_union(rb)),
(true, false) => Strategy::boxed(0..pos),
(false, true) => Strategy::boxed(rb),
(false, false) => Strategy::boxed(Just(pos)),
},
)
})
} }
*/
proptest! { proptest! {
#[test] #[test]
fn transform_ins_ins((vec_len, a, b) in test_params(), a_len in 1usize..VEC_SIZE, b_len in 1usize..VEC_SIZE) { fn transform_ins_ins(a_pos in 0usize..VEC_SIZE, a_len in 1usize..VEC_SIZE, b_pos in 0usize..VEC_SIZE, b_len in 1usize..VEC_SIZE) {
t_ins_ins(vec_len, a.0, a_len, b.0, b_len) t_ins_ins(VEC_SIZE, a_pos, a_len, b_pos, b_len)
} }
#[test] #[test]
fn transform_del_del((vec_len, a, b) in test_params()) { fn transform_del_del(a_pos in 0usize..VEC_SIZE, a_len in 1usize..VEC_SIZE, b_pos in 0usize..VEC_SIZE, b_len in 1usize..VEC_SIZE) {
t_del_del(vec_len, a.0, a.1, b.0, b.1) // Limit inputs
let a_len = a_len.min(VEC_SIZE - a_pos);
let b_len = b_len.min(VEC_SIZE - b_pos);
t_del_del(VEC_SIZE, a_pos, a_len, b_pos, b_len)
} }
#[test] #[test]
fn transform_ins_del((vec_len, a, b) in test_params(), i_len in 1usize..VEC_SIZE) { fn transform_ins_del(a_pos in 0usize..VEC_SIZE, a_len in 1usize..VEC_SIZE, b_pos in 0usize..VEC_SIZE, b_len in 1usize..VEC_SIZE) {
t_ins_del(vec_len, a.0, i_len, b.0, b.1) let b_len = b_len.min(VEC_SIZE - b_pos);
t_ins_del(VEC_SIZE, a_pos, a_len, b_pos, b_len)
} }
#[test] #[test]
fn transform_mov_ins((vec_len, a, b) in test_params(), i_len in 1usize..VEC_SIZE) { fn transform_mov_ins(a_len in 1usize..VEC_SIZE, a_pos in 0usize..VEC_SIZE, a_to in 0usize..VEC_SIZE, b_pos in 0usize..VEC_SIZE, b_len in 1usize..VEC_SIZE) {
t_mov_ins(vec_len, a.0, a.1, a.2, b.0, i_len) // Limit inputs
let a_to = filter_to(VEC_SIZE, a_pos, a_to);
let a_len = a_len.min(VEC_SIZE - a_pos.max(a_to));
t_mov_ins(VEC_SIZE, a_pos, a_len, a_to, b_pos, b_len)
} }
/*
#[test] #[test]
fn transform_mov_del((vec_len, a, b) in test_params()) { fn transform_mov_del(a_pos in 0usize..VEC_SIZE, a_len in 0usize..VEC_SIZE, a_to in 0usize..VEC_SIZE, b_pos in 0usize..VEC_SIZE, b_len in 1usize..VEC_SIZE) {
t_mov_del(vec_len, a.0, a.1, a.2, b.0, b.1) // Limit inputs
} let a_to = filter_to(VEC_SIZE, a_pos, a_to);
let a_len = a_len.min(VEC_SIZE - a_pos.max(a_to));
let b_len = b_len.min(VEC_SIZE - b_pos);
#[test] t_mov_del(VEC_SIZE, a_pos, a_len, a_to, b_pos, b_len, None)
fn transform_mov_mov((vec_len, a, b) in test_params()) {
t_mov_mov(vec_len, a.0, a.1, a.2, b.0, b.1, b.2);
} }
*/
/*
#[test] #[test]
fn transform_seq((vec_len, a, b, a2, b2, a3, b3) in test_params().prop_flat_map(|(vec_len, a, b)| fn transform_mov_mov(a_pos in 0usize..VEC_SIZE, a_len in 0usize..VEC_SIZE, a_to in 0usize..VEC_SIZE, b_pos in 0usize..VEC_SIZE, b_len in 1usize..VEC_SIZE, b_to in 0usize..VEC_SIZE) {
(Just(vec_len), Just(a), Just(b), mov_params(vec_len), mov_params(vec_len), mov_params(vec_len), mov_params(vec_len))) // Limit inputs
) { let a_to = filter_to(VEC_SIZE, a_pos, a_to);
let input = testvec(vec_len); let a_len = a_len.min(VEC_SIZE - a_pos.max(a_to));
let a = Operation::Seq { ops: vec![ let b_to = filter_to(VEC_SIZE, b_pos, b_to);
Operation::Mov { let b_len = b_len.min(VEC_SIZE - b_pos.max(b_to));
pos: a.0,
n: a.1, t_mov_mov(VEC_SIZE, a_pos, a_len, a_to, b_pos, b_len, b_to)
to: a.2,
},
Operation::Ins { pos: a2.0, val: testvec(a3.1) },
Operation::Del { pos: a3.0, n: a3.1 },
] };
let b = Operation::Seq { ops: vec![
Operation::Mov {
pos: b.0,
n: b.1,
to: b.2,
},
Operation::Ins { pos: b2.0, val: testvec(b3.1) },
Operation::Del { pos: b3.0, n: b3.1 },
] };
test_transform_cond(&a, &b, &input);
test_transform_cond(&b, &a, &input);
} }
*/
} }

View file

@ -16,18 +16,6 @@ fn apply_mov(#[case] pos: usize, #[case] n: usize, #[case] to: usize, #[case] ex
assert_eq!(input, expect); assert_eq!(input, expect);
} }
#[test]
fn print() {
let input = vec![1, 2, 3, 4, 5];
let op = Operation::Mov {
pos: 1,
n: 2,
to: 4,
};
op.print_on(&input);
}
#[test] #[test]
fn transform_ins_ins() { fn transform_ins_ins() {
let a = Operation::Ins { let a = Operation::Ins {
@ -393,5 +381,5 @@ fn transform_mov_mov5() {
n: 1, n: 1,
to: 3, to: 3,
}; };
test_transform(&a, &b, &input, &[2, 3, 1, 4]); test_transform(&a, &b, &input, &[2, 3, 4, 1]);
} }

View file

@ -1,589 +1,42 @@
mod util; mod util;
use otvec::Operation; use otvec::Operation;
use util::{test_transform, test_transform_sym}; use util::test_transform_sym;
use rstest::rstest; use rstest::rstest;
// MOV: [0, 1, 2, 3, 4, 5, 6, 7, 8] => [0, 1, 2, 3, 4, 5, 6, 7, 8]
// DEL: [0, 1, 2, 3, 4, 5, 6, 7, 8] => [0, 1, 2, 3, 4, 5, 6, 7, 8]
#[rstest] #[rstest]
// 1 MOV-DEL; Intersection::Overlap, Intersection::Empty; right end; to right // MOV-DEL; Intersection::Overlap, Intersection::Empty; right end; to right
// MOV: [0, (1, 2, 3), 4, 5, 6, 7, 8] => [0, 4, 5, (1, 2, 3), 6, 7, 8] // MOV: [0, (1, 2, 3), 4, 5, 6, 7, 8] => [0, 4, 5, (1, 2, 3), 6, 7, 8]
// DEL: [(0, 1), 2, 3, 4, 5, 6, 7, 8] => [2, 3, 4, 5, 6, 7, 8] // DEL: [(0, 1), 2, 3, 4, 5, 6, 7, 8] => [2, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov {pos: 1, n: 3, to: 6}, Operation::Del {pos: 0, n: 2}, &[4, 5, 2, 3, 6, 7, 8])] #[case(Operation::Mov {pos: 1, n: 3, to: 6}, Operation::Del {pos: 0, n: 2}, &[4, 5, 2, 3, 6, 7, 8])]
// 2 MOV-DEL; Intersection::Overlap, Intersection::Empty; right end; to left // MOV-DEL; Intersection::Overlap, Intersection::Empty; right end; to left
// MOV: [0, 1, 2, (3, 4, 5), 6, 7, 8] => [0, (3, 4, 5), 1, 2, 6, 7, 8] // MOV: [0, 1, 2, (3, 4, 5), 6, 7, 8] => [0, (3, 4, 5), 1, 2, 6, 7, 8]
// DEL: [0, 1, (2, 3), 4, 5, 6, 7, 8] => [0, 1, 4, 5, 6, 7, 8] // DEL: [0, 1, (2, 3), 4, 5, 6, 7, 8] => [0, 1, 4, 5, 6, 7, 8]
#[case(Operation::Mov {pos: 3, n: 3, to: 1}, Operation::Del {pos: 2, n: 2}, &[0, 4, 5, 1, 6, 7, 8])] #[case(Operation::Mov {pos: 3, n: 3, to: 1}, Operation::Del {pos: 2, n: 2}, &[0, 4, 5, 1, 6, 7, 8])]
// 3 MOV-DEL; Intersection::LessOverlap, Intersection::Over; // current debugging
// -
// MOV-DEL; Intersection::Overlap, Intersection::Over;
// MOV: [0, 1, 2, 3, 4, (5, 6, 7), 8] => [0, 1, (5, 6, 7), 2, 3, 4, 8] // MOV: [0, 1, 2, 3, 4, (5, 6, 7), 8] => [0, 1, (5, 6, 7), 2, 3, 4, 8]
// DEL: [0, (1, 2, 3, 4, 5), 6, 7, 8] => [0, 6, 7, 8] // DEL: [0, (1, 2, 3, 4, 5), 6, 7, 8] => [0, 6, 7, 8]
#[case(Operation::Mov {pos: 5, n: 3, to: 2}, Operation::Del {pos: 1, n: 5}, &[0, 6, 7, 8])] #[case(Operation::Mov {pos: 5, n: 3, to: 2}, Operation::Del {pos: 1, n: 5}, &[0, 6, 7, 8])]
// 4 ibt: over -
// MOV: [0, 1, 2,|3, 4, (5, 6, 7), 8] => [0, 1, 2, (5, 6, 7), 3, 4, 8] // MOV: [0, 1, 2, 3, 4, (5, 6, 7), 8] => [0, 1, 2, (5, 6, 7), 3, 4, 8]
// DEL: [0, (1, 2, 3, 4, 5), 6, 7, 8] => [0, 6, 7, 8] // DEL: [0, (1, 2, 3, 4, 5), 6, 7, 8] => [0, 6, 7, 8]
#[case(Operation::Mov {pos: 5, n: 3, to: 3}, Operation::Del {pos: 1, n: 5}, &[0, 6, 7, 8])] #[case(Operation::Mov {pos: 5, n: 3, to: 3}, Operation::Del {pos: 1, n: 5}, &[0, 6, 7, 8])]
// 5 MOV-DEL; Intersection::Overlap, Intersection::Over; ibt: LessOverlap // MOV-DEL; Intersection::Overlap, Intersection::Over;
// - // MOV: [0, 1, (2, 3, 4, 5, 6), 7, 8] => [0, (2, 3, 4, 5, 6), 1, 7, 8]
// MOV: [0,|1, (2, 3, 4, 5, 6), 7, 8] => [0, (2, 3, 4, 5, 6), 1, 7, 8]
// DEL: [(0, 1, 2), 3, 4, 5, 6, 7, 8] => [3, 4, 5, 6, 7, 8] // DEL: [(0, 1, 2), 3, 4, 5, 6, 7, 8] => [3, 4, 5, 6, 7, 8]
#[case(Operation::Mov {pos: 2, n: 5, to: 1}, Operation::Del {pos: 0, n: 3}, &[3, 4, 5, 6, 7, 8])] #[case(Operation::Mov {pos: 2, n: 5, to: 1}, Operation::Del {pos: 0, n: 3}, &[3, 4, 5, 6, 7, 8])]
// 6 ibt: over ----
// MOV: [|0, 1, 2, 3,(4, 5, 6), 7, 8] => [(4, 5, 6), 0, 1, 2, 3, 7, 8] => [(4, 5), 6, (0, 1, 2, 3), 7, 8]
// DEL: [(0, 1, 2, 3, 4, 5), 6, 7, 8] => [6, 7, 8]
#[case(Operation::Mov { pos: 4, n: 3, to: 0 }, Operation::Del { pos: 0, n: 6 }, &[6, 7, 8])]
// 7
// MOV: [0, 1, 2, 3, 4, (5, 6), 7, 8] => [0, 1, 2, 3, (5, 6), 4, 7, 8]
// DEL: [(0, 1, 2, 3, 4, 5), 6, 7, 8] => [6, 7, 8]
#[case(Operation::Mov { pos: 5, n: 2, to: 4 }, Operation::Del { pos: 0, n: 6 }, &[6, 7, 8])]
// 8 less moved to DEL
// MOV: [0, 1, 2, 3, (4, 5),6, 7, 8] => [0,(4, 5),1, 2, 3, 6, 7, 8] => [0,(4, 5),3, 6, 7, 8]
// DEL: [0,(1, 2), 3, 4, 5, 6, 7, 8] => [0, 3,(4, 5), 6, 7, 8] => [0, (4, 5), 3, 6, 7, 8]
#[case(Operation::Mov { pos: 4, n: 2, to: 1 }, Operation::Del { pos: 1, n: 2 }, &[0, 4, 5, 3, 6, 7, 8])]
// 9 less moved right from del
// MOV: [0, 1, 2, 3, (4, 5),6, 7, 8] => [0, 1, 2, 3, 6, 7, (4, 5), 8]
// DEL: [0,(1, 2), 3, 4, 5, 6, 7, 8] => [0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 4, n: 2, to: 8 }, Operation::Del { pos: 1, n: 2 }, &[0, 3, 6, 7, 4, 5, 8])]
// 10 less moved inside DEL
// MOV: [0, 1, 2, 3,(4, 5),6, 7, 8] => [0, (1), 4, 5, (2), 3, 6, 7, 8]
// DEL: [0,(1, 2),3, 4, 5, 6, 7, 8] => [0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 4, n: 2, to: 2 }, Operation::Del { pos: 1, n: 2 }, &[0, 4, 5, 3, 6, 7, 8])]
// 11 less moved left from DEL
// MOV: [0, 1, 2, 3,(4, 5),6, 7, 8] => [(4, 5),0, 1, 2, 3, 6, 7, 8]
// DEL: [0,(1, 2),3, 4, 5, 6, 7, 8] => [0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 4, n: 2, to: 0 }, Operation::Del { pos: 1, n: 2 }, &[4, 5, 0, 3, 6, 7, 8])]
// 12 greater moved right from DEL
// MOV: [0,(1, 2),3, 4, 5, 6, 7, 8] => [0, 3, (4, 5), 6, 7, 1, 2, 8] => [0, 3, 6, 7, 1, 2, 8]
// DEL: [0, 1, 2, 3,(4, 5),6, 7, 8] => [0, (1, 2), 3, 6, 7, 8] => [0, 3, 6, 7, 1, 2, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 8 }, Operation::Del { pos: 4, n: 2 }, &[0, 3, 6, 7, 1, 2, 8])]
// 13 greater moved left from DEL
// MOV: [(0), 1, 2, 3, 4, 5, 6, 7, 8] => [1, 0, 2, 3, 4, 5, 6, 7, 8]
// DEL: [0, (1), 2, 3, 4, 5, 6, 7, 8] => [0, 2, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 1, to: 2 }, Operation::Del { pos: 1, n: 1 }, &[0, 2, 3, 4, 5, 6, 7, 8])]
// 14 greater moved left from DEL
// MOV: [(0), 1, 2, 3, 4, 5, 6, 7, 8] => [1, 0, 2, 3, 4, 5, 6, 7, 8]
// DEL: [0, 1, (2), 3, 4, 5, 6, 7, 8] => [0, 1, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 1, to: 2 }, Operation::Del { pos: 2, n: 1 }, &[1, 0, 3, 4, 5, 6, 7, 8])]
// 15 greater moved left from DEL
// MOV: [(0, 1), 2, 3, 4, 5, 6, 7, 8] => [2, 0, 1, 3, 4, 5, 6, 7, 8]
// DEL: [0, 1, (2), 3, 4, 5, 6, 7, 8] => [0, 1, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Del { pos: 2, n: 1 }, &[0, 1, 3, 4, 5, 6, 7, 8])]
// 16 greater moved inside DEL
// MOV: [(0, 1), 2, 3, 4, 5, 6, 7, 8] => [(2), 0, 1, (3, 4), 5, 6, 7, 8]
// DEL: [0, 1, (2, 3, 4), 5, 6, 7, 8] => [0, 1, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Del { pos: 2, n: 3 }, &[0, 1, 5, 6, 7, 8])]
// 14 greater moved to DEL // MOV-DEL; Intersection::Overlap, Intersection::Empty; left end; to left
// MOV: [0,(1, 2),3, 4, 5, 6, 7, 8] => [0, 3, 4, 5,(1, 2),6, 7, 8] => [0, 3, (1, 2), 6, 7, 8] // MOV: [0, 1, 2, (3, 4, 5), 6, 7, 8] => [0, (3, 4, 5), 1, 2, 6, 7, 8]
// DEL: [0, 1, 2, 3,(4, 5),6, 7, 8] => [0, (1, 2), 3, 6, 7, 8] => [0, 3, (1, 2), 6, 7, 8] // DEL: [0, 1, 2, 3, 4, (5, 6), 7, 8] => [0, 1, 2, 3, 4, 7, 8]
// #[case(Operation::Mov { pos: 1, n: 2, to: 6 }, Operation::Del { pos: 4, n: 2 }, &[0, 3, 1, 2, 6, 7, 8])] // #[case(Operation::Mov {pos: 3, n: 3, to: 1}, Operation::Del {pos: 5, n: 2}, &[0, 6, 7, 1, 2, 3, 8])]
//
// MOV: [0, 1, 2, (3, 4, 5), 6, 7, 8] => [0, (3, 4, 5), 1, 2, 6, 7, 8] => [0, 4, 5, 6, 7, 8]
// DEL: [0, (1, 2, 3), 4, 5, 6, 7, 8] => [0, 4, 5, 6, 7, 8]
// #[case(Operation::Mov { pos: 3, n: 3, to: 1 }, Operation::Del { pos: 1, n: 3 }, &[0, 4, 5, 6, 7, 8])]
fn transform(#[case] a: Operation<i32>, #[case] b: Operation<i32>, #[case] expect: &[i32]) { fn transform(#[case] a: Operation<i32>, #[case] b: Operation<i32>, #[case] expect: &[i32]) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8]; let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform_sym(&a, &b, &input, expect); test_transform_sym(&a, &b, &input, expect);
} }
#[rstest]
// MOV: (0) 1 2 3 4 5 6 7 8 => 1 (0) 2 3 4 5 6 7 8
// DEL: 0 (1 2) 3 4 5 6 7 8 => 0 |3 4 5 6 7 8
#[case(Operation::Mov { pos: 0, n: 1, to: 2 }, Operation::Del { pos: 1, n: 2 }, &[0, 3, 4, 5, 6, 7, 8])]
#[case(Operation::Mov { pos: 0, n: 1, to: 3 }, Operation::Del { pos: 2, n: 2 }, &[1, 0, 4, 5, 6, 7, 8])]
#[case(Operation::Mov { pos: 0, n: 1, to: 3 }, Operation::Del { pos: 1, n: 2 }, &[0, 3, 4, 5, 6, 7, 8])]
// MOV: (0) 1 2 3 4 5 6 7 8 => 1 (0) 2 3 4 5 6 7 8
// DEL: 0 1 (2) 3 4 5 6 7 8 => 0 1 3 4 5 6 7 8
#[case(Operation::Mov { pos: 0, n: 1, to: 2 }, Operation::Del { pos: 2, n: 1 }, &[1, 0, 3, 4, 5, 6, 7, 8])]
// MOV: [(0), 1, 2, 3, 4, 5, 6, 7, 8] => [(1), 0, 2, 3, 4, 5, 6, 7, 8]
// DEL: [0, (1), 2, 3, 4, 5, 6, 7, 8] => [0, 2, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 1, to: 2 }, Operation::Del { pos: 1, n: 1 }, &[0, 2, 3, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, 4, 5, 6, 7, 8] => [(2), 0, 1, 3, 4, 5, 6, 7, 8]
// DEL: [0, 1, (2), 3, 4, 5, 6, 7, 8] => [0, 1, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Del { pos: 2, n: 1 }, &[0, 1, 3, 4, 5, 6, 7, 8])]
fn transform2(#[case] a: Operation<i32>, #[case] b: Operation<i32>, #[case] expect: &[i32]) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform_sym(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0, 1), 2, 3, 4, 5, 6, 7, 8] => [(2), 0, (1), 3, 4, 5, 6, 7, 8]
// DEL: [0, (1, 2), 3, 4, 5, 6, 7, 8] => [0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Del { pos: 1, n: 2 }, &[0, 3, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2,|3, 4, 5, 6, 7, 8] => [(2),|0, (1, 3), 4, 5, 6, 7, 8]
// DEL: [0, (1, 2, 3), 4, 5, 6, 7, 8] => [0, 4, 5, 6, 7, 8]
// rtarget: 1-2
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Del { pos: 1, n: 3 }, &[0, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3,|4, 5, 6, 7, 8] => [(2, 3), 0, (1), 4, 5, 6, 7, 8]
// DEL: [0, (1, 2, 3), 4, 5, 6, 7, 8] => [0, 4, 5, 6, 7, 8]
// rtarget: 2-3
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Del { pos: 1, n: 3 }, &[0, 4, 5, 6, 7, 8])]
// MOV: [(0,1, 2),3,|4, 5, 6, 7, 8] => [(3), 0, 1, (2, 4, 5), 6, 7, 8]
// DEL: [0, 1,(2, 3, 4, 5), 6, 7, 8] => [0, 1, 6, 7, 8]
// rtarget: 1-3
#[case(Operation::Mov { pos: 0, n: 3, to: 4 }, Operation::Del { pos: 2, n: 4 }, &[0, 1, 6, 7, 8])]
// MOV: [(0,1, 2),3,|4, 5, 6, 7, 8] => [(3), 0, (1, 2, 4), 5, 6, 7, 8]
// DEL: [0,(1, 2, 3, 4),5, 6, 7, 8] => [0, 5, 6, 7, 8]
// rtarget: 1-3
#[case(Operation::Mov { pos: 0, n: 3, to: 4 }, Operation::Del { pos: 1, n: 4 }, &[0, 5, 6, 7, 8])]
// MOV: [0, (1, 2), 3, 4, 5, 6, 7, 8] => [1, (2), 0, (3), 4, 5, 6, 7, 8]
// DEL: [0, 1, (2, 3), 4, 5, 6, 7, 8] => [0, (1), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Del { pos: 2, n: 2 }, &[1, 0, 4, 5, 6, 7, 8])]
fn transform3(#[case] a: Operation<i32>, #[case] b: Operation<i32>, #[case] expect: &[i32]) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform_sym(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0, 1, 2), 3,|4, 5, 6, 7, 8] => [3, (0, 1), 2, 4, 5, 6, 7, 8]
// DEL: [(0, 1), 2, 3, 4, 5, 6, 7, 8] => [(2), 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 4 }, Operation::Del { pos: 0, n: 2 }, &[3, 2, 4, 5, 6, 7, 8])]
// MOV: [0, (1, 2, 3), 4, 5, 6, 7, 8] => [(1, 2), 3, 0, 4, 5, 6, 7, 8]
// DEL: [0, (1, 2), 3, 4, 5, 6, 7, 8] => [0, (3), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 3, to: 0 }, Operation::Del { pos: 1, n: 2 }, &[3, 0, 4, 5, 6, 7, 8])]
fn transform_mov_del_within(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform_sym(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0, 1), 2,|3, 4, 5, 6, 7, 8] => [(2), (0, 1), 3, 4, 5, 6, 7, 8]
// DEL: [(0, 1, 2), 3, 4, 5, 6, 7, 8] => [3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 5 }, Operation::Del { pos: 0, n: 3 }, &[3, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, 4,|5, 6, 7, 8] => [(2), 3, 4, (0, 1), 5, 6, 7, 8]
// DEL: [(0, 1, 2), 3, 4, 5, 6, 7, 8] => [3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 5 }, Operation::Del { pos: 0, n: 3 }, &[3, 4, 5, 6, 7, 8])]
// MOV: [0, (1, 2), 3, 4, 5, 6, 7, 8] => [(0), 3, (1, 2), 4, 5, 6, 7, 8]
// DEL: [(0, 1, 2), 3, 4, 5, 6, 7, 8] => [3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 4 }, Operation::Del { pos: 0, n: 3 }, &[3, 4, 5, 6, 7, 8])]
// MOV: [|0,(1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, (3), 4, 5, 6, 7, 8]
// DEL: [0, (1, 2, 3), 4, 5, 6, 7, 8] => [0, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Del { pos: 1, n: 3 }, &[0, 4, 5, 6, 7, 8])]
// MOV: [0,|1, (2, 3), 4, 5, 6, 7, 8] => [(0, 2, 3, 1), 4, 5, 6, 7, 8]
// DEL: [(0, 1, 2, 3), 4, 5, 6, 7, 8] => [4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Del { pos: 0, n: 4 }, &[4, 5, 6, 7, 8])]
fn transform_mov_del_over(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform_sym(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3,|4, 5, 6, 7, 8] m2_to+0
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [2, 3, (0, 1), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[2, 3, 0, 1, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [2,|3, (0,|1), 4, 5, 6, 7, 8] m2_to-mn
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[2, 0, 1, 3, 4, 5, 6, 7, 8])]
// MOV: [|0, 1, (2, 3), 4, 5, 6, 7, 8] => [(2,|3), 0,|1, 4, 5, 6, 7, 8] m2_to+mn
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [0, (2, 3), 1, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 0 }, Operation::Mov { pos: 2, n: 2, to: 1 }, &[0, 2, 3, 1, 4, 5, 6, 7, 8])]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, 3,|4, 5, 6, 7, 8] m2_to+0
// MOV: [0, (1, 2), 3, |4, 5, 6, 7, 8] => [0, 3, (1, 2), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 1, n: 2, to: 4 }, &[0, 3, 1, 2, 4, 5, 6, 7, 8])]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [|0, (2, 3), 1, 4, 5, 6, 7, 8] m2_to+0
// MOV: [|0, 1, (2, 3), 4, 5, 6, 7, 8] => [(2, 3), 0, 1, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Mov { pos: 2, n: 2, to: 0 }, &[2, 3, 0, 1, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, 4, |5, 6, 7, 8] => [2, 3, 4,|(0, 1), 5, 6, 7, 8]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 5 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[2, 0, 1, 3, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, 4, 5, |6, 7, 8] => [2, 3, 4, 5, (0, 1), 6, 7, 8]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 6 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[2, 0, 1, 3, 4, 5, 6, 7, 8])]
fn transform_mov_mov_same(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [|2, (0, 1), {3, 4}, 5, 6, 7, 8] Sa/Gr
// MOV: [|0, 1, 2, (3, 4), 5, 6, 7, 8] => [ (3, 4), {0, 1}, 2,|5, 6, 7, 8] => [3, 4, 2, (0, 1), 5, 6, 7, 8]
//
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 3, n: 2, to: 0 }, &[3, 4, 2, 0, 1, 5, 6, 7, 8], true)]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [|(1, 2), 0, {3, 4}, 5, 6, 7, 8] Go/Gr
// MOV: [|0, 1, 2, (3, 4), 5, 6, 7, 8] => [(3, 4),| 0, {1, 2}, 5, 6, 7, 8]
// #[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 3, n: 2, to: 0 }, &[3, 4, 1, 2, 0, 5, 6, 7, 8], false)]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 3, n: 2, to: 0 }, &[1, 2, 3, 4, 0, 5, 6, 7, 8], false)]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0,|{3, 4}, 5, 6, 7, 8] Sa/Gr
// MOV: [0, |1, 2, (3, 4), 5, 6, 7, 8] => [|0, (3, 4), {1, 2}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 3, n: 2, to: 1 }, &[1, 2, 0, 3, 4, 5, 6, 7, 8], true)]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, {3, 4}, 5,|6, 7, 8] Le/Gr
// MOV: [0, 1, 2, (3, 4), 5, |6, 7, 8] => [|0, {1, 2}, 5, (3, 4), 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 3, n: 2, to: 6 }, &[1, 2, 0, 5, 3, 4, 6, 7, 8], true)]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [|0, (2, 3), 1, {4, 5}, 6, 7, 8] Gr/Gr
// MOV: [|0, 1, 2, 3, (4, 5), 6, 7, 8] => [(4, 5), 0,| 1, {2, 3}, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Mov { pos: 4, n: 2, to: 0 }, &[4, 5, 0, 2, 3, 1, 6, 7, 8], true)]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [|(1, 2), 0, {3, 4, 5}, 6, 7, 8]
// MOV: [|0, 1, 2, (3, 4, 5), 6, 7, 8] => [(3, 4, 5),|0, {1, 2}, 6, 7, 8]
// #[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 3, n: 3, to: 0 }, &[3, 4, 5, 1, 2, 0, 6, 7, 8], false)]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 3, n: 3, to: 0 }, &[1, 2, 3, 4, 5, 0, 6, 7, 8], false)]
// MOV: [|0, 1, (2, 3), 4, 5, 6, 7, 8] => [(2, 3), 0,|1, {4, 5}, 6, 7, 8] Go/Gr
// MOV: [0, |1, 2, 3, (4, 5), 6, 7, 8] => [|0, (4, 5), 1, {2, 3}, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 0 }, Operation::Mov { pos: 4, n: 2, to: 1 }, &[2, 3, 0, 4, 5, 1, 6, 7, 8], false)]
// MOV: [(0, 1), 2, 3, 4, |5, 6, 7, 8] => [{2, 3}, 4, (0, 1), 5, 6, 7, 8]
// MOV: [|0, 1, (2, 3), 4, 5, 6, 7, 8] => [(2, 3), {0, 1}, 4,|5, 6, 7, 8]
// #[case(Operation::Mov { pos: 0, n: 2, to: 5 }, Operation::Mov { pos: 2, n: 2, to: 0 }, &[2, 3, 4, 0, 1, 5, 6, 7, 8], false)]
fn transform_mov_mov_less(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
#[case] sym: bool,
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
if sym {
test_transform_sym(&a, &b, &input, expect);
} else {
test_transform(&a, &b, &input, expect);
}
}
#[rstest]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3, 4, 5, 6, 7, 8] => [0, 1, 2, 3, 4, 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0,|3, 4, 5, 6, 7, 8] => [0, (1, 2), 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[1, 2, 0, 3, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [{2}, (0, {1}), 3, 4, 5, 6, 7, 8] => [{2}, 0, 3, 1, 4..] => [0, 3, 1, 2, 4, 5, 6, 7, 8]
// MOV: [0, (1, 2), 3, |4, 5, 6, 7, 8] => [0, 3, (1, 2), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 1, n: 2, to: 4 }, &[3, 1, 2, 0, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3, 4, 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[1, 2, 0, 3, 4, 5, 6, 7, 8])]
// MOV: [0, (1, 2), 3, |4, 5, 6, 7, 8] => [0, 3, (1, 2), 4, 5, 6, 7, 8]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [{2}, (0, 1), 3,|4, 5, 6, 7, 8] => [0, 1, 3, 2, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 4 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[0, 1, 3, 2, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [2, 3, (0, 1), 4, 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[1, 2, 3, 0, 4, 5, 6, 7, 8])]
fn transform_mov_mov_truncated(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0), 1, 2, 3, 4, 5, 6, 7, |8] => [1, 2, 3, 4, 5, 6, 7, (0), 8]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 1, to: 8 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[2, 0, 1, 3, 4, 5, 6, 7, 8])]
fn transform_mov_mov_within(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0, 1, 2), 3, |4, 5, 6, 7, 8] => [3,(0,{1},2),4, 5, 6,|7, 8]
// MOV: [ 0,(1), 2, 3, 4, 5, 6, |7, 8] => [{0, 2}, 3,|4, 5, 6,(1), 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 4 }, Operation::Mov { pos: 1, n: 1, to: 7 }, &[3, 0, 2, 4, 5, 6, 1, 7, 8])]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [0, (2, 3), 1, 4, 5, 6, 7, 8] => [0, (2), 3, 1, 4, 5, 6, 7,|8]
// MOV: [0, 1, (2), 3, 4, 5, 6, 7, |8] => [0, 1, 3, 4, 5, 6, 7, (2), 8] => [0,|1, (3), 4, 5, 6, 7, 2, 8] !!
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Mov { pos: 2, n: 1, to: 8 }, &[0, 3, 1, 4, 5, 6, 7, 2, 8])]
// MOV: [|0,*(1, 2, 3), 4, 5, 6, 7, 8] => [(1, 2, 3), 0,*4, 5, 6, 7, 8] => [1, (2, 3), 0,|4, 5, 6, 7, 8] !!b2
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [0, (2, 3), 1, 4, 5, 6, 7, 8] => [|0, 2, 3, (1), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 3, to: 0 }, Operation::Mov { pos: 2, n: 2, to: 1 }, &[1, 0, 2, 3, 4, 5, 6, 7, 8])]
// #equal targets
// MOV: [(0, 1, 2), 3, |4, 5, 6, 7, 8] => [3, (0, 1, 2), 4, 5, 6, 7, 8] => [ 3, (0, 1), 2,|4, 5, 6, 7, 8] ? +m2_n
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [2, 3, (0, 1), 4, 5, 6, 7, 8] => [(2), 3,|0, 1, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 4 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[3, 2, 0, 1, 4, 5, 6, 7, 8])]
// MOV: [(0, 1, 2), 3, 4, |5, 6, 7, 8] => [3, 4, ({0, 1},|2),|5, 6, 7, 8]
// MOV: [(0, 1), 2, 3, 4, |5, 6, 7, 8] => [{2}, 3, 4,|(0, 1), 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 5 }, Operation::Mov { pos: 0, n: 2, to: 5 }, &[3, 4, 2, 0, 1, 5, 6, 7, 8])]
// MOV: [|0, (1, 2, 3), 4, 5, 6, 7, 8] => [({1, 2}, 3),|0, 4, 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [|(1, 2), 0, {3}, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 3, to: 0 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[3, 1, 2, 0, 4, 5, 6, 7, 8])]
// #split
// MOV: [|0, (1, 2, 3,*4), 5, 6, 7, 8] => [|({1, 2}, 3,|4), 0, 5, 6, 7, 8] => [3, 1, 2, 4, 0, 5, 6, 7, 8]
// MOV: [0, (1, 2), 3,| 4, 5, 6, 7, 8] => [|0, {3, (1, 2), 4}, 5, 6, 7, 8] => [3, 1, 2, 4, 0, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 4, to: 0 }, Operation::Mov { pos: 1, n: 2, to: 4 }, &[3, 1, 2, 4, 0, 5, 6, 7, 8])]
// MOV: [|0, (1,*2, 3, 4), 5, 6, 7, 8] => [ (1,|2, {3, 4}), 0, 5, 6, 7, 8]
// MOV: [ 0, 1,|2, (3, 4), 5, 6, 7, 8] => [|0, {1,(3, 4), 2}, 5, 6, 7, 8] => [1, 3, 4, 2, 0, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 4, to: 0 }, Operation::Mov { pos: 3, n: 2, to: 2 }, &[1, 3, 4, 2, 0, 5, 6, 7, 8])]
fn transform_mov_mov_over(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// b split by a
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [|2, (0, {1}), 3, 4, 5, 6, 7, 8]
// MOV: [|0, (1, 2, 3), 4, 5, 6, 7, 8] => [(1, 2,|3), {0}, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 1, n: 3, to: 0 }, &[1, 2, 0, 3, 4, 5, 6, 7, 8])]
// MOV: [0, (1, 2), 3, |4, 5, 6, 7, 8] => [|{0}, 3, (1, {2}), 4,|5, 6, 7, 8] => [2, (0), 3, 1, 4,|5, 6, 7, 8]
// MOV: [|0, 1, (2, 3, 4), 5, 6, 7, 8] => [(2, 3,|4), 0, {1}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 4 }, Operation::Mov { pos: 2, n: 3, to: 0 }, &[2, 3, 1, 4, 0, 5, 6, 7, 8])]
// MOV: [0, (1, 2), 3, 4, |5, 6, 7, 8] => [0, 3, 4, (1, {2}), 5, 6, 7, 8] => [2, {0}, 3, 4, 1, 5,|6, 7, 8]
// MOV: [|0, 1, (2, 3, 4, 5), 6, 7, 8] => [(2, 3, 4,|5), 0, {1}, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 5 }, Operation::Mov { pos: 2, n: 4, to: 0 }, &[2, 3, 4, 1, 5, 0, 6, 7, 8])]
// MOV: [(0, 1, 2), 3, |4, 5, 6, 7, 8] => [{3, (0, 1, 2), 4}, 5,|6, 7, 8] => [5,|3, 0, 1, {2}, 4, 6, 7, 8] => [5, 2, 3, 0, 1, 4, 6, 7, 8]
// MOV: [0, 1, (2, 3, 4), 5, |6, 7, 8] => [(0, 1), 5, (2, 3,|4), 6, 7, 8] => [5, 2, 3, 0, 1, 4, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 4 }, Operation::Mov { pos: 2, n: 3, to: 6 }, &[5, 2, 3, 0, 1, 4, 6, 7, 8])]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [{2, (0, 1), 3}, 4, 5,|6, 7, 8] => [4, 5,|(2, 0, {1}, 3), 6, 7, 8]
// MOV: [0, (1, 2, 3), 4, 5, |6, 7, 8] => [{0}, 4, 5, (1, 2,|3), 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 1, n: 3, to: 6 }, &[4, 5, 1, 2, 0, 3, 6, 7, 8])]
// a split by b
// MOV: [(0, 1, 2), 3, |4, 5, 6, 7, 8] => [|3, (0, 1, {2}), 4, 5, 6, 7, 8] => [(2), 3, 0, 1, 4, 5, 6, 7, 8]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [{0},(2, 3), {1},|4, 5, 6, 7, 8] => [2, 3, (0), (1), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 4 }, Operation::Mov { pos: 2, n: 2, to: 1 }, &[2, 3, 0, 1, 4, 5, 6, 7, 8])]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [|4, (0, 1, {2, 3}), 5, 6, 7, 8] => [(2, 3), 4, 0, 1, 5, 6, 7, 8]
// MOV: [0, |1, (2, 3, 4), 5, 6, 7, 8] => [{0}, (2, 3, 4), {1},|5, 6, 7, 8] => [2, 3, 4, 0, 1, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 4, to: 5 }, Operation::Mov { pos: 2, n: 3, to: 1 }, &[2, 3, 4, 0, 1, 5, 6, 7, 8])]
// MOV: [(0, 1, 2), 3, 4, 5, |6, 7, 8] => [3, 4, 5, (0, 1, {2}), 6, 7, 8] => [2, 3, 4, 5, 0, 1, 6, 7, 8]
// MOV: [0, |1, (2, 3, 4), 5, 6, 7, 8] => [{0}, (2, 3, 4), {1}, 5,|6, 7, 8] => [2, 3, 4, 5, (0), (1), 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 6 }, Operation::Mov { pos: 2, n: 3, to: 1 }, &[2, 3, 4, 5, 0, 1, 6, 7, 8])]
// MOV: [|0, (1, 2, 3), 4, 5, 6, 7, 8] => [(1, 2, {3}), 0,| 4, 5, 6, 7, 8]
// MOV: [0, 1, |2, (3, 4), 5, 6, 7, 8] => [|0, {1}, (3, 4), {2}, 5, 6, 7, 8] => [1, 2, 0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 3, to: 0 }, Operation::Mov { pos: 3, n: 2, to: 2 }, &[1, 2, 0, 3, 4, 5, 6, 7, 8])]
// both split
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [|4, (0, 1, {2, 3}), 5, 6, 7, 8] => [2, 3, 4, 0, 1, 5, 6, 7, 8]
// MOV: [0, |1, (2, 3, 4, 5, 6, 7), 8] => [{0}, (2, 3, 4, 5, 6, 7), {1}, 8] => [2, 3, 4, 0, 1, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 4, to: 5 }, Operation::Mov { pos: 2, n: 6, to: 1 }, &[2, 3, 4, 0, 1, 5, 6, 7, 8])]
fn transform_mov_mov_split_ol_less(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// a split by b
// MOV: [|0, (1, 2, 3, 4, 5, 6, 7), 8] => [ ({1, 2, 3}, 4, 5, 6, 7), 0,|8]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [|{4}, (0, 1, 2, 3), {5, 6, 7}, 8] => [5, 6, 7, {4}, 0, 1, 2, 3, 8]
#[case(Operation::Mov { pos: 1, n: 7, to: 0 }, Operation::Mov { pos: 0, n: 4, to: 5 }, &[4, 5, 6, 7, 0, 1, 2, 3, 8])]
// MOV: [|0, (1, 2, 3), 4, 5, 6, 7, 8] => [({1}, 2, 3), 0,|4, 5, 6, 7, 8]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [{2}, (0, 1), {3}, 4, 5, 6, 7, 8] => [2, 3, 0, 1, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 3, to: 0 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[2, 3, 0, 1, 4, 5, 6, 7, 8])]
// MOV: [|0, 1, (2, 3, 4, 5, 6, 7), 8] => [({2, 3}, 4, 5, 6, 7), 0, 1,|8] => [4, 5, 6, 7, 0, 1, 2, 3, 8]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [|{4}, (0, 1, 2, 3), {5, 6, 7}, 8] => [4, 5, 6, 7, 0, 1, 2, 3, 8]
#[case(Operation::Mov { pos: 2, n: 6, to: 0 }, Operation::Mov { pos: 0, n: 4, to: 5 }, &[4, 5, 6, 7, 0, 1, 2, 3, 8])]
// MOV: [|0, 1, (2, 3, 4), 5, 6, 7, 8] => [({2}, 3, 4), 0, 1,|5, 6, 7, 8]
// MOV: [0, (1, 2), 3, |4, 5, 6, 7, 8] => [|0, {3}, (1, 2), {4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 3, to: 0 }, Operation::Mov { pos: 1, n: 2, to: 4 }, &[3, 4, 0, 1, 2, 5, 6, 7, 8])]
// MOV: [0, (1, 2, 3), 4, |5, 6, 7, 8] => [0,|4, ({1}, 2, 3), 5, 6, 7, 8]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [{2}, (0, 1), {3}, 4,|5, 6, 7, 8] => [{2}, 0, 1, 4,|(3), 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 3, to: 5 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[0, 1, 4, 2, 3, 5, 6, 7, 8])]
// MOV: [0, |1, (2, 3, 4), 5, 6, 7, 8] => [0, ({2}, 3, 4), 1,|5, 6, 7, 8] wi
// MOV: [(0, 1, 2), 3, |4, 5, 6, 7, 8] => [{3}, (0,|1, 2), {4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 3, to: 1 }, Operation::Mov { pos: 0, n: 3, to: 4 }, &[0, 3, 4, 1, 2, 5, 6, 7, 8])]
// b split by a, R
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [0, ({2}, 3), 1,|4, 5, 6, 7, 8]
// MOV: [(0, 1, 2), 3, |4, 5, 6, 7, 8] => [{3}, (0,|1, 2), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Mov { pos: 0, n: 3, to: 4 }, &[0, 3, 1, 2, 4, 5, 6, 7, 8])]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [{0, ({2}, 3), 1}, 4,|5, 6, 7, 8] => [{0, 3, 1}, 4,|2, 5, 6, 7, 8]
// MOV: [(0, 1, 2), 3, 4, |5, 6, 7, 8] => [{3}, 4, (0,|1, 2), 5, 6, 7, 8] => [4, 0, (3), 1, 2, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Mov { pos: 0, n: 3, to: 5 }, &[4, 0, 3, 1, 2, 5, 6, 7, 8])]
// b split by a, L
// MOV: [0, 1, |2, (3, 4), 5, 6, 7, 8] => [|0, {1, (3, 4), 2}, 5, 6, 7, 8] => [1, {3}, 4, 2,|0, 5, 6, 7, 8]
// MOV: [|0, (1, 2, 3), 4, 5, 6, 7, 8] => [(1,|2, 3), 0, {4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 3, n: 2, to: 2 }, Operation::Mov { pos: 1, n: 3, to: 0 }, &[1, 4, 2, 3, 0, 5, 6, 7 ,8])]
fn transform_mov_mov_split_ol_greater(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// MOV: [0, 1, (2, 3, 4), 5, |6, 7, 8] => [0, 1, 5, (2, 3, 4), 6, 7, 8]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [4, (0, 1, 2, 3), 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 3, to: 6 }, Operation::Mov { pos: 0, n: 4, to: 5 }, &[0, 1, 2, 3, 5, 4, 6, 7, 8])]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, 3, 4, 5, 6, 7, 8]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [2, 3, (0, 1), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[3, 2, 0, 1, 4, 5, 6, 7, 8])]
// MOV: [0, 1, (2, 3), 4, |5, 6, 7, 8] => [0, 1, 4, (2, 3), 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 5 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[1, 2, 0, 4, 3, 5, 6, 7, 8])]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [0, (2, 3), 1, 4, 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2), 0, 3, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[3, 1, 2, 0, 4, 5, 6, 7, 8])]
// same destination
// MOV: [0, (1, 2), 3, |4, 5, 6, 7, 8] => [{0}, 3,|(1, 2), 4, 5, 6, 7, 8]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [{2}, 3, (0, 1),|4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 4 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[3, 0, 1, 2, 4, 5, 6, 7, 8])]
// MOV: [0, (1, 2, 3), 4, |5, 6, 7, 8] => [{0}, 4,|(1, 2, 3), 5, 6, 7, 8]
// MOV: [(0, 1), 2, 3, 4, |5, 6, 7, 8] => [{2, 3}, 4, (0, 1),|5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 3, to: 5 }, Operation::Mov { pos: 0, n: 2, to: 5 }, &[4, 0, 1, 2, 3, 5, 6, 7, 8])]
// MOV: [|0, 1, (2, 3), 4, 5, 6, 7, 8] => [|(2, 3),0, {1}, 4, 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2),|0, {3}, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 0 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[1, 2, 3, 0, 4, 5, 6, 7, 8])]
// MOV: [|0, 1, (2, 3, 4), 5, 6, 7, 8] => [|(2, 3, 4), 0, {1}, 5, 6, 7, 8]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2),|0, {3, 4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 3, to: 0 }, Operation::Mov { pos: 1, n: 2, to: 0 }, &[1, 2, 3, 4, 0, 5, 6, 7, 8])]
// MOV: [0, |1, 2, (3, 4), 5, 6, 7, 8] => [0,|(3, 4), 1, {2}, 5, 6, 7, 8]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [0, (2, 3),|1, {4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 3, n: 2, to: 1 }, Operation::Mov { pos: 2, n: 2, to: 1 }, &[0, 2, 3, 4, 1, 5, 6, 7, 8])]
fn transform_mov_mov_ol_greater(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [|4, (0, 1, {2, 3}),*5, 6, 7, 8] => [|(2, 3), 4, 0, 1, {5}, 6, 7, 8] => [5, 2, 3, 4, 0, 1, 6, 7, 8]
// MOV: [0, 1, (2, 3, 4), 5, |6, 7, 8] => [{0, 1}, 5, (2, 3, 4),|6, 7, 8] => [5, 2, 3, 4, (0, 1), 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 4, to: 5 }, Operation::Mov { pos: 2, n: 3, to: 6 }, &[5, 2, 3, 4, 0, 1, 6, 7, 8])]
// MOV: [(0, 1, 2), 3, 4, 5, |6, 7, 8] => [{3},4, 5, (0, 1, {2}),*6,|7, 8] => [4, 5, 0, 1, 6, (2, 3), 7, 8]
// MOV: [0, 1, (2, 3), 4, 5, 6, |7, 8] => [{0, 1}, 4, 5,|6, (2, 3),*7, 8] => [4, 5, 0, 1, 6, 2, 3, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 6 }, Operation::Mov { pos: 2, n: 2, to: 7 }, &[4, 5, 0, 1, 6, 2, 3, 7, 8])]
// MOV: [(0, 1, 2), 3, 4, 5, |6, 7, 8] => [3, 4, 5, (0, 1, 2), 6, 7, 8]
// MOV: [0, (1, 2, 3), 4, |5, 6, 7, 8] => [{0}, 4, (1, 2, 3), 5,|6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 6 }, Operation::Mov { pos: 1, n: 3, to: 5 }, &[4, 1, 2, 3, 5, 0, 6, 7, 8])]
// MOV: [(0, 1, 2), 3, 4, 5, |6, 7, 8] => [3, 4, 5, (0, 1, 2), 6, 7, 8]
// MOV: [|0, (1, 2, 3, 4), 5, 6, 7, 8] => [(1, 2, 3, 4), 0, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 6 }, Operation::Mov { pos: 1, n: 4, to: 0 }, &[1, 2, 3, 4, 5, 0, 6, 7, 8])]
// same destination
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2),|0, {3, 4}, 5, 6, 7, 8]
// MOV: [|0, 1, (2, 3, 4), 5, 6, 7, 8] => [|(2, 3, 4), 0, {1}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 2, n: 3, to: 0 }, &[1, 2, 3, 4, 0, 5, 6, 7, 8])]
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1, 2),|0, {3}, 4, 5, 6, 7, 8]
// MOV: [|0, 1, (2, 3), 4, 5, 6, 7, 8] => [|(2, 3), 0, {1}, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 2, n: 2, to: 0 }, &[1, 2, 3, 0, 4, 5, 6, 7, 8])]
// MOV: [(0, 1, 2), 3, 4, 5, |6, 7, 8] => [3, 4, 5, (0, 1, 2), 6, 7, 8]
// MOV: [0, (1, 2, 3), 4, 5, |6, 7, 8] => [{0}, 4, 5, (1, 2, 3),|6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 6 }, Operation::Mov { pos: 1, n: 3, to: 6 }, &[4, 5, 0, 1, 2, 3, 6, 7, 8])]
fn transform_mov_mov_ol_less(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// info: 10 test items
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8, 9] => [{2, 3, (0, 1), 4}, 5,|6, 7, 8, 9] => [5,|2, 3, 0, {1}, 4, 6, 7, 8, 9]
// MOV: [0, (1, 2, 3, 4), 5, |6, 7, 8, 9] => [{0}, 5, (1, 2, 3,|4), 6, 7, 8, 9] => [5, 1, 2, 3, (0), 4, 6, 7, 8, 9]
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Mov { pos: 1, n: 4, to: 6 }, &[5, 1, 2, 3, 0, 4, 6, 7, 8, 9])]
fn transform_mov_mov_tmp(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// a_split_by_b, to right
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0,|1), {3, 4}, 5, 6, 7, 8]
// MOV: [0, |1, 2, (3, 4), 5, 6, 7, 8] => [{0, (3, 4), 1}, 2,|5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 3, n: 2, to: 1 }, &[2, 0, 3, 4, 1, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0,|1), {3, 4, 5}, 6, 7, 8]
// MOV: [0, |1, 2, (3, 4, 5), 6, 7, 8] => [{0, (3, 4, 5), 1}, 2,|6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 3, n: 3, to: 1 }, &[2, 0, 3, 4, 5, 1, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [{2, 3}, (0,|1), 4, 5, 6, 7, 8]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [{0, (2, 3), 1}, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Mov { pos: 2, n: 2, to: 1 }, &[0, 2, 3, 1, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [2, 3, (0,|1), {4, 5}, 6, 7, 8] end >= m2
// MOV: [0, |1, 2, 3, (4, 5), 6, 7, 8] => [{0, (4, 5), 1}, 2, 3,|6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Mov { pos: 4, n: 2, to: 1 }, &[2, 3, 0, 4, 5, 1, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, 4, |5, 6, 7, 8] => [{2, 3}, 4, (0,|1), 5, 6, 7, 8]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [{0, (2, 3), 1}, 4,|5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 5 }, Operation::Mov { pos: 2, n: 2, to: 1 }, &[4, 0, 2, 3, 1, 5, 6, 7, 8])]
// a_split_by_b, to left
// MOV: [|0, (1, 2), 3, 4, 5, 6, 7, 8] => [(1,|2), 0, {3, 4}, 5, 6, 7, 8]
// MOV: [0, 1, |2, (3, 4), 5, 6, 7, 8] => [|0, {1, (3, 4), 2}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 1, n: 2, to: 0 }, Operation::Mov { pos: 3, n: 2, to: 2 }, &[1, 3, 4, 2, 0, 5, 6, 7, 8])]
// b_split_by_a, m2_to_right
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [{2, (0, 1), 3}, 4,|5, 6, 7, 8]
// MOV: [0, 1, (2, 3), 4, |5, 6, 7, 8] => [{0, 1}, 4, (2,|3), 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 2, n: 2, to: 5 }, &[4, 2, 0, 1, 3, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [2, {3, (0, 1), 4}, 5,|6, 7, 8]
// MOV: [0, 1, 2, (3, 4), 5, |6, 7, 8] => [{0, 1}, 2, 5, (3,|4), 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Mov { pos: 3, n: 2, to: 6 }, &[2, 5, 3, 0, 1, 4, 6, 7, 8])]
// b_split_by_a, m2_to_left
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0, 1), 3, 4, 5, 6, 7, 8]
// MOV: [|0, 1, (2, 3), 4, 5, 6, 7, 8] => [(2, 3), 0, 1, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 2, n: 2, to: 0 }, &[2, 0, 1, 3, 4, 5, 6, 7, 8])]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [|2, {3, (0, 1), 4}, 5, 6, 7, 8]
// MOV: [0, 1, |2, (3, 4), 5, 6, 7, 8] => [{0, 1}, (3,|4), 2, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 4 }, Operation::Mov { pos: 3, n: 2, to: 2 }, &[3, 0, 1, 4, 2, 5, 6, 7, 8])]
// both split
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [{2}, (0,|1), {3}, 4, 5, 6, 7, 8]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [0, (2, 3), 1, 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 0, n: 2, to: 3 }, Operation::Mov { pos: 2, n: 2, to: 1 }, &[0, 2, 3, 1, 4, 5, 6, 7, 8])]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [{4}, (0,|1, 2, 3), {5, 6, 7}, 8]
// MOV: [0, |1, 2, 3, (4, 5, 6, 7), 8] => [0, (4, 5, 6, 7), 1, 2, 3, 8]
#[case(Operation::Mov { pos: 0, n: 4, to: 5 }, Operation::Mov { pos: 4, n: 4, to: 1 }, &[0, 4, 5, 6, 7, 1, 2, 3, 8])]
// MOV: [(0, 1, 2), 3, 4, 5, |6, 7, 8] => [3, {4, 5}, (0,|1, 2), {6, 7}, 8]
// MOV: [0, |1, 2, 3, (4, 5, 6, 7), 8] => [|0, (4, 5, 6, 7), 1, 2, {3}, 8]
#[case(Operation::Mov { pos: 0, n: 3, to: 6 }, Operation::Mov { pos: 4, n: 4, to: 1 }, &[3, 0, 4, 5, 6, 7, 1, 2, 8])]
fn transform_mov_mov_split_less(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}
#[rstest]
// a_split_by_b, to right
// MOV: [0, 1, 2, 3, (4, 5), 6, |7, 8] => [{0, 1, 2, 3}, 6, (4,|5), 7, 8]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [{4, (0, 1, 2, 3), 5}, 6,|7, 8]
#[case(Operation::Mov { pos: 4, n: 2, to: 7 }, Operation::Mov { pos: 0, n: 4, to: 5 }, &[6, 4, 0, 1, 2, 3, 5, 7, 8])]
// MOV: [0, 1, 2, 3, (4, 5), 6, |7, 8] => [{0, 1, 2}, 3, 6, (4,|5), 7, 8]
// MOV: [(0, 1, 2), 3, 4, |5, 6, 7, 8] => [3, {4, (0, 1, 2),*5}, 6,|7, 8]
#[case(Operation::Mov { pos: 4, n: 2, to: 7 }, Operation::Mov { pos: 0, n: 3, to: 5 }, &[3, 6, 4, 0, 1, 2, 5, 7, 8])]
// MOV: [0, 1, (2, 3, 4), 5, |6, 7, 8] => [{0}, 1, 5, (2,|3, 4), 6, 7, 8]
// MOV: [(0),1, 2,|3, 4, 5, 6, 7, 8] => [1, {2, (0),*3, 4}, 5,|6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 3, to: 6 }, Operation::Mov { pos: 0, n: 1, to: 3 }, &[1, 5, 2, 0, 3, 4, 6, 7, 8])]
// a_split_by_b, to left
// MOV: [0, 1, |2, (3, 4), 5, 6, 7, 8] => [{0, 1}, (3,|4), 2, 5, 6, 7, 8] m_to -m2_n
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [|2, {3, (0, 1), 4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 3, n: 2, to: 2 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[3, 0, 1, 4, 2, 5, 6, 7, 8])]
// MOV: [|0, 1, 2, 3, (4, 5, 6, 7), 8] => [(4,|5, 6, 7), {0, 1, 2, 3}, 8]
// MOV: [(0, 1, 2, 3), 4, |5, 6, 7, 8] => [{4, (0, 1, 2, 3), 5, 6, 7}, 8]
#[case(Operation::Mov { pos: 4, n: 4, to: 0 }, Operation::Mov { pos: 0, n: 4, to: 5 }, &[4, 0, 1, 2, 3, 5, 6, 7, 8])]
// MOV: [|0, 1, 2, (3, 4), 5, 6, 7, 8] => [(3,|4), {0, 1}, 2, 5, 6, 7, 8]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [|2, {3, (0, 1), 4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 3, n: 2, to: 0 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[3, 0, 1, 4, 2, 5, 6, 7, 8])]
// MOV: [0, 1, 2, |3, (4, 5), 6, 7, 8] => [{0, 1}, 2, (4,|5), 3, 6, 7, 8]
// MOV: [(0, 1), 2, 3, 4, |5, 6, 7, 8] => [2,|3, {4, (0, 1), 5}, 6, 7, 8]
#[case(Operation::Mov { pos: 4, n: 2, to: 3 }, Operation::Mov { pos: 0, n: 2, to: 5 }, &[2, 4, 0, 1, 5, 3, 6, 7, 8])]
// b_split_by_a, to right
// MOV: [0, |1, 2, (3, 4), 5, 6, 7, 8] => [{0, (3, 4), 1}, 2,|5, 6, 7, 8]
// MOV: [(0, 1), 2, |3, 4, 5, 6, 7, 8] => [2, (0,|1), {3, 4}, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 3, n: 2, to: 1 }, Operation::Mov { pos: 0, n: 2, to: 3 }, &[2, 0, 3, 4, 1, 5, 6, 7, 8])]
// MOV: [0, |1, (2, 3), 4, 5, 6, 7, 8] => [{0, (2, 3), 1}, 4, 5, 6, 7, 8]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [{2, 3}, (0,|1), 4, 5, 6, 7, 8]
#[case(Operation::Mov { pos: 2, n: 2, to: 1 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[0, 2, 3, 1, 4, 5, 6, 7, 8])]
// both split
// MOV: [0, |1, 2, (3, 4), 5, 6, 7, 8] => [{0}, (3,|4), {1}, 2, 5, 6, 7, 8]
// MOV: [(0, 1), 2, 3, |4, 5, 6, 7, 8] => [{2}, 3, (0, 1), 4,|5, 6, 7, 8]
#[case(Operation::Mov { pos: 3, n: 2, to: 1 }, Operation::Mov { pos: 0, n: 2, to: 4 }, &[3, 0, 1, 4, 2, 5, 6, 7, 8])]
fn transform_mov_mov_split_greater(
#[case] a: Operation<i32>,
#[case] b: Operation<i32>,
#[case] expect: &[i32],
) {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8];
test_transform(&a, &b, &input, expect);
}

View file

@ -1,40 +1,29 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::{ use std::{fmt::Debug, sync::atomic::AtomicUsize};
fmt::{Debug, Display},
sync::atomic::AtomicUsize,
};
use otvec::{transform, Operation}; use otvec::{transform, Operation};
pub fn test_transform<T: PartialEq + Clone + Debug + Display>( pub fn test_transform<T: PartialEq + Clone + Debug>(
a: &Operation<T>, a: &Operation<T>,
b: &Operation<T>, b: &Operation<T>,
input: &[T], input: &[T],
expect: &[T], expect: &[T],
) { ) {
// Print operations
println!("A/B:");
a.print_on(input);
b.print_on(input);
let (mut a2, mut b2) = (a.clone(), b.clone()); let (mut a2, mut b2) = (a.clone(), b.clone());
transform(&mut a2, &mut b2); transform(&mut a2, &mut b2);
dbg!(&a2, &b2); dbg!(&a2, &b2);
check_op(&a2, a, b); check_op(&a2, a);
check_op(&b2, a, b); check_op(&b2, b);
let mut data = input.to_vec(); let mut data = input.to_vec();
a.clone().apply(&mut data); a.clone().apply(&mut data);
b2.apply(&mut data); b2.apply(&mut data);
let mut data2 = input.to_vec();
b.clone().apply(&mut data2);
a2.apply(&mut data2);
assert_eq!(data, data2, "OT condition unfulfilled");
assert_eq!(data, expect, "a, b2"); assert_eq!(data, expect, "a, b2");
assert_eq!(data2, expect, "b, a2");
let mut data = input.to_vec();
b.clone().apply(&mut data);
a2.apply(&mut data);
assert_eq!(data, expect, "b, a2");
} }
#[derive(Default)] #[derive(Default)]
@ -43,21 +32,15 @@ pub struct CondCatchCtr {
ok: AtomicUsize, ok: AtomicUsize,
} }
pub fn test_transform_cond_catch< pub fn test_transform_cond_catch<T: PartialEq + Clone + Debug + std::panic::RefUnwindSafe>(
T: PartialEq + Clone + Debug + Display + std::panic::RefUnwindSafe,
>(
a: &Operation<T>, a: &Operation<T>,
b: &Operation<T>, b: &Operation<T>,
input: &[T], input: &[T],
ctr: Option<&CondCatchCtr>, ctr: Option<&CondCatchCtr>,
) { ) {
let do_count = !a.is_empty() && !b.is_empty();
if do_count {
if let Some(ctr) = ctr { if let Some(ctr) = ctr {
ctr.total.fetch_add(1, std::sync::atomic::Ordering::Relaxed); ctr.total.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
} }
}
let res = std::panic::catch_unwind(|| { let res = std::panic::catch_unwind(|| {
let (mut a2, mut b2) = (a.clone(), b.clone()); let (mut a2, mut b2) = (a.clone(), b.clone());
@ -66,8 +49,8 @@ pub fn test_transform_cond_catch<
}); });
if let Ok((a2, b2)) = res { if let Ok((a2, b2)) = res {
// check_op(&a2, a, b); check_op(&a2, a);
// check_op(&b2, a, b); check_op(&b2, b);
let mut data = input.to_vec(); let mut data = input.to_vec();
a.clone().apply(&mut data); a.clone().apply(&mut data);
@ -76,30 +59,13 @@ pub fn test_transform_cond_catch<
let mut data2 = input.to_vec(); let mut data2 = input.to_vec();
b.clone().apply(&mut data2); b.clone().apply(&mut data2);
a2.apply(&mut data2); a2.apply(&mut data2);
assert_eq!(data, data2, "ops:\nA: {a:?}\nB: {b:?}");
if data != data2 {
// Print operations
println!("A/B: Operation::{a:?}, Operation::{b:?}");
a.print_on(input);
b.print_on(input);
if let Some(ctr) = ctr {
let total = ctr.total.load(std::sync::atomic::Ordering::Relaxed);
let success = ctr.ok.load(std::sync::atomic::Ordering::Relaxed);
let perc = (success as f64 / total as f64) * 100.0;
println!("Cases passed: {success}/{total} ({perc:0.2}%)");
}
panic!("OT condition unfulfilled");
}
if do_count {
if let Some(ctr) = ctr { if let Some(ctr) = ctr {
ctr.ok.fetch_add(1, std::sync::atomic::Ordering::Relaxed); ctr.ok.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
} }
} }
} }
}
pub fn print_cond_catch_ctr(ctr: &CondCatchCtr) { pub fn print_cond_catch_ctr(ctr: &CondCatchCtr) {
let total = ctr.total.load(std::sync::atomic::Ordering::Relaxed); let total = ctr.total.load(std::sync::atomic::Ordering::Relaxed);
@ -107,13 +73,11 @@ pub fn print_cond_catch_ctr(ctr: &CondCatchCtr) {
let perc = (success as f64 / total as f64) * 100.0; let perc = (success as f64 / total as f64) * 100.0;
if success < total { if success < total {
panic!("❌ Cases passed: {success}/{total} ({perc:0.2}%)"); panic!("Cases passed: {success}/{total} ({perc:0.2}%)");
} else {
println!("✅ Cases passed: {success}/{total} ({perc:0.2}%)");
} }
} }
pub fn test_transform_sym<T: PartialEq + Clone + Debug + Display>( pub fn test_transform_sym<T: PartialEq + Clone + Debug>(
a: &Operation<T>, a: &Operation<T>,
b: &Operation<T>, b: &Operation<T>,
input: &[T], input: &[T],
@ -131,8 +95,8 @@ pub fn test_transform_cond<T: PartialEq + Clone + Debug>(
let (mut a2, mut b2) = (a.clone(), b.clone()); let (mut a2, mut b2) = (a.clone(), b.clone());
transform(&mut a2, &mut b2); transform(&mut a2, &mut b2);
// dbg!(&a2, &b2); // dbg!(&a2, &b2);
check_op(&a2, a, b); check_op(&a2, a);
check_op(&b2, a, b); check_op(&b2, b);
let mut data = input.to_vec(); let mut data = input.to_vec();
a.clone().apply(&mut data); a.clone().apply(&mut data);
@ -144,16 +108,14 @@ pub fn test_transform_cond<T: PartialEq + Clone + Debug>(
assert_eq!(data, data2, "ops:\nA: {a:?}\nB: {b:?}"); assert_eq!(data, data2, "ops:\nA: {a:?}\nB: {b:?}");
} }
fn check_op<T: Debug>(op: &Operation<T>, a: &Operation<T>, b: &Operation<T>) { fn check_op<T: Debug>(op: &Operation<T>, a: &Operation<T>) {
match op { match op {
Operation::Nop => {} Operation::Nop => {}
Operation::Ins { val, .. } => { Operation::Ins { val, .. } => assert!(val.len() > 0, "empty op: {op:?}\nfrom: {a:?}"),
assert!(val.len() > 0, "empty op: {op:?}\nfrom: {a:?}; {b:?}") Operation::Del { n, .. } => assert!(*n > 0, "empty op: {op:?}\nfrom: {a:?}"),
}
Operation::Del { n, .. } => assert!(*n > 0, "empty op: {op:?}\nfrom: {a:?}; {b:?}"),
Operation::Mov { pos, n, to } => { Operation::Mov { pos, n, to } => {
assert!(pos != to && *n > 0, "empty op: {op:?}\nfrom: {a:?}; {b:?}") assert!(pos != to && *n > 0, "empty op: {op:?}\nfrom: {a:?}")
} }
Operation::Seq { ops } => ops.iter().for_each(|op| check_op(op, a, b)), Operation::Seq { ops } => ops.iter().for_each(|op| check_op(op, a)),
} }
} }