Skip to content

Commit 929ad2e

Browse files
author
GBathie
committed
Parser for new json format and new operators (Implies and Equiv)
1 parent 80385c6 commit 929ad2e

8 files changed

Lines changed: 260 additions & 130 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ fxhash = "0.2.1"
1515
itertools = "0.14.0"
1616
log = "0.4.27"
1717
ordered-float = "5.0.0"
18+
serde = { version = "1.0.219", features = ["derive"] }
19+
serde_json = "1.0.140"
1820
thiserror = "2.0.12"
1921

2022
[dev-dependencies]

src/algos/meta/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ where
8989

9090
/// Solve Boolean Synthesis problem using Divide and Conquer and the algorithm specified in `params`.
9191
///
92-
/// If the number of traces is more than 128 split immediately.
92+
/// If the number of traces is more than 128, split immediately.
9393
/// Otherwise, try to solve the instance with the algorithm implemented by `params`.
9494
/// If no solution is found, try to find one by splitting recursively.
9595
/// Splitting is handled using [`split_and_solve_non_overlapping`].

src/bin/experiments.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,32 @@ fn main() {
1616
env_logger::init();
1717

1818
let args = CliArgs::parse();
19-
let (traces, alphabet, target, operators) = traces_from_file(&args.input_filename);
19+
let instance = traces_from_file(&args.input_filename);
2020

2121
let (time, sol, name) = match args.command {
2222
AlgoCommand::Enum(p) => get_name_time_sol(
23-
traces,
24-
alphabet,
25-
operators,
26-
target,
23+
instance.traces,
24+
instance.atomic_propositions,
25+
instance.operators,
26+
instance.target,
2727
args.max_size_ltl,
2828
args.domin_nb,
2929
p,
3030
),
3131
AlgoCommand::SetCover(p) => get_name_time_sol(
32-
traces,
33-
alphabet,
34-
operators,
35-
target,
32+
instance.traces,
33+
instance.atomic_propositions,
34+
instance.operators,
35+
instance.target,
3636
args.max_size_ltl,
3737
args.domin_nb,
3838
p,
3939
),
4040
AlgoCommand::BeamSearch(p) => get_name_time_sol(
41-
traces,
42-
alphabet,
43-
operators,
44-
target,
41+
instance.traces,
42+
instance.atomic_propositions,
43+
instance.operators,
44+
instance.target,
4545
args.max_size_ltl,
4646
args.domin_nb,
4747
p,

src/ltl/cm.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,6 @@ impl CharMatrix {
7878
binop_for_cm!(bitor as or);
7979
binop_for_cm!(bitand as and);
8080
binop_for_cm!(until);
81+
binop_for_cm!(implies);
82+
binop_for_cm!(equiv);
8183
}

src/ltl/cs.rs

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
//! and related operators.
33
use std::{
44
fmt::{Debug, Display},
5-
ops::{BitAnd, BitOr, Not},
5+
ops::{BitAnd, BitOr, BitXor, Not},
66
};
77

88
/// Characteristic sequence of an LTL formula on a trace.
99
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1010
pub struct CharSeq {
11-
values: u64,
11+
pub(crate) values: u64,
1212
length: usize,
1313
}
1414

@@ -74,6 +74,41 @@ impl CharSeq {
7474
(self.values & 1) == 1
7575
}
7676

77+
/// Boolean implication operator (->)
78+
#[inline]
79+
pub(crate) fn implies(self, rhs: Self) -> Self {
80+
let CharSeq { values: x, length } = self;
81+
let CharSeq {
82+
values: y,
83+
length: _l2,
84+
} = rhs;
85+
// x -> y <=> !x or y
86+
let values = x.not().bitor(y);
87+
let values = if self.length < 64 {
88+
values & ((1u64 << self.length) - 1)
89+
} else {
90+
values
91+
};
92+
CharSeq { values, length }
93+
}
94+
95+
/// Boolean equivalence operator (<->)
96+
#[inline]
97+
pub(crate) fn equiv(self, rhs: Self) -> Self {
98+
let CharSeq { values: x, length } = self;
99+
let CharSeq {
100+
values: y,
101+
length: _l2,
102+
} = rhs;
103+
let values = (x.bitxor(y)).not();
104+
let values = if self.length < 64 {
105+
values & ((1u64 << self.length) - 1)
106+
} else {
107+
values
108+
};
109+
CharSeq { values, length }
110+
}
111+
77112
/// LTL Next operator (X)
78113
#[inline]
79114
pub(crate) fn next(mut self) -> Self {
@@ -167,7 +202,7 @@ impl FromIterator<bool> for CharSeq {
167202

168203
#[cfg(test)]
169204
mod tests {
170-
use rand::{rng, Rng};
205+
use rand::{Rng, rng};
171206

172207
use super::*;
173208

@@ -320,4 +355,44 @@ mod tests {
320355
assert_eq!(U(x, y), y | (x & X(U(x, y))));
321356
}
322357
}
358+
359+
#[test]
360+
fn x_implies_x() {
361+
for _ in 0..100 {
362+
let x = random_seq();
363+
assert_eq!(x.implies(x).values, (1 << x.length) - 1);
364+
}
365+
}
366+
367+
#[test]
368+
fn implies_def() {
369+
for _ in 0..100 {
370+
let (x, y) = random_pair();
371+
assert_eq!(x.implies(y), x.not() | y);
372+
}
373+
}
374+
375+
#[test]
376+
fn x_equiv_x() {
377+
for _ in 0..100 {
378+
let x = random_seq();
379+
assert_eq!(x.equiv(x).values, (1 << x.length) - 1);
380+
}
381+
}
382+
383+
#[test]
384+
fn equiv_iff_double_implies() {
385+
for _ in 0..100 {
386+
let (x, y) = random_pair();
387+
assert_eq!(x.equiv(y), x.implies(y) & y.implies(x));
388+
}
389+
}
390+
391+
#[test]
392+
fn equiv_def() {
393+
for _ in 0..100 {
394+
let (x, y) = random_pair();
395+
assert_eq!(x.equiv(y), (x & y) | (x.not() & y.not()));
396+
}
397+
}
323398
}

0 commit comments

Comments
 (0)