Skip to content

Logic types

Emil Karlén edited this page Mar 1, 2021 · 14 revisions

Logic type values are pure functions as found in most programming languages.

line-matcher

A line-matcher matches a line, with line number and text contents:

contents actual-file.txt : any line : ( line-num < 10 && contents ~ ^OK$ )

~ ^OK$ is a text-matcher applied on the line text contents.

A line-matcher may be assigned to a symbol, so that the code above becomes:

def line-matcher IS_OK_LINE = contents ~ ^OK$

contents actual-file.txt : any line : IS_OK_LINE

Line-matchers may be combined and negated using logic operators

  • && (and)

  • || (or)

  • ! (not)

    contents actual-file.txt : any line : ( matches ^OK$ || matches ^ERROR$ )

Using symbols may improve readability:

def line-matcher IS_OK_LINE     = matches ^OK$
def line-matcher IS_ERROR_LINE  = matches ^ERROR$
def line-matcher IS_RESULT_LINE = IS_OK_LINE || IS_ERROR_LINE

contents actual-file.txt : any line : IS_RESULT_LINE

file-matcher

A file-matcher matches a file:

dir-contents actual-dir : -selection name '*.out'  num-files == 1

name '*.out' is a file-matcher used by this variant of the "dir-contents" instruction.

A file-matcher may be assigned to a symbol, so that the code above becomes:

def file-matcher IS_OUT_FILE = name '*.out'

dir-contents actual-dir : -selection IS_OUT_FILE  num-files == 1

file-matchers may be combined and negated using logic operators

  • && (and)
  • || (or)
  • ! (not)

This, together with the type matcher may improve the assertion:

dir-contents actual-dir : -selection ( type file && suffix .out )  num-files == 1

Using symbols may improve readability:

def file-matcher IS_REGULAR_FILE  = type file
def file-matcher IS_OUT_FILE_NAME = name '*.out'
def file-matcher IS_OUT_FILE      = IS_REGULAR_FILE && IS_OUT_FILE_NAME

dir-contents actual-dir : -selection IS_OUT_FILE  num-files == 1

text-transformer

A text-transformer transforms a string, e.g. the contents of a file.

Many transformers treats the text as a sequence of new-line separated text lines.

The file that the transformer is applied to is not modified.

contents actual-file.txt :
         -transformed-by filter ( contents ~ ^OK$ || contents ~ ^ERROR$ )
         num-lines == 1

A text-transformer may be assigned to a symbol, so that the code above becomes:

def text-transformer SELECT_RESULT_LINES = filter ( matches ^OK$ || matches ^ERROR$ )

contents actual-file.txt :
         -transformed-by SELECT_RESULT_LINES
         num-lines == 1

The "filter" transformer uses line-matchers to select lines. So symbols may again be used to improve readability:

def line-matcher     IS_OK_LINE            = contents ~ ^OK$
def line-matcher     IS_ERROR_LINE         = contents ~ ^ERROR$
def line-matcher     IS_RESULT_LINE        = IS_OK_LINE || IS_ERROR_LINE

def text-transformer SELECT_RESULT_LINES = filter IS_RESULT_LINE

contents actual-file.txt :
         -transformed-by SELECT_RESULT_LINES
         num-lines == 1

With the definitions above, we can add an assertion on the lines that are not result lines:

contents actual-file.txt :
         -transformed-by filter IS_RESULT_LINE
         num-lines == 1

contents actual-file.txt :
         -transformed-by filter ! IS_RESULT_LINE
         num-lines > 0

lines-transformers may be combined using sequencing/composition in the same way as shell pipes:

def text-transformer TIMESTAMP_LINES = replace '..:..' TIMESTAMP | filter contents ~ TIMESTAMP

contents actual-file.txt :
         -transformed-by TIMESTAMP_LINES
         equals <<EOF
start TIMESTAMP
stop  TIMESTAMP
EOF

The "file" instruction

The "file" instruction can create a file that is a transformed variant of an existing file:

def text-transformer TIMESTAMP_LINES = replace '..:..' TIMESTAMP | filter contents ~ TIMESTAMP

file expected-timestamps-in-stdout.txt = -contents-of -rel-result stdout
                                         -transformed-by TIMESTAMP_LINES

contents expected-timestamps-in-stdout.txt : equals <<EOF
start TIMESTAMP
stop  TIMESTAMP
EOF