rules: # TODO(lb): Bitwise identities # TODO(lb): to_number(to_string(x)), etc. - name: depr-prag-legacy short: Remove legacy pragma examples: - before: | .pragma "legacy" after: "" queries: - | ( (pragma key: (string) @s) (#eq? @s "\"legacy\"") ) - name: depr-rel-qual short: Deprecated relation qualifier examples: - before: | .decl f(X: number) input after: | .decl f(X: number) .input f - before: | .decl g() printsize after: | .decl g() .printsize g queries: - | (relation_decl qualifier: "input") - | (relation_decl qualifier: "output") - | (relation_decl qualifier: "printsize") - name: depr-type-decl short: Deprecated type declaration examples: - before: | .number_type T after: | .type T <: number - before: | .symbol_type T after: | .type T <: symbol queries: - | (legacy_type_decl) - name: error-dup-rel-decl short: Duplicated relation declaration long: > Conflicting declarations given for relation. Try deleting one. Soufflé would treat this as an error. captures: true slow: true examples: - before: | .decl f() .decl f() after: | .decl f() queries: - | ( (program (relation_decl (ident) @first) (relation_decl (ident) @second)) (#eq? @first @second) ) - name: error-dup-type-decl short: Duplicated type declaration long: > Conflicting definitions given for type. Try deleting one. Soufflé would treat this as an error. captures: true slow: true examples: - before: | .type Foo <: symbol .type Foo <: number after: | .type Foo <: number queries: - | ( (program (type_decl (subtype left: (ident) @first)) (type_decl (subtype left: (ident) @second))) (#eq? @first @second) ) - name: simpl-binop-const short: Simplify constant binary operation (+, -) examples: - before: | even(2 + 2). after: | even(4). queries: - | (binary_op left: (constant) operator: "+" right: (constant)) - | (binary_op left: (constant) operator: "-" right: (constant)) - name: simpl-binop-id short: Simplify binary operation identity examples: - before: | even(2 + 0). after: | even(2). - before: | num(1 * x) :- even(x). after: | num(x) :- even(x). queries: - | ( (binary_op operator: "+" (constant (number (integer (decimal) @const)))) (#match? @const "0") ) - | ( (binary_op (constant (number (integer (decimal) @const))) operator: "+") (#match? @const "0") ) - | ( (binary_op operator: "-" (constant (number (integer (decimal) @const)))) (#match? @const "0") ) - | ( (binary_op operator: "*" (constant (number (integer (decimal) @const)))) (#match? @const "1") ) - | ( (binary_op (constant (number (integer (decimal) @const))) operator: "*") (#match? @const "1") ) - | ( (binary_op operator: "/" (constant (number (integer (decimal) @const)))) (#match? @const "1") ) - name: simpl-call-cat short: Simplify call to cat examples: - before: | rel(cat("", x)) :- g(x). after: | rel(x). queries: - | ( (functor_call functor: (intrinsic_functor) @func argument: (constant) @con) (#eq? @func "cat") (#eq? @con "\"\"") ) - name: simpl-call-intrin short: Simplify call to intrinsic functor examples: - before: | rel(x) :- x = cat("foo", "bar"). after: | rel(cat("foobar")). queries: - | ( (functor_call functor: (intrinsic_functor) @func . argument: (constant) . argument: (constant)) (#eq? @func "cat") ) - | ( (functor_call functor: (intrinsic_functor) @func argument: (constant)) (#eq? @func "to_float") ) - | ( (functor_call functor: (intrinsic_functor) @func argument: (constant)) (#eq? @func "to_number") ) - | ( (functor_call functor: (intrinsic_functor) @func argument: (constant)) (#eq? @func "to_string") ) - | ( (functor_call functor: (intrinsic_functor) @func argument: (constant)) (#eq? @func "to_unsigned") ) - name: simpl-call-range short: Simplify range expression long: > The default step is 1. examples: - before: | num(x) :- x = range(0, 10, 1). after: | num(x) :- x = range(0, 10). queries: - | ( (range step: (constant) @const) (#eq? @const "1") ) - name: simpl-con-const short: Simplify constant constraint examples: - before: | even(0) :- true. after: | even(0). - before: | valid(x) :- ok(x), false. after: "" - before: | maybe(x) :- no(x), (yes(x); true). after: | maybe(x) :- no(x), yes(x). queries: - | (conjunction (bool)) - name: simpl-con-comp short: Simplify trivial comparison constraint examples: - before: | f(x) :- g(x), x = x. after: | f(x) :- g(x). - before: | f() :- 1 != 1. after: "" queries: - | ( (comparison left: (_) @first right: (_) @second) (#eq? @first @second) ) - name: simpl-neg-double short: Remove double negation of atom captures: true examples: - before: | g() :- h(3), !!f(). after: | g() :- h(3), f(). - before: | g() :- !!!f(). after: | g() :- !f(). queries: - | (monotonic_rule body: (disjunction (conjunction (negation) . (negation)+ . (atom (qualified_name (ident)))) @conj)) - name: simpl-dup-conj short: Remove duplicated atom in conjunction examples: - before: | f(x) :- g(x), h(x), g(x). after: | f(x) :- g(x), h(x). queries: - | ( (conjunction (atom) @first (atom) @second) (#eq? @first @second) ) - name: simpl-dup-fact short: Remove duplicated fact captures: true slow: true examples: - before: | f(0). f(0). after: | f(0). queries: - | ( (program (fact) @first (fact) @second) (#eq? @first @second) ) - name: simpl-dup-rule short: Remove duplicated rule captures: true slow: true examples: - before: | f(x) :- g(x). f(x) :- g(x). after: | f(x) :- g(x). queries: - | ( (program (monotonic_rule) @first (monotonic_rule) @second) (#eq? @first @second) ) - | ( (program (subsumptive_rule) @first (subsumptive_rule) @second) (#eq? @first @second) ) - name: simpl-rule-fact short: Remove rule with fact for a body captures: true slow: true examples: - before: | f(0). g() :- f(0). after: | f(0). g(). queries: # It's hoped the anchors make this more performant... Doesn't appear to help # much. - | ( (program (fact (atom) @fact) (monotonic_rule body: (disjunction . (conjunction . (atom) @rule .) .))) (#eq? @fact @rule) ) - name: simpl-union-dup short: Simplify union with duplicated type examples: - before: | .type U = X | X after: | .type U = X - before: | .type U = T | S | T after: | .type U = T | S queries: - | ( (type_union (qualified_name) @first (qualified_name) @second) (#eq? @first @second) ) - name: simpl-union-prim short: Simplify union with primitive type examples: - before: | .type U = X | symbol after: | .type U = symbol - before: | .type U = T | number | S after: | .type U = number queries: - | (type_union (primitive_type)) - name: style-symb-op short: Prefer symbolic operators examples: - before: | rule(x band y) :- rule(x), rule(y). after: | rule(x & y) :- rule(x), rule(y). - before: | rule(lnot y) :- rule(y). after: | rule(!y) :- rule(y). queries: - | (unary_op operator: "bnot") - | (binary_op operator: "band") - | (binary_op operator: "bor") - | (binary_op operator: "bxor") - | (binary_op operator: "bshl") - | (binary_op operator: "bshr") - | (binary_op operator: "bshru") - | (unary_op operator: "lnot") - | (binary_op operator: "land") - | (binary_op operator: "lor") - | (binary_op operator: "lxor")