AuRUS (Automated Repair of Unrealisable Specifications) is a search-based tool that automatically repairs unrealisable Linear-Time Temporal Logic (LTL) specifications.
A reactive specification is unrealisable when no controller can satisfy it under every possible environment behaviour: the fault lies in the specification itself, not in any implementation. Synthesis tools such as Strix can detect unrealisability, but they don't tell you how to fix it. AuRUS closes that gap: it searches for realisable variants of the specification that remain as semantically and syntactically close as possible to the original intent.
π AuRUS is the first reference implementation of the model-counting-guided repair approach introduced in our GECCO 2023 paper Automated Repair of Unrealisable LTL Specifications Guided by Model Counting (arXiv). If you build on this approach or reimplement any part of it, please cite the paper.
AuRUS is built around a genetic algorithm (GA): a search procedure inspired by natural selection. A GA maintains a population of candidate solutions and improves it over successive generations β the fittest candidates survive and reproduce, their traits are recombined and randomly perturbed, and quality gradually increases. GAs need only two ingredients β a representation of candidates and a fitness function to score them β which makes them a great fit for the space of LTL formulas: discrete, tree-structured, and hard to navigate with directed search. Each classic GA ingredient maps to AuRUS as follows:
- Individual β one candidate solution. In AuRUS: a complete assume-guarantee specification
(A', G'), represented by the syntax trees of its formulas. - Population β the set of candidates alive in a given generation. In AuRUS: seeded from the input specification by adding patterned assumptions over the input variables (e.g.
G F x,G Β¬(x0 β§ β¦ β§ xn)). - Fitness β a score measuring how good a candidate is; it decides who survives. In AuRUS: a weighted combination of realisability status (checked with Strix, on a graded scale so partially fixed candidates still receive gradient), semantic similarity to the original (via bounded model counting β details below), and syntactic similarity (overlap between the sub-formula sets).
- Selection β the fittest individuals become the parents of the next generation. In AuRUS: a best-selector keeps the top-N candidates, which also carry over unchanged (elitism), so the best fitness never decreases.
- Crossover β two parents exchange sub-structures, combining traits discovered independently. In AuRUS: a sub-formula of one parent is transplanted into the other, or sub-formulas from each parent are merged under a binary connective (
β¨, β§, U, R, W). - Mutation β small random changes that inject the diversity crossover cannot provide. In AuRUS: a random sub-formula of an assumption or guarantee is rewritten (see the modes below).
- Termination β the loop stops when a budget is exhausted. In AuRUS: generations (
-Gen), individuals (-Max), or wall-clock time (-GATO); every realisable candidate found along the way is reported as a repair, ranked by fitness.
Mutation in more detail. The operator picks an assumption or a guarantee (biased by -GPR), selects a random sub-formula inside it, and applies one of three modes: a general syntactic mutation (flip/swap atoms, exchange or stack operators), a weakening (Ο β¨ Ο_w β no original model is lost), or a strengthening (Ο_s β¨ Ο β no new model is added). Weakening an assumption relaxes the environment; strengthening a guarantee tightens the system's obligations. The principal directed rules:
| Formula | Weakening | Strengthening |
|---|---|---|
p |
true, p β¨ q, F p |
false, p β§ q, G p |
X Ο |
true, F Ο |
false, G Ο |
F Ο |
true, F G Ο, q W Ο |
false, Ο, G Ο, G F Ο |
G Ο |
true, Ο, F Ο, G F Ο |
false, G Ο1 β¨ G Ο2 (when Ο = Ο1 β¨ Ο2) |
Ο1 β§ Ο2 |
true, Ο1, Ο1 β¨ Ο2, F(Ο1 β§ Ο2) |
false, Ο1 β§ Ο2 β§ q, G(Ο1 β§ Ο2) |
Ο1 β¨ Ο2 |
true, Ο1 β¨ Ο2 β¨ q |
false, Ο1 β§ Ο2, drop a disjunct |
Ο1 U Ο2 |
true, Ο1 W Ο2, F Ο2 |
false, Ο2, Ο1 β§ Β¬Ο2 β§ X(Ο1 U Ο2) |
Ο1 W Ο2 |
true, F Ο1 β¨ (Ο1 U Ο2), G Ο1 β¨ F Ο2 |
false, G Ο1, Ο1 U Ο2 |
(q denotes a fresh literal; one outcome per cell is selected uniformly at random.)
The central technical contribution of our GECCO 2023 paper is a way to quantify how much of the original specification's meaning a candidate repair preserves β without solving an intractable exact model-counting problem. AuRUS approximates the number of models (satisfying lasso traces of bounded length k) of an LTL formula as follows:
LTL Ο ββOWLβββΆ BΓΌchi automaton B_Ο βββΆ word automaton A_Ο βββΆ transfer matrix T_Ο
β
approx. count #Μ(Ο, k) = I Β· T_Ο^k Β· F
- From formulas to automata. Ο is translated into a BΓΌchi automaton, and from it a finite-word automaton
A_Οaccepting exactly the finite prefixes (bases) extendable into a satisfying lasso trace. - Weighted transition matrix.
A_Οis encoded as a matrixT_Οwhere entryT[i][j]is the number of propositional valuations carrying stateito statej. - Counting by matrix exponentiation. The number of accepted bases of length k is
I Β· T_Ο^k Β· F, withI/Fthe indicator vectors of initial and accepting states β one matrix build per formula, then each bound is just a matrix power. - Comparing specifications. The semantic similarity between the original
Sand a candidateS'averages the two containment ratios#(S β§ S', k)/#(S, k)and#(S β§ S', k)/#(S', k)β capturing the behaviours ofSthe repair preserves (lost models) and the new behaviours it introduces (won models).
Worked example. For Ο = G(p β X q) over {p, q}, the word automaton has three live states β start, obligation pending (p just read, q due next), no obligation β plus a sink. Counting the valuations along each edge:
β 0 2 2 β
T_Ο = β 0 1 1 β I = (1 0 0), F = (0 1 1)α΅, I Β· T_Οβ΄ Β· F = 108
β 0 2 2 β
The matrix counts bases, not lassos, so it can under- or over-count β but the fitness function only needs the relative ordering of candidates, which the approximation preserves (9 out of 10 benchmark sets match the exact ranking) while running two to three orders of magnitude faster. This is what makes semantic guidance feasible inside a search evaluating thousands of candidates per run. The implementation computes the two containment ratios through an equivalent complement formulation (counting the lost and won models directly); see FITNESS.md for the equivalence proof and its verification.
This model-counting-based semantic distance, including the weighted-transition-matrix construction and the conjunction-based lost/won-models comparison, was introduced by our paper. If you reuse or reimplement this technique, please cite it.
π¦ Just want the model counter? The transfer-matrix approach lives on as a standalone tool, EstiMate β a fast, accurate model counter that estimates the number of models of LTL formulas using transfer matrices. Use it directly if you need bounded LTL model counting outside the repair setting.
If you use AuRUS, the techniques it implements, or any derivative/reimplementation of this approach in your research, please cite:
MatΓas Brizzio, Maxime Cordy, Mike Papadakis, CΓ©sar SΓ‘nchez, Nazareno Aguirre, and Renzo Degiovanni. 2023. Automated Repair of Unrealisable LTL Specifications Guided by Model Counting. In Proceedings of the Genetic and Evolutionary Computation Conference (GECCO '23), Lisbon, Portugal. ACM, 1499β1507.
@inproceedings{10.1145/3583131.3590454,
author = {Brizzio, Mat\'{\i}as and Cordy, Maxime and Papadakis, Mike and
S\'{a}nchez, C\'{e}sar and Aguirre, Nazareno and Degiovanni, Renzo},
title = {Automated Repair of Unrealisable LTL Specifications Guided by Model Counting},
year = {2023},
isbn = {9798400701191},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
url = {https://doi.org/10.1145/3583131.3590454},
doi = {10.1145/3583131.3590454},
booktitle = {Proceedings of the Genetic and Evolutionary Computation Conference},
pages = {1499--1507},
numpages = {9},
keywords = {search-based software engineering, LTL-synthesis, model counting},
location = {Lisbon, Portugal},
series = {GECCO '23}
}A CITATION.cff file is included, so GitHub's "Cite this repository" button works out of the box.
- Java 11 or later (set
JAVA_HOME). - Apache Ant (a
build.xmlis provided; required libraries ship inlib/). - The Strix reactive synthesis tool β installed natively, or via our Docker image (recommended for macOS, or for Linux users who prefer not to build Strix's dependencies).
git clone https://github.com/MatiasBrizzio/AuRUS.git
cd AuRUS
./setup.sh # checks Java/Ant/Docker and the vendored native tools,
# and warns about known OS-specific gotchas (see below)
ant compileBy default AuRUS invokes the native Strix binary (lib/new_strix/strix) directly β the formula and input/output signal lists are prepared in Java, with no shell wrapper involved. To use the provided Docker image instead β recommended on macOS β pass -docker at runtime.
β οΈ Linux users: the committedlib/new_strix/strixbinary is currently macOS-only. Without-docker, realizability checks fail silently on Linux and the search will not find any repairs../setup.shdetects this and warns you. Two fixes, neither requiring you to own a Linux machine:-docker(the bundledDockerfilecompiles Strix for Linux inside the container β Docker Desktop already runs a Linux VM under the hood, even on macOS), or-synth=ltlsynt, a Docker-free alternative described below.
Besides TLSF, AuRUS also accepts Spectra specifications: pass a .spectra file with the -use-spectra flag (realisability is then checked via the image in docker-spectra/).
cd lib
docker build -t strix_image .
docker-machine create default
docker-machine env --shell cmd defaultRepair the classic (unrealisable) arbiter example:
./unreal-repair.sh case-studies/arbiter/arbiter.tlsfThe arbiter must grant each client infinitely often, but nothing forces clients to keep requesting β so no implementation exists. AuRUS finds repairs such as adding the missing fairness assumptions, recovering the standard fix while staying close to the original specification.
A configuration close to the one used in our experimental evaluation:
./unreal-repair.sh -Max=1000 -Gen=1000 -Pop=100 -k=20 -GATO=7200 -addA \
-out=result/arbiter/ case-studies/arbiter/arbiter.tlsfThis caps generation at 1000 individuals, uses a population of 100, allows the GA to add assumptions, and writes the realisable repairs to result/arbiter/ (default: next to the input specification).
Reference (genuine) solutions can be supplied so AuRUS assesses the quality of the learnt repairs at the end of the run:
./unreal-repair.sh \
-ref=case-studies/arbiter/genuine/arbiter_fixed0.tlsf \
-ref=case-studies/arbiter/genuine/arbiter_fixed1.tlsf \
case-studies/arbiter/arbiter.tlsfUsage: ./unreal-repair.sh [flags] input-file.{tlsf|spectra}
| Flag | Default | Meaning |
|---|---|---|
-Gen=N |
10 | Number of generations |
-Pop=N |
100 | Population size per generation |
-Max=N |
β | Maximum number of individuals to generate |
-GATO=s |
none | Overall GA timeout (seconds) |
-sol=T |
0.0 | Discard solutions with fitness below threshold T |
| Flag | Default | Meaning |
|---|---|---|
-COR=r |
10 | Percentage of the population selected for crossover |
-MR=r |
100 | Probability (%) with which a specification is mutated |
-geneMR=r |
1/|formula| | Probability (%) with which each sub-formula (gene) is mutated (0 = the default 1/size rule) |
-geneNUM=n |
unbounded | Maximum number of sub-formulas mutated per formula (0 = no limit) |
-GPR=r |
50 | Probability (%) of mutating guarantees rather than assumptions β near 0 focuses on assumptions, near 100 on guarantees |
-addA |
off | Allow the GA to add new assumptions (long form -addAssumptions also accepted) |
-removeG |
off | Allow the GA to remove guarantees (long form -removeGuarantees also accepted) |
-onlyInputsA |
off | Restrict newly generated assumptions to input variables only |
-GA_random_selector |
off | Replace the best-selector with a random selector (for ablation studies) |
| Flag | Default | Meaning |
|---|---|---|
-factors=S,SYN,SEM |
0.7,0.1,0.2 |
Weights of realisability status, syntactic distance, and semantic distance (the semantic weight is split evenly between the lost-models and won-models directions) |
-k=N |
10 | Bound for the model-counting approach |
-onlySAT |
off | Disable realisability checking inside the fitness; realisability is verified only on the final candidates |
-strongSAT |
off | Additionally check strong satisfiability of candidates during fitness evaluation |
-precise |
off | Use the exact bounded model counter instead of the automata/matrix approximation β exact counts, orders of magnitude slower |
-random |
off | Baseline mode: generate Max random mutants and check realisability only at the end |
| Flag | Default | Meaning |
|---|---|---|
-RTO=s |
20 | Strix (realisability) timeout per query |
-SatTO=s |
30 | LTL SAT-solving timeout per query |
-MCTO=s |
180 | Model-counting timeout per query |
-docker |
off | Run Strix through the Docker image (recommended on macOS) |
-no-docker |
default | Use the local Strix installation (lib/strix_tlsf.sh) |
-use-spectra |
off | Treat the input as a Spectra specification |
-synth=NAME |
strix |
Realisability tool to use: strix (native binary or Docker, see above) or ltlsynt β a Docker-free alternative from the Spot library, installable via brew install spot (macOS) or conda install -c conda-forge spot (Linux/macOS); see spot.lre.epita.fr/install.html for Debian/Ubuntu packages |
-synth-bin=PATH |
tool default | Override the synthesiser binary path/name |
-ref=file.tlsf |
β | Reference (genuine) solution for the end-of-run quality analysis (repeatable) |
-out=dir |
input dir | Output directory for the generated repairs |
The specifications for every case study used in the paper live in case-studies/, each with its genuine reference solutions. Evaluation scripts:
| Script | Purpose |
|---|---|
run-literature.sh |
Case studies from the literature (default configuration) |
run-syntech.sh |
Case studies from the SynTech benchmark |
run-syntcomp.sh |
Case studies from the SYNTCOMP benchmark |
run-benchmarks.sh |
Runs each case study 10 times (also usable for the random-generation baseline) |
run-sensitivity-analysis.sh |
Sensitivity analysis (configure run-all-sensitivity.sh / run-all-sensitivity-syntcomp.sh first to enable/disable fitness components) |
Use read-results.sh to summarise the runs:
./read-results.sh result/result-70-10-20/arbiter/arbiter-genuineThis shows the 10-run results for the arbiter under weights 0.7 (realisability), 0.1 (syntactic), 0.2 (semantic).
AuRUS is implemented and maintained by:
Questions, bug reports, and contributions are welcome β please open an issue or a pull request, contact me by email or by skype maty.brizzio.
AuRUS is released under the GNU GPL v3.