No edit summary |
|||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
The current versions of ProB can make use the clingo ASP solver as an alternate way of solving constraints. | The current versions of ProB can make use the clingo ASP solver as an alternate way of solving constraints. | ||
This backend translates a subset of B formulas to SAT by encoding the formulas in ASP (Answer Set Programming) first and then using clingo to translate this to SAT and solve it. | This backend translates a subset of B formulas to SAT by encoding the formulas in ASP (Answer Set Programming) first and then using clingo to translate this to SAT and solve it. | ||
Limitations: | |||
* it can only translate first-order values (no sets of sets, no higher-order relations or functions) | |||
* it cannot yet deal with nested existential quantifiers inside universal quantifiers | |||
In contrast to the Kodkod backend, B2ASP can deal with arbitrary n-ary relations (and not just binary ones) and there are no issues with integer overflows. | |||
== Using B2ASP == | == Using B2ASP == | ||
| Line 113: | Line 119: | ||
== Article == | == Article == | ||
[https://link.springer.com/chapter/10.1007/978-3-032-15981-6_9 Michael Leuschel: | The following [https://link.springer.com/chapter/10.1007/978-3-032-15981-6_9 article] describes this backend in more detail: | ||
Using Prolog to Translate Set Theory and B to SAT. PADL 2025: 143-160. | * Michael Leuschel: Using Prolog to Translate Set Theory and B to SAT. PADL 2025: 143-160. | ||
The article also has an accompanying [https://zenodo.org/records/17660151 Zenodo archive of benchmarks]. | |||
[https://zenodo.org/records/17660151 Zenodo archive of benchmarks]. | |||
The current versions of ProB can make use the clingo ASP solver as an alternate way of solving constraints. This backend translates a subset of B formulas to SAT by encoding the formulas in ASP (Answer Set Programming) first and then using clingo to translate this to SAT and solve it.
Limitations:
In contrast to the Kodkod backend, B2ASP can deal with arbitrary n-ary relations (and not just binary ones) and there are no issues with integer overflows.
B2ASP solving consists of the following phases:
The backend can be used in the REPL of probcli:
>>> :clingo pq = 1..2 /\ {2,4}
PREDICATE is TRUE
Solution:
pq = {2}
You can use :clingo #file=FILE to solve a predicate from a file. The command :clingo-double-check double checks the solution using ProB's default solver.
You can also use SOLVER_FOR_PROPERTIES preference to specify clingo as backend for solving PROPERTIES (aka axioms) of B models. For example, you can put this into your DEFINITIONS section for this:
SET_PREF_SOLVER_FOR_PROPERTIES == "clingo";
Here is an example using this preference to compute a dominating set of a graph:
MACHINE IceCream_Clingo
// Dominating set example:
// place ice cream vans so that every house (node) is at most one block away from a van
DEFINITIONS
N == 24;
CUSTOM_GRAPH == rec(layout:"dot", rankdir:"TB",
nodes: {j•j∈NODES |
rec(value:j, style:"filled",
fillcolor:IF ice(j)=TRUE THEN "mistyrose" ELSE "white" END
)},
edges: rec(color:"gray", arrowhead:"odot",
arrowtail:"odot", dir:"both",
label:"edge",
edges: edge)
);
bi_edge == (edge ∪ edge⁻¹);
SET_PREF_SOLVER_FOR_PROPERTIES == "clingo";
VISB_SVG_FILE == "IceCream.svg";
VISB_SVG_UPDATES == {n • n∈NODES |
rec(`id`:n, fill: IF ice(n)=TRUE THEN "red" ELSE "LightBlue" END)}
SETS
NODES = {n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,
n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24}
CONSTANTS edge, ice
PROPERTIES
edge∈ NODES ↔ NODES ∧
edge = { n1↦n2, n1↦n4,
n2↦n3,
n3↦n4, n3↦n5, n3↦n7,
n4↦n7,
n5↦n6, n5↦n9,
n6↦n7, n6↦n8,
n7↦n8,
n8↦n10, n8↦n13,
n9↦n10, n9↦n11, n9↦n12,
n11↦n12, n11↦n14,
n12↦n13,
n13↦n16,
n14↦n15, n14↦n17,
n15↦n16, n15↦n17, n15↦n18, n15↦n21,
n16↦n18, n16↦n19,
n17↦n19,
n18↦n19, n18↦n20, n18↦n21,
n19↦n20, n19↦n21,
n20↦n21, n20↦n22,
n21↦n22, n21↦n23, n21↦n24,
n22↦n23, n21↦n24,
n23↦n24
} ∧
ice ∈ NODES→ BOOL ∧
∀x.(x∈NODES ⇒
(ice(x)=TRUE or
TRUE ∈ ice[edge[{x}] ∪ edge⁻¹[{x}]]
)
)
∧ card({x|x∈NODES ∧ ice(x)=TRUE})≤6
/* minimal solution requires 6 vans */
OPERATIONS
v <-- NrVans = BEGIN v := card(ice⁻¹[{TRUE}]) END;
xx <-- Get(yy) = PRE yy∈NODES ∧ {CUSTOM_GRAPH} = ∅ THEN xx:= ice(yy) END;
v <-- Vans = BEGIN v:= ice⁻¹[{TRUE}] END
END
Here is the graphical rendering of a solution using the custom graph definition above:

The following article describes this backend in more detail:
The article also has an accompanying Zenodo archive of benchmarks.