Skip to content

Commit 1281fee

Browse files
author
GBathie
committed
Helper functions to write tests more easily and additional tests
1 parent 3908812 commit 1281fee

1 file changed

Lines changed: 201 additions & 39 deletions

File tree

src/tests/mod.rs

Lines changed: 201 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::rc::Rc;
22

3+
use itertools::Itertools;
4+
35
use crate::{
46
algos::{atoms, create_initial_cache, enumeration::aux::enum_aux},
57
formula::{rebuild_formula, tree::FormulaTree},
@@ -37,7 +39,13 @@ macro_rules! helper_ops_binary {
3739
};
3840
}
3941

40-
helper_ops_unary!(Globally as G, Finally as F, WeakNext as X, StrongNext as SX);
42+
helper_ops_unary!(
43+
Not as Not,
44+
Globally as G,
45+
Finally as F,
46+
WeakNext as X,
47+
StrongNext as SX
48+
);
4149
helper_ops_binary!(Until as U, Release as R, Or as OR, And as AND);
4250
fn build_atom(s: &str, i: usize) -> FormulaTree {
4351
FormulaTree::Atom(AtomicProposition(s.into(), i))
@@ -74,75 +82,229 @@ fn test_ltl_search(instance: &str, expected: FormulaTree) {
7482
assert!(f.size() <= expected.size());
7583
}
7684

85+
/// Converts an array of array of array of ints (yes)
86+
/// to a json string that looks like this:
87+
/// ```json
88+
/// [
89+
/// {
90+
/// "a": ["1", "1", "1", "0"],
91+
/// "b": ["0", "0", "0", "0"]
92+
/// },
93+
/// {
94+
/// "a": ["0", "1"],
95+
/// "b": ["0", "0"]
96+
/// },
97+
/// {
98+
/// "a": ["0", "0", "1", "1"],
99+
/// "b": ["1", "0", "0", "0"]
100+
/// },
101+
/// ]
102+
/// ```
103+
/// The names ("a", "b" above) are given in the atomic_props array.
104+
fn to_traces_str(traces: &[&[&[i32]]], atomic_props: &[&str]) -> String {
105+
format!(
106+
"[{}]",
107+
traces
108+
.iter()
109+
.map(|ts| {
110+
format!(
111+
"{{ {} }}",
112+
ts.iter()
113+
.zip(atomic_props)
114+
.map(|(t, a)| {
115+
format!(
116+
r#""{a}": [{}]"#,
117+
t.iter().map(|s| format!(r#""{s}""#)).join(", ")
118+
)
119+
})
120+
.join(", ")
121+
)
122+
})
123+
.join(", ")
124+
)
125+
}
126+
127+
fn instance_str(
128+
positive_traces: &[&[&[i32]]],
129+
negative_traces: &[&[&[i32]]],
130+
atomic_props: &[&str],
131+
) -> String {
132+
let positive_traces_str: String = to_traces_str(positive_traces, atomic_props);
133+
let negative_traces_str: String = to_traces_str(negative_traces, atomic_props);
134+
135+
format!(
136+
r#"{{
137+
"positive_traces": {},
138+
"negative_traces": {},
139+
"atomic_propositions": {:?},
140+
"number_atomic_propositions": {},
141+
"number_traces": {},
142+
"number_positive_traces": {},
143+
"number_negative_traces": {},
144+
"max_length_traces": {}
145+
}}"#,
146+
positive_traces_str,
147+
negative_traces_str,
148+
atomic_props,
149+
atomic_props.len(),
150+
positive_traces.len() + negative_traces.len(),
151+
positive_traces.len(),
152+
negative_traces.len(),
153+
positive_traces
154+
.iter()
155+
.filter_map(|s| s.iter().map(|s2| s2.len()).max())
156+
.chain(
157+
negative_traces
158+
.iter()
159+
.filter_map(|s| s.iter().map(|s2| s2.len()).max())
160+
)
161+
.max()
162+
.unwrap()
163+
)
164+
}
165+
166+
macro_rules! make_instance {
167+
(pos : [$( { $( $name:ident : [$($v:literal),*]),* }), *],
168+
neg: [$( { $( $name2:ident : [$($v2:literal),*]),* }), *]) => {
169+
&instance_str(
170+
&[ $( &[ $( &[ $( $v),* ]),* ]),*],
171+
&[ $( &[ $( &[ $( $v2),* ]),* ]),*],
172+
& helper!{ $([ $( $name ),* ]),* }
173+
)
174+
};
175+
}
176+
177+
macro_rules! helper {
178+
([ $( $values:ident ),*] $(, [ $( $v:ident ),*] )*) => { [$( stringify!($values) ),*]};
179+
}
180+
77181
#[test]
78-
fn globally_a() {
79-
let example = r#"{
80-
"positive_traces": [
182+
fn strong_next_not_a() {
183+
let example = make_instance!(pos: [
184+
{
185+
a: [1, 0, 1, 1]
186+
},
81187
{
82-
"a": ["1", "1", "1", "1"]
188+
a: [0, 0, 1]
189+
},
190+
{
191+
a: [1, 0, 1, 0]
83192
}
84193
],
85-
"negative_traces": [
194+
neg: [
195+
{
196+
a: [1, 1, 1, 0]
197+
},
86198
{
87-
"a": ["1", "1", "1", "0"]
199+
a: [0]
88200
},
89201
{
90-
"a": ["0", "1"]
202+
a: [1]
91203
},
92204
{
93-
"a": ["0", "0", "1", "1"]
205+
a: [0, 1, 1, 0, 1]
94206
},
95207
{
96-
"a": ["1", "0", "1", "0"]
208+
a: [1, 1, 1, 1]
209+
}
210+
]);
211+
212+
let exp = SX(Not(build_atom("a", 0)));
213+
test_ltl_search(example, exp);
214+
}
215+
216+
#[test]
217+
fn globally_a() {
218+
let example = make_instance!(pos: [
219+
{
220+
a: [1, 1, 1, 1]
97221
}
98222
],
99-
"atomic_propositions": ["a"],
100-
"number_atomic_propositions": 1,
101-
"number_traces": 5,
102-
"number_positive_traces": 1,
103-
"number_negative_traces": 4,
104-
"max_length_traces": 4
105-
}"#;
223+
neg: [
224+
{
225+
a: [1, 1, 1, 0]
226+
},
227+
{
228+
a: [0, 1]
229+
},
230+
{
231+
a: [0, 0, 1, 1]
232+
},
233+
{
234+
a: [1, 0, 1, 0]
235+
}
236+
]);
106237

107238
let exp = G(build_atom("a", 0));
108239
test_ltl_search(example, exp);
109240
}
110241

111242
#[test]
112243
fn globally_a_or_b() {
113-
let example = r#"{
114-
"positive_traces": [
244+
let example = make_instance!(
245+
pos: [
115246
{
116-
"a": ["0", "1", "1", "1"],
117-
"b": ["1", "0", "0", "0"]
247+
a: [0, 1, 1, 1],
248+
b: [1, 0, 0, 0]
118249
}
119250
],
120-
"negative_traces": [
251+
neg: [
121252
{
122-
"a": ["1", "1", "1", "0"],
123-
"b": ["0", "0", "0", "0"]
253+
a: [1, 1, 1, 0],
254+
b: [0, 0, 0, 0]
124255
},
125256
{
126-
"a": ["0", "1"],
127-
"b": ["0", "0"]
257+
a: [0, 1],
258+
b: [0, 0]
128259
},
129260
{
130-
"a": ["0", "0", "1", "1"],
131-
"b": ["1", "0", "0", "0"]
261+
a: [0, 0, 1, 1],
262+
b: [1, 0, 0, 0]
132263
},
133264
{
134-
"b": ["1", "1", "0", "0", "0"],
135-
"a": ["1", "0", "1", "0", "1"]
265+
b: [1, 1, 0, 0, 0],
266+
a: [1, 0, 1, 0, 1]
136267
}
137-
],
138-
"atomic_propositions": ["a", "b"],
139-
"number_atomic_propositions": 2,
140-
"number_traces": 5,
141-
"number_positive_traces": 1,
142-
"number_negative_traces": 4,
143-
"max_length_traces": 5
144-
}"#;
145-
268+
]);
146269
let exp = G(OR(build_atom("a", 0), build_atom("b", 1)));
147270
test_ltl_search(example, exp);
148271
}
272+
273+
#[test]
274+
fn finally_a_and_b() {
275+
let example = make_instance!(
276+
pos: [
277+
{
278+
a: [0, 0, 1, 1],
279+
b: [1, 0, 1, 0]
280+
},
281+
{
282+
a: [1, 0, 1, 1],
283+
b: [0, 1, 0, 1]
284+
},
285+
{
286+
a: [1, 1, 1],
287+
b: [0, 1, 1]
288+
}
289+
],
290+
neg: [
291+
{
292+
a: [1, 0, 1, 0],
293+
b: [0, 1, 0, 1]
294+
},
295+
{
296+
a: [0, 1],
297+
b: [1, 0]
298+
},
299+
{
300+
a: [0, 0, 1, 1],
301+
b: [1, 0, 0, 0]
302+
},
303+
{
304+
b: [1, 1, 0, 0, 0],
305+
a: [0, 0, 1, 0, 1]
306+
}
307+
]);
308+
let exp = F(AND(build_atom("a", 0), build_atom("b", 1)));
309+
test_ltl_search(example, exp);
310+
}

0 commit comments

Comments
 (0)