Edit me

Strings

  • cat(string, string) is used to concatenate two strings together. It can be nested to concatenate more than two strings.
    .decl Y(a:symbol, b:symbol)
    .decl Z(a:symbol, b:symbol, c:symbol)
    .output Z
    Y("a","b").
    Y("c","d").
    Z(a,b, cat(cat(a,b), a)) :- Y(a,b).
    

    The output would be:

    a	b	aba
    c	d	cdc
    
  • contains(string1, string2) is used to check if the latter string contains the former string.
    .decl stringTable(t:symbol)
    .decl substringTable(t:symbol)
    .decl outputData(substr:symbol, str:symbol)
    .output outputData
    outputData(x,y) :- substringTable(x), stringTable(y), contains(x,y).
    stringTable("aaaa").
    stringTable("abba").
    stringTable("bcab").
    stringTable("bdab").
    substringTable("a").
    substringTable("ab").
    substringTable("cab").
    

    The output would be:

    a	aaaa
    a	abba
    a	bcab
    a	bdab
    ab	abba
    ab	bcab
    ab	bdab
    cab	bcab
    
  • match is used to check if the latter string matches a wildcard pattern specified in the former string.
    .decl inputData(t:symbol)
    .decl outputData(t:symbol)
    .output outputData
    outputData(x) :- inputData(x), match("a.*",x).
    inputData("aaaa").
    inputData("abba").
    inputData("bcab").
    inputData("bdab").
    

    The output would be:

    aaaa
    abba
    
  • ord(string) is used to return the ordinal number associated with string. This is not a lexicographic ordering. The ordinal number is based on the order of appearance (see example below).
    .decl n(x:symbol)
    n("Homer").
    n("Marge").
    n("Bart").
    n("Lisa").
    n("Maggie").
    .decl r(x:number)
    .output r
    r(1) :- n(x), n(y), ord(x) < ord(y), x="Homer", y="Bart".
    r(2) :- n(x), n(y), ord(x) > ord(y), x="Maggie", y="Homer".
    r(3) :- n(x), n(y), ord(x) > ord(y), x="Marge", y="Bart".
    

    The output would be:

    1
    2
    

    r(3) is not set, since ord(“Marge”) is less than ord(“Bart”) (the string “Marge” appears before the string “Bart”, therefore it has a smaller ordinal number).

  • Equality operations (= and !=) are also available for string types, by performing an ordinal comparison.

  • strlen(string) returns the length of string as number.
    .decl length(n:number)
    .output length
    length(n) :- n=strlen("Hello").
    length(n) :- n=strlen("World!").
    

    The output would be:

    5
    6
    
  • substr(string, index, length) is used to return the substring starting at index with length length of string. The index is zero-based.
    .decl substring(s:symbol)
    .output substring
    substring(s) :- s=substr("Hello_", 2, 3).
    substring(s) :- string="World!", s=substr(string, 3, strlen(string)).
    

    The output would be:

    llo
    ld!
    
  • to_number(string) transforms a string representing a number to its associated number.
    .decl tonumber(n:number)
    .output tonumber
    tonumber(n) :- n=to_number("123").
    tonumber(n) :- n=to_number("1534").
    

    The output would be:

    123
    1534
    

    The reverse operation to_string(number) also exists, which turns a number to its string representation.

Arithmetic

  • Soufflé supports standard arithmetic operations +, -, *, /, ^ and %. Examples of this are given below.
    .decl e(x:number, t:symbol, y:number)
    e(10 * 2,"10*2", 20).
    e(10 + 2,"10+2", 12).
    e(10 / 2,"10/2", 5).
    e(10 ^ 2 , "10^2", 100).
    e(10 % 3, "10%3", 1).
    e(2^4%13 , "2^4%13",3).
    
  • Soufflé supports bitwise logical operations: band (bitwise and), bor (bitwise or), bxor (bitwise exclusive-or), bshl (bitwise shift left), bshr (bitwise shift right), and bshru (bitwise shift right/unsigned).

Examples of this are given below.

e(0xFFF1 band 0xF, "0xFFF1 band 0xF", 0x1).
e(0xFF00 bor 0x000F, "0xFF00 bor 0x000F", 0xFF0F).
e(0xFFFF bxor 0x000F, "0xFFFF bxor 0x000F", 0xFFF0).
  • Soufflé supports logical operations that consider every non-zero number as true and always return 1 or 0: land (logical and), lor (logical or), lxor (logical exclusive-or), and lnot (logical not).

Examples of this are given below.

e(1 land 2, "1 land 2", 1).
e(1 land 0, "1 land 0", 0).
e(1 lor 0, "1 lor 0", 1).
  • Soufflé supports max and min operations over numbers.
    e(max(3, 4), "max(3, 4)", 4).
    e(min(3, 4), "min(3, 4)", 3).
    
  • Soufflé supports standard unary operation -.
    e(-2*10,"-20", -20).
    e(-2,"-2", -2).
    e(--2,"--2", 2).
    
  • Soufflé supports standard binary operations >, <, =, !=, >= and <=. Examples of this are given below.
    A(a,c) :- a > c.
    B(a,c) :- a < c.
    C(a,c) :- a = c.
    D(a,c) :- a != c.
    E(a,c) :- a <= c.
    F(a,c) :- a >= c.
    
  • $ is used to generate unique random values to populate a table. It should be used with care as it may result in stepping outside the standard Datalog semantics.
    .decl A (n:number)
    .decl B (a:number, b:number)
    .decl C (a:number, b:number)
    .output C
    A(0).
    A(i+1) :- A(i), i<1000.		
    B($,i) :- A(i).		
    C(i,j) :- B(c,i), B(c,j), i!=j.
    

    The above example does not output anything.

Syntax

In the following, we define constraints and argument values in Soufflé more formally using syntax diagrams and EBNF. The syntax diagrams were produced with Bottlecaps.

Constraints

constraint

constraint ::= argument ( '<' | '>' | '<=' | '>=' | '=' | '!=' ) argument
           | ( 'match' | 'contains' ) '(' argument ',' argument ')'
           | 'true'
           | 'false'

Argument List

Argument List

argument_list ::= ( argument ( ',' argument )* )?

Argument Values

Argument

argument ::= 
      STRING
    | FLOAT
    | UNSIGNED
    | NUMBER
    | '_'
    | '$' ( IDENT ( '(' argument_list ')' )? )?
    | IDENT
    | 'nil'
    | '[' argument_list ']'
    | ( '(' argument | 'as' '(' argument ',' type_name | ( '@' IDENT | intrinsic_functor ) '(' argument_list ) ')'
    | aggregator
    | ( unary_operation | argument binary_operation ) argument     

Unary Operations

Unary Operation

unary_operation ::= '-' | 'bnot' | 'lnot'

Binary Operations

Binary Operation

binary_operation ::=  '+' | '-' | '*' | '/' | '%' | '^' | 'land' | 'lor' | 'lxor' | 'band' | 'bor' | 'bxor' | 'bshl' | 'bshr' | 'bshru' 

Intrinsic Functors

Intrinsic Functor

intrinsic_functor ::= 'cat' | 'ord' | 'range' | 'strlen' | 'substr' | 'to_float' | 'to_number' | 'to_string' | 'to_unsigned'