The text in this file will eventually be incorporated within the K
reference manual.

-----------------------------

KTEST:
------

To test the definition against all the programs in this folder, go to the
parent folder where the simple-untyped.k definition is and execute

  ktest simple-untyped.k --programs programs_and_results --extension simple --exclude dekker

The --exclude option tells which programs to exclude from krunning.  You may
want to exclude programs which take a lot of time, or which don't terminate.

If you want to skip the PDF poster generation, which takes some time, execute

  ktest simple-untyped.k --programs programs_and_results --extension simple --exclude dekker --skip pdf

If you already kompiled your definition and want to only krun the programs:

  ktest simple-untyped.k --programs programs_and_results --extension simple --exclude dekker --skip "kompile pdf"

KTEST:
------

To test your solution, go to the folder where it is located (i.e.,
where the file simple-untyped.k that you wrote is) and then call the
ktest tool on the config.xml file (the one in this folder).  For
example, if your solution is in the parent folder, to test it go there
and type

  ktest tests/config.xml

As another example, if the k distribution is installed at
"/home/cs422-Fall-2013/k" and if you solve this exercise
in "/home/cs422-Fall-2013/joe/hw3/ex1", then test it by executing
the following command from the folder where your solution is:

ktest /home/cs422-Fall-2013/k/dist/tutorial/2_languages/1_simple/1_untyped/exer\
cises/break-continue/config.xml

If you want to skip the kompilation and the pdf generation, then use the
following command instead (and similarly for the second example above):

  ktest tests/config.xml --skip "kompile pdf"

If you want to skip only one of kompile or pdf (typically the pdf), then use
only that one in the --skip option (e.g., --skip pdf).

Both the original SIMPLE untyped programs and the programs in this folder
will be tested.  If your solution is correct, then all tests should pass,
except, potentially, the new break-from-function.simple (see the comments
there for the reason).

If your solution is somewhere else, then use the -d option of ktest to give
the directory to where your K definition is located.  For example, provided
that your definition is in the parent folder, then to test it you can type
the following command in this folder (i.e., programs_and_results):

  ktest config.xml -d ..

KTEST:
------

To test this definition, you can call ktest on the config.xml file in this
folder.  Recall that if you call ktest from any other folder than where
your definition is, then you need the option "-d path/to/your/def/directory".
For example, if you want to call it from this folder, then type

  ktest config.xml -d ..

If you want to call it from the parent folder then just type:

  ktest results/config.xml

Also recall that if your definition is already kompiled, then you can skip
kompilation to save time using the --skip kompile option; if you want to skip
both kompilation and pdf generation then use the option --skip "kompile pdf".

KTEST:
------

The general philosophy of ktest is that the config file contains all the static
info (where the programs and their results are), but it does not contains the
dynamic info (where the actual definition to be tested is).  The same
philosophy holds when we use include.  So all the non-definition attributes
need to be statically solved at the place where the include attribute appears.
The use of an include attribute is nothing but syntactic sugar, so the user
does not have to repeat all that information which has already been given in
the included configuration.  The include attributes can be desugared completely
statically, and thus independently from where the config file containing the
include attribute is called.

In short, the inclusion of a config2.xml file into a config1.xml file is
equivalent to having a flat config1'.xml file instead of config1.xml, which
would behave exactly the same way as config1.xml, wherever ktest may call it
from.  So imagine that you have that config1'.xml built that way, completely
statically (actually, this is probably the way you implement it anyway).  Now,
the same way I can call ktest on config1'.xml from wherever I want, the same
way I want to be able to completely equivalently call ktest on config1.xml from
the same place.

For example, suppose that you are somewhere called "the working directory" and
that the definition you want to test is at path/lang.k from the working
directory.  Suppose that for some reason you really need to put your
config1'.xml/config1.xml file at path1 from the working directory.  Then your
config1'.xml file will look something like this:

<test> definition="path/lang.k" programs="P1" ...  </test>

where P1 is the relative path from the directory path1 to where the programs
are, and you would call it with the command

  ktest path1/config1'.xml

