finitedomain
Version:
A fast feature rich finite domain solver
242 lines (209 loc) • 5.63 kB
Plain Text
Import/export DSL CFG
Goal symbol is `cfg`, insignificant whitespace is `whitespace`:
cfg:
statements
statements:
statement [statements]
statement:
newline
comment
atrule newline
varstmt newline
constraint newline
whitespace:
` `
`\t`
newline:
`\r`
`\n`
comment:
/#.*$/m
anywhitespace:
whitespace
newline
ident:
quoted-ident
unquoted-ident
quoted-ident:
/'[^']+'/
can contain anything except single quotes
must be quoted throughout the input problem
solver will use name as if without quotes (relevant when reading results or debugging)
unquoted-ident:
/[^0-9()\[\] \t\n\r,'=][^()\[\'] \t\n\r,=]*/
cannot result in a literal of this CFG
cannot result in a keyword part of a literal of this CFG (matrix, distinct, etc)
cannot start with a digit
idents:
ident [`,` idents]
number:
/\d+/
atrule:
`@custom` ident [`=`] *
`@custom targets [`=`] all`
`@custom targets(` idents `)`
`@mode` mode
*:
i'm just being lazy. parse through to eol. hand of to special handler for this @rule. todo
mode:
`constraints`
`propagators`
varstmt:
`:` ident [`=`] domain [aliases] mods
aliases:
alias [aliases]
alias:
`alias(` ident `)`
domain:
pair
`[` `]`
`[` lohis `]`
`[` pairs `]`
`*`
number
lohis =
lohi [lohi]
lohi =
number [`,`] number [`,`]
pair:
`[` lohi `]`
pairs:
pair [`,`] [pairs]
mods:
mod [mods]
mod:
`@markov` markov
`@list` prio
`@max`
`@mid`
`@min`
`@minMaxCycle`
`@naive`
`@splitMax`
`@splitMin`
prio:
`prio(` expressions `)`
markov:
marko [markov]
marko:
matrix
legend
expand
matrix:
`matrix(` "literal" `)`
the literal is a matrix object that can be evalled like [{vector:[1,0],_boolVarIndex:2},{vector:[0,1]}]
legend:
`legend(` expressions `)`
expand:
`expand(` number `)`
constraint:
expr [cop expr]
nulcall
expr: // does not return a value (expression statement)
vexpr [rop vexpr]
vexpr: // value returning expression (var or constant value)
valcall
ident
number
grouping
expressions:
expr [[`,`] expressions]
nulcall:
`distinct(` expressions `)`
`nall(` expressions `)`
valcall:
`sum(` expressions `)`
`product(` expressions `)`
`all?(` expressions `)`
`nall?(` expressions `)`
`none?(` expressions `)`
rop: // reflecting op (not a constraint on its own, but enforces result var state)
`==?`
`!=?`
`<?`
`<=?`
`>?`
`>=?`
`+`
`-`
`*`
`/`
cop: // constraining op, has no result
`==`
`!=`
`<`
`<=`
`>`
`>=`
`&`
grouping:
`(` vexpr `)`
`(` grouping `)`
There's currently only one semantic rule that we can't codify in the CFG:
- Vars must either be explicitly (through the colon) or implicitly (by being a result var) declared before being used as a value. You cannot implicitly declare and use a constraint in the same statement. It's considered a parse error if a var is used prematurely.
Examples:
## constraint problem export
@custom var-strat = {"_class":"$var_strat_config","type":"naive","inverted":false}
@custom val-strat = min
: v0 = [0 10000] alias(#box1[x])
: v1 = [100 100] alias(#box1[width])
: v2 = [0 10000] alias(#box1[y])
: v3 = [100 100] alias(#box1[height])
: v4 = [610 610] alias(#box2[x])
: v5 = [100 100] alias(#box2[width])
: v6 = [0 10000] alias(#box2[y])
: v7 = [100 100] alias(#box2[height])
: v8 = [100 100]
: v9 = [1 100000000]
: v10 = [1200 1200]
: v11 = [1 100000000]
: v12 = [800 800]
: v13 = [1 100000000]
: v14 = [1 100000000]
: v15 = [590 590]
: v16 = [590 590]
: v17 = [610 610]
: v18 = [0 100000000]
: v19 = [2 2]
: v20 = [400 400]
: v21 = [0 100000000]
v9 = v10 - v1 # initial: [1 100000000] = [1200 1200] - [100 100]
v0 < v9 # initial: [0 10000] < [1 100000000]
v11 = v12 - v3 # initial: [1 100000000] = [800 800] - [100 100]
v2 < v11 # initial: [0 10000] < [1 100000000]
v13 = v10 - v5 # initial: [1 100000000] = [1200 1200] - [100 100]
v4 < v13 # initial: [610 610] < [1 100000000]
v14 = v12 - v7 # initial: [1 100000000] = [800 800] - [100 100]
v6 < v14 # initial: [0 10000] < [1 100000000]
v15 = v0 + v1 # initial: [100 100]5 = [0 10000] + v1
v18 = v3 / v19 # initial: [0 100000000] = [100 100] / [2 2]
v2 = v20 - v18 # initial: [0 10000] = [400 400] - [0 100000000]
v21 = v7 / v19 # initial: [0 100000000] = [100 100] / [2 2]
v6 = v20 - v21 # initial: [0 10000] = [400 400] - [0 100000000]
@custom targets = all
## end of export
## constraint problem export
@custom var-strat = {"_class":"$var_strat_config","type":"naive","inverted":false}
@custom val-strat = min
: v0 = [5 5] alias(STATE)
: v1 = [0 100] alias(V1) @markov legend(10,100) matrix([{vector:[1,0],_boolVarIndex:2},{vector:[0,1]}])
: v2 = [0 1]
: v3 = [5 5]
: v4 = [0 100] alias(V2) @markov legend(10,100) matrix([{vector:[1,0],_boolVarIndex:5},{vector:[0,1]}])
: v5 = [0 1]
: v6 = [100 100]
v2 = v0 ==? v3 # initial: [0 1] = [5 5] ==? [5 5]
markov(v1) # initial: markov([0 100])
v5 = v0 ==? v6 # initial: [0 1] = [5 5] ==? [100 100]
markov(v4) # initial: markov([0 100])
@custom targets = all
## end of export
## constraint problem export
@custom var-strat = {"_class":"$var_strat_config","type":"naive","inverted":false}
@custom val-strat = min
: v0 = [1 4] alias(V1) @list prio(2 4 3 1)
: v1 = [1 4] alias(V2) @list prio(3 1 4 2)
: v2 = [0 0]
v0 < v1
@custom targets = all
## end of export