<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.1" xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:trans="http://docbook.org/ns/transclusion"
         xmlns:svg="http://www.w3.org/2000/svg"
         xmlns:m="http://www.w3.org/1998/Math/MathML"
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns:db="http://docbook.org/ns/docbook">
  <?xxe-sn 2ahi4rjnvuo 1?>

  <title><?xxe-sn 2ahi4rjnvuo 2?>Context</title>

  <para><?xxe-sn 2ahi4rjnvuo 3?>Computer program and its internal states and
  transitions between them can be looked at from two different points of view:
  control flow and data flow. Any information that can be derived from control
  flow is called <emphasis><?xxe-sn 2ahi4rjnvuo 4?>context</emphasis> in
  Xreate.</para>

  <para><?xxe-sn 2ahi4rjnvuo 5?>Data that can be captured from analysing
  control flow consists of two parts as follows:</para>

  <itemizedlist>
    <?xxe-sn 2ahi4rjnvuo 6?>

    <listitem>
      <?xxe-sn 2ahi4rjnvuo 7?>

      <para><?xxe-sn 2ahi4rjnvuo 8?>Instantaneous state or current place
      within the code. It's fully determined by current code block as well as
      hierarchy of all its respective parents</para>
    </listitem>

    <listitem>
      <?xxe-sn 2ahi4rjnvuo 9?>

      <para><?xxe-sn 2ahi4rjnvuo a?>Historical data determined by all previous
      visited code blocks</para>
    </listitem>
  </itemizedlist>

  <para><?xxe-sn 2ahi4rjnvuo b?>Xreate allows to express Context and reason
  about it by employing block level annotations. See <link
  xlink:href="/w/transcend#code-blocks-and-context"><?xxe-sn 2ahi4rjnvuo c?>syntax</link>.</para>

  <section>
    <?xxe-sn 2ahi4rjnvuo d?>

    <title><?xxe-sn 2ahi4rjnvuo e?>Examples of Context Usage: Suggestions and
    Requirements</title>

    <programlisting xml:id="Examples_1"><?xxe-sn 2ahi4rjnvuo f?>//someStringFn = function:: string {...}
            
main = function:: string; entry 
{
    context:: env(utf8).
    someStringFn()
}</programlisting>

    <para><?xxe-sn 2ahi4rjnvuo g?>Example shows annotation <code><?xxe-sn 2ahi4rjnvuo h?>env(utf8)</code>
    which conveys some information about the block thus distinguishing it from
    the others. It allows compiler to apply specific compilation rules for
    this block. Suppose <code><?xxe-sn 2ahi4rjnvuo i?>someStringFn</code> has
    different specializations for different environments. Now it's possible to
    invoke specialization tailored for UTF8 environment.</para>

    <para><?xxe-sn 2ahi4rjnvuo j?>Different story with the next example. Here
    we want to stipulate context properties:</para>

    <programlisting xml:id="Examples_2"><?xxe-sn 2ahi4rjnvuo k?>name - "...."
guard::                         safe
{
  crucialOperation = function:: int 
    {0}
}

main = function::               int; entry 
{
  context::                     env(safe).
  crucialOperation()
}</programlisting>

    <para><?xxe-sn 2ahi4rjnvuo l?>Function <code><?xxe-sn 2ahi4rjnvuo m?>crucialOperation</code>
    has only one specialization <code><?xxe-sn 2ahi4rjnvuo n?>safe</code> in
    the example. If context does not provide required environment
    <code><?xxe-sn 2ahi4rjnvuo o?>env(safe)</code>compiler can't find
    appropriate specialization and halts with compilation error. This is a way
    for function to express requirements or <emphasis><?xxe-sn 2ahi4rjnvuo p?>contract</emphasis>
    to a context it works within.</para>
  </section>

  <section>
    <?xxe-sn 2ahi4rjnvuo q?>

    <title><?xxe-sn 2ahi4rjnvuo r?>Context Propagation</title>

    <para><?xxe-sn 2ahi4rjnvuo s?>Context of a particular code block contains
    not only its own annotations but also reflects parent blocks as well as
    previously executed blocks. It's achieved by <emphasis><?xxe-sn 2ahi4rjnvuo t?>context
    propagation</emphasis>.</para>

    <para><?xxe-sn 2ahi4rjnvuo u?>Context propagation means that nested blocks
    <emphasis><?xxe-sn 2ahi4rjnvuo v?>inherit</emphasis> context of parents.
    Moreover callee function's context inherits caller's one. Example:</para>

    <programlisting xml:id="ContextPropagation1"><?xxe-sn 2ahi4rjnvuo w?>name = "..."
//requires 'safe' context
guard::                                            safe 
{
  crucialOperation = function(a:: int, b::int):: int 
    { 0 }
}

