Combinatorial programming made simple
2023-07-18
Jo Devriendt
Performance
- C++ implementation, Exact backend solver
- responsiveness
- 60 'edges' (Joost): 18.1s IDP vs 0.7s MW
- 12 'concretes' (Simon): 3.7s IDP - 0.5s MW
- speed of propagation inference
- TODO: find showcase application
- That's why we're meeting ;)
Motivation
Simplicity
- minimum of concepts for users to learn
- syntax close to familiar (programming) languages
- ease of use (e.g., informative error messages, fewer pitfalls, ...)
- Website with examples & online editor
manyworlds.site
- Source code (should compile on Linux)
gitlab.com/nonfiction-software/manyworlds
(Antlr4 grammar)
- Precompiled docker image
hub.docker.com/r/nonfictionsoftware/manyworlds
- Work-in-progress user documentation
gitlab.com/nonfiction-software/manyworlds/-/wikis/Syntax-and-semantics
- These slides: slides.com/jod/manyworlds_intro
Resources
Map coloring example
declare border: string, string -> bool.
define border as {("BE","NL"),("BE","FR"),("BE","LU"),("BE","DE"),
("LU","FR"),("LU","DE"),("NL","DE"),("FR","DE")} else false.
declare color: string -> {"r","g","b","y"}.
all[color(x)!=color(y) for x,y where border(x,y)].
vocabulary V {
type country := {BE,NL,FR,LU,DE}
border: country * country -> Bool
type rgby := {r,g,b,y}
color: country -> rgby
}
theory T:V {
! (x,z) in border: color(x)~=color(z).
}
structure S:V {
border := {(BE,NL),(BE,FR),(BE,LU),(BE,DE),(LU,FR),(LU,DE),(NL,DE),(FR,DE)}.
}
vocabulary V {
type digit := {0..9}
L: () -> digit
E: () -> digit
S: () -> digit
F: () -> digit
O: () -> digit
D: () -> digit
I: () -> digit
T: () -> digit
}
theory T:V {
L() * 1000 + E() * 100 + 11 * S() + F() * 1000 + O() * 110 + D() =
D() * 1000 + I() * 100 + E() * 10 + T().
L()~=E() & L()~=S() & L()~=F() & L()~=O() & L()~=D() & L()~=I() & L()~=T().
E()~=S() & E()~=F() & E()~=O() & E()~=D() & E()~=I() & E()~=T().
S()~=F() & S()~=O() & S()~=D() & S()~=I() & S()~=T().
F()~=O() & F()~=D() & F()~=I() & F()~=T().
O()~=D() & O()~=I() & O()~=T().
D()~=I() & D()~=O() & D()~=T().
I()~=O() & I()~=T().
O()~=T().
L()~=0 & F()~=0 & D()~=0.
}
structure S:V { }
LESS + FOOD = DIET
declare L,E,S,F,O,D,I,T: -> {0..9}.
1000*L() + 100*E() + 10*S() + S() +
1000*F() + 100*O() + 10*O() + D() =
//---------------------------------
1000*D() + 100*I() + 10*E() + T() .
L()>0. F()>0. D()>0.
distinct(L(),E(),S(),F(),O(),D(),I(),T()).
LESS + FOOD = DIET
- Less advanced language constructs
- types (TODO)
- floating point numbers (TODO)
- inductive definitions (TODO)
- constructed types
- partial functions ...
- tooling
- tutorial (TODO)
- syntax highlighting (TODO)
- interactive consultant
- cDMN ...
Drawbacks
Long term (2023+)
- multiplication/division/modulo
- floating point numbers
- inductive/recursive definitions
- "first class" tuples
- enterprise edition
- ...
To Do
Short term (2023)
- types
- documentation, tutorial
- count inference
- memory use
- runtime efficiency
- syntax highlighting,
auto completion - Windows build
- ...
But ManyWorlds is "good enough" to be put to the test!
Translator FO(.) <-> MW
?
Declarations
All functions are total.
Predicates are simply function symbols mapping to bool
(or {true, false})
declare border: string, string -> bool.
declare <id list> : <list of int/bool/string> -> <finite range>
Every symbol is a function symbol mapping to a finite range
declare color: string -> {"r","g","b","y"}.
declare L,E,S,F,O,D,I,T: -> {0..9}.
Constraints
- Expressions are (nested) terms
- Well-typed according to basic types:
- Simplest terms are values:
- Operators:
- Builtin function symbols:
- Qauntifiers and aggregates:
bool, int, string
true, false, -1, 0, 1, "", "Alice", ...
+, -, *, not, and, or, xor, =, !=, >=, >, <=, <,
... implies ..., ... if ... else ...
min, max, abs, distinct, same, count
<id> [<term> for <variable id list> where <term>]
all[color(x)!=color(y) for x,y where border(x,y)].
all[color(x)!=color(y) for x,y where border(x,y)].
sum[value(x) for x where Item(x) and inKnapsack(x)].
Definitions
define <id or term> as <definition> else <default value>
All definitions will define total functions, so default is used to cover the remaining cases
define border as {("BE","NL"),("BE","FR"),("BE","LU"),("BE","DE"),
("LU","FR"),("LU","DE"),("NL","DE"),("FR","DE")} else false.
Enumeration:
Classic definition:
define fib(x) as
0 if x=0 else
1 if x=1 else
fib(x-1) + fib(x-2)
where x in {0..100} else 0.
General
- All statements end with a '.'
- C-style comments:
- // this is a line comment
- /* this is a multiline
comment */
- Inference (solve, intersect) is given at command line.
ManyWorlds - combinatorial programming made simple
By Jo Devriendt
ManyWorlds - combinatorial programming made simple
- 235