Now suppose that a config2.xml file for testing lank.k against the same
programs has already been created in the past and that you would like to
replace the verbose and redundant config1'.xml with a config1.xml which simply
includes config2.xml.  For concreteness, assume that config2.xml is at relative
path path2 from where config1'.xml/config1.xml is, and that its contents is

<test> definition="lang.k" programs="P2" ...  </test>

Then it must be the case that P1=path1/P2.  Knowing this, we can call ktest on
config2.xml as follows:

  ktest path1/path2/config2.xml --directory path

This suggests that we include config2.xml into config1.xml as follows:

  <include file="path2/config2.xml" directory="path">

That is, the include attribute in config.xml contains exactly and only the
information that I would have to manually pass to ktest to call config2.xml
instead of config1'.xml or config1.xml.

However, since configuration files have fixed programs folders, we have to
agree on what are the programs corresponding to the include attribute in
config1.xml.  There is only one reasonable way that can be, namely the same
programs folder as in config1'.xml, that is, P1.  So in a command like

  ktest path1/config1.xml --directory path --programs P

the root directory P is applied to P1 and NOT to P2 (again, think config1'.xml
instead of config1.xml).  So the above command would be equivalent to

  ktest path1/path2/config2.xml --directory path --programs P/path1/P2



KTEST: CONFIGURATION FILES: TEST ELEMENT:
-----------------------------------------

In a batch mode, ktest requires a configuration file.

A configuration file can have multiple <test> elements. A <test> element
corresponds to a single job mode where each attribute corresponds to the
command line option of the same name.

A <test> element requires a K definition to be tested. For example, the
following <test> element just kompiles "lang.k".

  <test
    definition="lang.k"
  />

Given the above, ktest does nothing but kompilation, but might be useful when
you want to only check if your K definition is valid to kompile.

A <test> element can also have "programs" attributes that specify root
directories of programs to be tested.  Note that all nested sub-directories
are considered when searching the programs.  Several root directories can be
given, separated by white spaces.  A "programs" attribute requires an
"extension" attribute that indicates extensions of programs to be executed.
For example, the following <test> element kompiles "lang.k" and runs all
programs under the directories "P1" and "P2", whose extension is either "E1"
or "E2".

  <test
    definition="lang.k"
    programs="P1 P2"
    extension="E1 E2"
  />

In other words, given the above <test> element, ktest has the same behavior
with the following bash shell script:

  kompile lang.k
  for i in `find P1 -name '*.E1' -o -name '*.E2'`
           `find P2 -name '*.E1' -o -name '*.E2'`
  do
    krun $i
  done

Note that if there exist multiple files with the same name under the "P1" and
"P2" directories, the one in the "P2" is only executed.

An "exclude" attribute specifies which programs not to be executed. A program
whose file name contains a pattern given by a "exclude" attribute is excluded
for the execution.

A "results" attribute specifies root directories of reference outputs. For
each program "pgm.ext", a reference output file "pgm.out" is searched under
the directories given by a "results" attribute. As the "programs" attribute, a
"results" attribute can have several root directories separated by white
spaces, and also, the one from the last root directory  is used when multiple
reference outputs with the same name exist. The directories given by a
"results" attribute are also used when searching an input file of each
program.

A <test> element can have several <kompile-option> elements, which is used at
the kompilation of the given K definition. The default options of krun can be
specified by a <all-programs> element that contains multiple <krun-option>
elements. Note that the <all-programs> element can be given once at most.
Program specific options can be given by <program> elements. A <program>
element has a "name" attribute and multiple <krun-option> elements. A program
whose name contains a pattern given by a "name" attribute is executed with the
options specified by the <program> element.

A <test> element can have an optional "directory" attribute, which specifies
where the kompiled directory is created. If this attribute is not given, the
kompiled directory is created, by default, at the directory in which the K
definition resides. The "directory" attribute is necessary when you provide
multiple <test> elements that have the same K definition but have different
<kompile-option> elements.