test = function:: int; entry {
  //blockA
  context:: env(safe).

  range = [1..10]:: [int].   
  loop fold(range-&gt;x::int, 0-&gt;acc):: int {  
      //blockB
      crucialOperation(x, acc)  // In the nested scope env(safe) context still accessible
  }
} </programlisting>

    <para><?xxe-sn 2ahi4rjnvuo x?>This is example of <emphasis><?xxe-sn 2ahi4rjnvuo y?>nested
    scope context propagation</emphasis>. It demonstrates availability of a
    <code><?xxe-sn 2ahi4rjnvuo z?>env(safe)</code> annotation in the context
    of the nested block <code><?xxe-sn 2ahi4rjnvuo 10?>blockB</code> despite
    being declared in <code><?xxe-sn 2ahi4rjnvuo 11?>blockA</code>.</para>

    <para><?xxe-sn 2ahi4rjnvuo 12?>More complicated case is
    <emphasis><?xxe-sn 2ahi4rjnvuo 13?>inter-function context
    propagation</emphasis>. It means context propagates through
    "caller/callee" relation: callee inherits caller context. The example
    below demonstrates this:</para>

    <programlisting xml:id="ContextPropagation2"><?xxe-sn 2ahi4rjnvuo 14?>name = "..."
toSI = function(x:: int)::      int
  { 0 }

calculate = function(x:: int):: int 
{ 
  y = toSI(x):: int.
  y
}
            
test = function::               int; entry 
{
  context::                     units(millimeters).
  calculate(10)
}  </programlisting>

    <para><?xxe-sn 2ahi4rjnvuo 15?>Suppose <code><?xxe-sn 2ahi4rjnvuo 16?>calculate()</code>works
    with values measured in different units. It normalizes each value by
    invoking <code><?xxe-sn 2ahi4rjnvuo 17?>toSI()</code> conversion. One
    approach is to keep unit information for each variable independently. But
    if we know that entire program or a part of it works only with specific
    unit we can register it in a context, <code><?xxe-sn 2ahi4rjnvuo 18?>units(millimeters)</code>in
    this example, and <code><?xxe-sn 2ahi4rjnvuo 19?>calculate()</code> and
    its callees inherit context allowing compiler to generate code tailored
    for specific units only.</para>

    <para><?xxe-sn 2ahi4rjnvuo 1a?>Context is determined by reasoning over
    control flow graph of a program during compilation. Let's consider
    example:</para>

    <programlisting xml:id="ContextPropagation3"><?xxe-sn 2ahi4rjnvuo 1b?>name = "..."
calcInches = function::   int
{
  context::               precision(accurate); units(inches).
  calculate()
}

calcMillis = function::   int 
{
  context::               precision(accurate); units(millimeters).
  calculate()
}

calculate = function::    int 
  { 0 }</programlisting>

    <para><?xxe-sn 2ahi4rjnvuo 1c?>Client functions <code><?xxe-sn 2ahi4rjnvuo 1d?>calcInches()</code>
    and <code><?xxe-sn 2ahi4rjnvuo 1e?>calcMillis()</code> each define context
    with a configuration options for a main routine <code><?xxe-sn 2ahi4rjnvuo 1f?>calculate()</code>.
    Unlike in previous example, there are several callers with different
    context here.</para>

    <para><?xxe-sn 2ahi4rjnvuo 1g?>In case with several possible control flow
    paths each introducing different context, only path invariant context
    annotations could be determined at compile time. Obviously, annotations
    that are the same for each possible alternative are part of context in any
    case. It's <code><?xxe-sn 2ahi4rjnvuo 1h?>precision(accurate)</code> in
    the example above, since both client function define it. More formally,
    statically determined context is a conjunction of all possible contexts of
    a given code block.</para>

    <para><?xxe-sn 2ahi4rjnvuo 1i?>However the other annotation
    <code><?xxe-sn 2ahi4rjnvuo 1j?>units(...)</code> differs from path to path
    and can be determined only during runtime. Late Transcend functionality is
    used for this. Context reasoning employing Late Transcend called
    <emphasis><?xxe-sn 2ahi4rjnvuo 1k?>Late Context</emphasis> or
    <emphasis><?xxe-sn 2ahi4rjnvuo 1l?>Latex</emphasis> for short.</para>
  </section>

  <section>
    <?xxe-sn 2ahi4rjnvuo 1m?>

    <title><?xxe-sn 2ahi4rjnvuo 1n?>Latex (Late Context)</title>

    <para><?xxe-sn 2ahi4rjnvuo 1o?>Static(compile-time) context reasoning is
    <emphasis><?xxe-sn 2ahi4rjnvuo 1p?>weak</emphasis> since it's able to
    infer only partial context, consisting of properties that are true for all
    possible paths leading in a CFG to a given block. Other part consists of
    set of possible properties that depends on exact path in CFG. Such
    uncertainty possible to resolve during runtime once it's known which path
    is chosen.</para>

    <para><?xxe-sn 2ahi4rjnvuo 1q?>It leads to a necessity of having //late
    context// - context data gathered on relevant occasion at runtime to
    determine right decisions.</para>

    <para><?xxe-sn 2ahi4rjnvuo 1r?>However, for any cases it's crucial to
    consider //possible contexts// that is, contexts valid only under certain
    conditions.</para>

    <para><?xxe-sn 2ahi4rjnvuo 1s?>Latex approach can be described as
    follows:</para>

    <itemizedlist>
      <?xxe-sn 2ahi4rjnvuo 1t?>

      <listitem>
        <?xxe-sn 2ahi4rjnvuo 1u?>

        <para><?xxe-sn 2ahi4rjnvuo 1v?>All possible alternative contexts for
        the given scope computed during compile time used as input for
        Latex</para>
      </listitem>

      <listitem>
        <?xxe-sn 2ahi4rjnvuo 1w?>

        <para><?xxe-sn 2ahi4rjnvuo 1x?>All possible paths are numerated and
        specific latex parameter created to keep data about current
        path.</para>
      </listitem>

      <listitem>
        <?xxe-sn 2ahi4rjnvuo 1y?>

        <para><?xxe-sn 2ahi4rjnvuo 1z?>Late parameter used as guard for Late
        Transcend facts context consists of.</para>
      </listitem>
    </itemizedlist>

    <para><?xxe-sn 2ahi4rjnvuo 20?>As of now, to convey late context data
    latex parameter injected into function signature as hidden
    parameter.</para>

    <programlisting xml:id="Latex1"><?xxe-sn 2ahi4rjnvuo 21?>name = "..."
