Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cedws/smtlib-go
Go library for generating SMT-LIB problem S-expressions
https://github.com/cedws/smtlib-go
go smtlib z3
Last synced: 6 days ago
JSON representation
Go library for generating SMT-LIB problem S-expressions
- Host: GitHub
- URL: https://github.com/cedws/smtlib-go
- Owner: cedws
- Created: 2024-12-22T10:26:38.000Z (12 days ago)
- Default Branch: master
- Last Pushed: 2024-12-22T10:50:47.000Z (12 days ago)
- Last Synced: 2024-12-22T11:30:20.532Z (12 days ago)
- Topics: go, smtlib, z3
- Language: Go
- Homepage:
- Size: 2.93 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# smtlib-go
Go library for generating [SMT-LIB](https://smt-lib.org/) problem S-expressions.
## Example
This code generates an SMT-LIB problem to stdout which can then be passed to a solver like Z3.
```
// Optimise for the best path (highest value) in the tree given N nodes starting at the bottom with A, B, or C
// Node values are 10, 20, 30, 40, 50, 60 for A, B, C, D, E, F respectively// Correct solution is C, E, F for maxNodes of 3
// Correct solution is B, D, E, F for maxNodes of 4/*
F
D E
A B C
*/
``````go
package mainimport (
"os". "github.com/cedws/smtlib-go"
)func main() {
// Declare the variables
nodeA := Literal("node_A")
nodeB := Literal("node_B")
nodeC := Literal("node_C")
nodeD := Literal("node_D")
nodeE := Literal("node_E")
nodeF := Literal("node_F")// Create the problem with initial capacity of 32
problem := make(Problem, 0, 32)problem.Add(DeclareFun{Name: "node_A", Type: "Bool"})
problem.Add(DeclareFun{Name: "node_B", Type: "Bool"})
problem.Add(DeclareFun{Name: "node_C", Type: "Bool"})
problem.Add(DeclareFun{Name: "node_D", Type: "Bool"})
problem.Add(DeclareFun{Name: "node_E", Type: "Bool"})
problem.Add(DeclareFun{Name: "node_F", Type: "Bool"})// Add tree constraints
problem.Add(Assert{Expression: Implies{Antecedent: nodeD, Consequent: Or{Left: nodeA, Right: nodeB}}})
problem.Add(Assert{Expression: Implies{Antecedent: nodeE, Consequent: Or{Left: nodeB, Right: nodeC}}})
problem.Add(Assert{Expression: Implies{Antecedent: nodeF, Consequent: Or{Left: nodeD, Right: nodeE}}})nodeValues := map[string]int{
"node_A": 10,
"node_B": 20,
"node_C": 30,
"node_D": 40,
"node_E": 50,
"node_F": 60,
}var maximiseTerms []Expression
for node, value := range nodeValues {
maximiseTerms = append(maximiseTerms, Ite{
Condition: Literal(node),
TrueExpr: Literal(value),
FalseExpr: Literal(0),
})
}problem.Add(Maximize{
Objective: Sum(
maximiseTerms,
),
})// Initialise terms
iteTerms := []Expression{
Ite{Condition: nodeA, TrueExpr: Literal(1), FalseExpr: Literal(0)},
Ite{Condition: nodeB, TrueExpr: Literal(1), FalseExpr: Literal(0)},
Ite{Condition: nodeC, TrueExpr: Literal(1), FalseExpr: Literal(0)},
Ite{Condition: nodeD, TrueExpr: Literal(1), FalseExpr: Literal(0)},
Ite{Condition: nodeE, TrueExpr: Literal(1), FalseExpr: Literal(0)},
Ite{Condition: nodeF, TrueExpr: Literal(1), FalseExpr: Literal(0)},
}// Generate best solutions up to 6 max nodes
for maxNodes := range 6 {
problem.Add(Push{})problem.Add(Assert{
Expression: LessThanOrEqual{
Sum(iteTerms),
Literal(maxNodes + 1),
},
})problem.Add(CheckSat{})
problem.Add(GetModel{})problem.Add(Pop{})
}problem.WriteTo(os.Stdout)
}
```