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