import raw ("core/control-context.lp").

compute = function::     int 
  { 0 }

computeFast = function:: int {
  context::              computation(fast).

  compute()
}

computePrecisely = function:: int {
  context::              computation(precise). 

  compute()
}

test = function(cmnd:: int):: int; entry {
  context::              arithmetic(iee754). 

  if (cmnd &gt; 0)::int {computePrecisely()} else {computeFast()} 
}</programlisting>

    <para><?xxe-sn 2ahi4rjnvuo 22?>Static scope</para>

    <para><?xxe-sn 2ahi4rjnvuo 23?></para>

    <programlisting><?xxe-sn 2ahi4rjnvuo 24?>name = "..."
import raw ("core/control-context.lp")
case context:: computation(fast) {
  compute = function:: num {
      0
  }
}

case context:: computation(precise) {
  compute = function:: num {
      0
  }
}

executeComputation= function:: num {
  compute()
}

test = function(cmnd:: num)::  num; entry {
  if (cmnd &gt; 0)::num {
    context::                  computation(fast).
    executeComputation()
  
  } else {
    context::                  computation(precise).
    executeComputation()
  } 
}</programlisting>

    <para><?xxe-sn 2ahi4rjnvuo 25?>To sum up, context consists of two
    complements parts: on the one hand //static(early) context// denotes
    compile time inferences,</para>

    <para><?xxe-sn 2ahi4rjnvuo 26?>and on the other hand, //late(dynamic)
    context// denotes annotations decided upon at runtime.</para>

    <note>
      <?xxe-sn 2ahi4rjnvuo 27?>

      <para><?xxe-sn 2ahi4rjnvuo 28?>Since it is possible to determine number
      of possible contexts with diffent outcome decisions, it is possible to
      determine least size for late context data enough to identify each
      possible variant. (In example above, since there are only two
      specializons of `compute`, 1 bit is enough to convey late context
      data)</para>
    </note>
  </section>

  <section>
    <?xxe-sn 2ahi4rjnvuo 29?>

    <title><?xxe-sn 2ahi4rjnvuo 2a?>Remarks on late context
    implementation</title>

    <para><?xxe-sn 2ahi4rjnvuo 2b?></para>

    <para><?xxe-sn 2ahi4rjnvuo 2c?>To return to a last example, in order to
    correcly determine `compute`'s context it's necessary:</para>

    <para><?xxe-sn 2ahi4rjnvuo 2d?>After such transformation signature of
    `executeComputation` looks like
    `executeComputation(__hidden_context_data__)`,</para>

    <para><?xxe-sn 2ahi4rjnvuo 2e?>where `hidden_context_data` holds data
    enough to determine within `executeComputation` which one of possible
    contexts it encountered with.</para>

    <para><?xxe-sn 2ahi4rjnvuo 2f?>Consequently, `executeComputation` decides
    which specialization of `compute` should be called based on
    `hidden_context_data` value.</para>

    <para><?xxe-sn 2ahi4rjnvuo 2g?>Only at run-time there is enough
    information for `executeComputation` to decide what specialization of
    `compute` to call.</para>
  </section>
</chapter>