To sum, for example, given the following <test> element:

  <test
    definition="lang.k"
    directory="D"
    programs="P1 P2"
    extension="E1 E2"
    exclude="X1 X2"
    results="R1 R2"
    />
    <kompile-option name="--O1" value="V1" />
    <kompile-option name="--O2" value="V2" />
    <all-programs>
      <krun-option name="--O3" value="V3" />
      <krun-option name="--O4" value="V4" />
    </all-programs>
    <program name="N1">
      <krun-option name="--O5" value="V5" />
      <krun-option name="--O6" value="V6" />
    </program>
    <program name="N2">
      <krun-option name="--O7" value="V7" />
      <krun-option name="--O8" value="V8" />
    </program>
  </test>

ktest works as follows:

At first, "lang.k" is kompiled with the options "--O1=V1 --O2=V2", whose
kompiled directory "lang-kompiled" is saved at "D".  And then, all programs
under the "P1" and "P2" directories, whose extension is either "E1" or "E2",
are executed with the options "--O3=V3 --O4=V4". However, a program whose name
contains "N1" (or "N2, resp.) is executed with another series of options
"--O5=V5 --O6=V6" (or "--O7=V7 --O8=V8", resp.). Furthermore, a program whose
name contains "X1" or "X2" is excluded in the execution. When a program, say
"pgm.ext", is executed, an input file "pgm.in" under the "R1" or "R2", if any,
is given as a stdin; and an output file "pgm.out" is used for comparison with
the actual stdout. Note that if there exist multiple files with the same name
under the "P1" and "P2" (or "R1" and "R2", resp.) directories, the only one in
the "P2" (or "R2", resp.) is used.


KTEST: CONFIGURATION FILES: INCLUDE ELEMENT:
--------------------------------------------

A configuration file can have multiple <include> elements as well as <test>
elements. By an <include> element, you can include another configuration file.
For example, you can include "another_config.xml" file as follows:

  <include
    file="another_config.xml"
  />

Basically, an <include> element inherits all attributes and elements from the
included configuration file, which can be, of course, overwritten by
explicitly specifying them, except "definition", "directory", "programs", and
"results" attributes. For example, let a configuration file be:

  <include
    file="another_config.xml"
    exclude="new_exclude"
  />

and the included configuration file "another_config.xml" be:

  <test
    definition="D"
    programs="P"
    exclude="X"
  />

then the included <test> element is virtually same with the following:

  <test
    definition="D"
    programs="P"
    exclude="new_exclude"
  />

Although the "programs" and "results" attributes cannot be overwritten, they
can be incremented by using "more-programs" and "more-results" attributes.
For example, let a configuration file be:

  <include
    file="config.xml"
    more-programs="P"
    more-results="R"
  />

and the included configuration file "config.xml" be:

  <test
    definition="lang.k"
    programs="P1 P2"
    results="R1 R2"
  />

then the included <test> element is virtually same with the following:

  <test
    definition="lang.k"
    programs="P1 P2 P"
    results="R1 R2 R"
  />

Note that "definition" attribute cannot be overwritten at all.

Also note that an <include> element can also have "directory", "programs", or
"results" attributes, but they have another meaning: path resolution.


KTEST: PATH RESOLUTION:
-----------------------

Every path of a configuration file is relative. Three different kinds of paths
exist: definition, programs, and results. A root for the relative directories
can be specified using command line options. For example, let command line
arguments of ktest be:

  $ ktest C/config.xml --directory D --programs P --results R

and 'C/config.xml' be:

  <test
    definition="D1/lang.k"
    programs="P1 P2"
    results="R1 R2"
  />

then the paths are resolved as follows:

  <test
    definition="D/D1/lang.k"
    programs="P/P1 P/P2"
    results="R/R1 R/R2"
  />

Note that the option --directory is optional, and its default value is the
current directory. Also, the options --programs and --results are optional,
and their default values are the directory where the given configuration file
resides. For example, the following command

  ktest C/config.xml

is virtually same with the following:

  ktest C/config.xml --directory . --programs C --results C


The root can be also specified using <include>'s attributes. The same rule is
applied here. For example, let a configuration file 'C/config.xml' have the
following <include> element:

  C/config.xml:

  <include
    file=C1/config1.xml
    directory=D
    programs=P
    results=R
  />

and the included configuration file 'C/C1/config1.xml' be:

  C/C1/config1.xml:

  <test
    definition="D1/lang.k"
    programs="P1 P2"
    results="R1 R2"
  />

then the <include> element is resolved as follows:

  C/config.xml:

  <test
    definition="D/D1/lang.k"
    programs="P/P1 P/P2"
    results="R/R1 R/R2"
  />

Note that the attribute 'definition' is optional, and its default value is the
current directory. Also the attributes 'programs' and 'results' are optional,
and their default values are the directory where the included configuration
file resides. For example, the following <include> element

  <include
    file=C1/config1.xml
  />

is vitally same with the following:

  <include
    file=C1/config1.xml
    directory=.
    programs=C1
    results=C1
  />


To sum, the roots given by command line options and <include>'s attributes are
accumulated to resolve the relative paths. For example, let command line
argument of ktest be:

  $ ktest C/config.xml --directory D --programs P --results R

and configuration file 'C/config.xml' be:

  C/config.xml:

  <include
    file=C1/config1.xml
    directory=D0
    programs=P0
    results=R0
  />

and the included configuration file 'C/C1/config1.xml' be:

  C/C1/config1.xml:

  <test
    definition="D1/lang.k"
    programs="P1 P2"
    results="R1 R2"
  />

then the paths are eventually resolved as follows:

  <test
    definition="D/D0/D1/lang.k"
    programs="P/P0/P1 P/P0/P2"
    results="R/R0/R1 R/R0/R2"
  />

Note that when they are not specified, the default roots are:

  D  = .
  P  = C
  R  = C
  D0 = .
  P0 = C1
  R0 = C1


FILE READ/WRITE:
----------------

If you want to write something to a file at once,  you can go with  #open and
#write .

For example,

 rule <k> run => writeFile("file", "content") ... </k>

 syntax K ::= writeFile(String,String)
 rule writeFile(File:String, Content:String)
   => writeFD(#open(File), Content)

 syntax K ::= writeFD(Int,String)
 rule writeFD(FD:Int, Content:String)
   => #write(FD, Content) ~> #close(FD)

TODO: how to read from a file


KRUN: CONFIGURATION PARSER VARIABLES:
-------------------------------------

Suppose that you want to parse configuration variables (say CFG1, CFG2, ...) 
with different parsers ('parser1', 'parser2', ...).
Here is how you can set a parser for each configuration variable:

-$ krun -config-var-parser="parser1" -cCFG1="some term" -cCFG3="another term"
        -config-var-parser="parser2" -cCFG2="other term" 

Note that once you have setup parser1 then it is active until -config-var-parser
option is used again. That is, in our example, the values of CFG1 and CFG3 are
parsed using parser1 and the value of CFG2 is parser using parser2.

GENERALIZED STRICTNESS:
-----------------------

This feature allows one to customize strictness for all positions or for individual positions.  
Example 1:
  syntax Exp ::= Exp "+" Exp [left, strict<k>(all(context('rvalue)))]
  syntax K ::= rvalue(K) [strict,context(result(RVal))]
  syntax RVal ::= Int

The first line declares "+" strict in the <k> cell, on all arguments, wrapping all of them for evaluation with the 'rvalue context wrapper.
The second line declares rvalue which is itself strict, and which when used as a context cools for results of type RVal (defined on the third line).

Example 2:
  syntax Exp ::=   Exp "=" Exp [right, strict(1, 2(context(rvalue))), assign]
  syntax Exp ::= "rvalue" "(" Exp ")" [context(result(RVal)), strict, klabel(rvalue)]
  
  The first line declares "=" strict (in the <k> cell), evaluating the first argument to the default computation result type (KResult) and the second argument to the default wrapped with the rvalue context wrapper (note the klabel annotation on line 2).

General syntax:
StrictAttribute ::=  StrictHead | StrictHead "(" StrictPositions ")" 
StrictHead ::= StrictType | StrictType "<" CellNames ">"
StrictType ::= "strict" | "seqstrict"
CellNames ::= List{CellName,","}

StrictPositions ::= List{StrictPosition, ","}
StrictPosition ::= Position | Posistion "(" StrictPositionAttributes ")"
Position ::= Int | "all" | "other"
StrictPositionAttributes ::= List{StrictPositionAttribute, ","}
StrictPositionAttribute ::= "context" "(" KLabel ")" 
                          | ContextPositionAttribute

ContextPositionAttribute ::= "result" "(" KSort ")"
                           | "cell" "(" CellNames ")"

ContextContextAttribute ::= "context" "(" ContextPositionAttributes ")"
ContextPositionAttributes ::= List{ContextPositionAttribute, ","}

The semantics when transforming these into context is based on the following principles
(1) the "<" CellNames ">"  arguments of StrictHead are transformed into "cell" "(" CellNames ")" attributes for all positions.
(2) StrictPosition declarations are processed in order.  If duplicates are found, the latter update the attributes values they redeclare.
(3) "all" refers to all positions, updating the existing ones and adding those missing
(4) "other" refers to all positions which have not been declared up to encountering "other"
(5) If "context" attribute is found, the RHS of the context rule is wrapped with the corresponding label and the subattributes of the "context" attribute are used to update the current attributes.
(6) The attributes passed to the context rule for a given position are obtained by updating the production attributes with the StrictPositionAttributes (perhaps updated using the context attributes as specified at (5)) corresponding to that position.

Note: Currently, generalized strictness does not apply to strict labels


MACRO / FUNCTION / ANYWHERE RULES
-----------------------

What is the difference between 'macro', 'anywhere', and 'function'?
The generated maude code seems to be same except metadata. Who makes, if any, a difference?

They all generate the same code now.  However, they are semantically different:

macro should only be used for desugaring, and should be applied to programs before any evaluation is started.

function should only be used for annotating function declarations

anywhere should be used for rules which we want to apply anywhere, disabling configuration concretization for them.


  Function rules are anywhere rules, but anywhere rules are not constrained to functions. 

The [function] attribute can be attached to syntax declarations. All the rules corresponding to that function are annotated automatically as [anywhere] which is only a rule attribute. However, if we want to say that a rule applies anywhere without being related to a function declaration, we simply annotate it with [anywhere] and the contextual transformation will not affect that rule. Therefore the functionality of [function] is implemented using [anywhere], and [anywhere] is an attribute which does not fill the context for that rule.

Does desugaring also apply to rules?  

It surely applies to programs.
Concerning rules, that has been debated in the past, but I'm not sure we reached a definite conclusion. 


The best way to understand these is to forget about the Maude backend.  They translate the same way in Maude because Maude does nor provide us with the subtle differences that we need here.

macro: yes, they are supposed to apply statically, before any rewriting starts, both on the program and on the semantic rules.  So in terms of performance, they are supposed to not count (i.e., their amortized cost is zero).

function: is a label has this attribute, then it is as if it is a builtin function, the only difference being that it is "implemented" using K rules.  We even considered changing the language in which functions are implemented, and following a functional style instead.  So they are meant to be very fast, almost instantaneous, when compared to the other rules.  Different backends are free to implement the functions different ways.  The symbolic execution engine also considers than as part of the axiomatization of the underlying domain in which semantic rules are applied.  So mathematically speaking, functions do not count as semantic computational steps.

anywhere: these are just rules which can apply anywhere they match, so they are expected to be comparatively very slow.  Their application counts as computational steps, so they are interleaved etc. in formal analyses.  It is hard to reason with them in reachability logic.  One should avoid such rules by any means if possible, and use strictness and normal rules instead.


KOMPILE - isSort predicates
---------------------------

Currently the compilation process assumes that all KLabels having 'is' as a prefix are of the form 'isSort' where Sort is the name of a syntactic category.
Therefore users defining their own labels should be aware of this and understand that defining and using an isXXX label which is not related to a sort XXX will 
result in undefined behavior.
