<?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, its internal states and
  transitions between them can be looked at from two different points of view:
  control flow and data flow. In order to express and employ control flow
  related program's properties Xreate supports mechanism called
  <emphasis><?xxe-sn 2axopn9e3uo 1?>context</emphasis> — ability to assign
  transcend data to a code blocks in a way that related blocks in the CFG have
  related contexts.</para>

  <para><?xxe-sn 2ahi4rjnvuo 5?>Code block's context is exhaustingly defined
  as follows:</para>

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

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

      <para><?xxe-sn 2ahi4rjnvuo 8?>Block's place within the code in terms of
      hierarchy of all its respective parents.</para>
    </listitem>

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

      <para><?xxe-sn 2ahi4rjnvuo a?>Historical data determined by previous
      visited code blocks in terms of "caller-callee" relation graph.</para>
    </listitem>
  </itemizedlist>

  <para><?xxe-sn 2ahi4rjnvuo b?>Block level annotations are used to define
  context and reason about it. See <link
  xlink:href="/d/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?>In this example the annotation
    <code><?xxe-sn 2ahi4rjnvuo h?>env(utf8)</code> conveys some information
    about the block thus distinguishing it from the others, which allows 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. In this
    case context can be viewed as a <emphasis><?xxe-sn 2axopn9e3uo 2?>suggestion</emphasis>
    to pick up appropriate specialization.</para>

    <para><?xxe-sn 2ahi4rjnvuo j?>Also there is possibility to define expected
    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 the context does not provide required environment
    <code><?xxe-sn 2ahi4rjnvuo o?>env(safe)</code>compiler can't find
    appropriate specialization and reports compilation error. This is a way
    for function to express <emphasis><?xxe-sn 2axopn9e3uo 3?>requirements</emphasis>
    or contract 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?><emphasis><?xxe-sn 2axopn9e3uo 4?>Context
    propagation</emphasis> means that contexts of different blocks are
    connected reflecting control flow. Context of a particular code block is
    gathered from following sources:</para>

    <itemizedlist>
      <?xxe-sn 2axopn9e3uo 5?>

      <listitem>
        <?xxe-sn 2axopn9e3uo 6?>

        <para><?xxe-sn 2axopn9e3uo 7?>Local context — annotations that are
        defined within the block</para>
      </listitem>

      <listitem>
        <?xxe-sn 2axopn9e3uo 8?>

        <para><?xxe-sn 2axopn9e3uo 9?>Parent context. Block's context inherits
        context of its parent reflecting block's place within a
        program.</para>
      </listitem>

      <listitem>
        <?xxe-sn 2axopn9e3uo a?>

        <para><?xxe-sn 2axopn9e3uo b?>Client context. Blocks context also
        includes caller's context reflecting control flow. It allows taking
        into account in which context a given code is used.</para>
      </listitem>
    </itemizedlist>

    <para><?xxe-sn 2ahi4rjnvuo u?>Example below</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?>demonstrates context propagation to a nested
    block which is exhibited by 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 defined in the <code><?xxe-sn 2ahi4rjnvuo 11?>blockA</code>.</para>

    <para><?xxe-sn 2ahi4rjnvuo 12?>Another case is propagation from caller to
    a callee. 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(mm).
  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(mm)</code>in
    this example, letting functions <code><?xxe-sn 2ahi4rjnvuo 19?>calculate()</code>
    and its callees inherit context allowing compiler to generate code
    tailored for specific units only.</para>
  </section>

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

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

    <note>
      <?xxe-sn 2cpm8zia70g 3?>

      <para><?xxe-sn 2cpm8zia70g 4?>This section is still incomplete. It will
      be reworked soon.</para>
    </note>

    <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. Beyond that are entries
    that depend on exact path in CFG. Such uncertainty is possible to resolve
    during runtime once it's known which path exactly is chosen.</para>

    <para><?xxe-sn 2ahi4rjnvuo 1q?>To solve this problem <emphasis><?xxe-sn 2axopn9e3uo 11?>late
    context</emphasis> is introduced - embedding into compiled code certain
    instructions to gathered data on relevant occasion at runtime to determine
    exact or <emphasis><?xxe-sn 2axopn9e3uo 12?>strong</emphasis>,
    context.</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?>Set of all possible context facts for
        the given block is computed during compile time. Each such fact is
        associated with code paths it holds for.</para>
      </listitem>

      <listitem>
        <?xxe-sn 2axopn9e3uo 13?>

        <para><?xxe-sn 2axopn9e3uo 14?>During execution the information is
        gathered which facts are hold depending on actual code path.
        Information stored in the late parameters. To convey late context data
        the latex parameter is injected into function signature as hidden
        parameter.</para>
      </listitem>

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

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

    <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 it up, context consists of two
    complements parts: on the one hand <emphasis><?xxe-sn 2axopn9e3uo 15?>static(early)
    context</emphasis>, that denotes compile time inference's result and on
    the other hand, <emphasis><?xxe-sn 2axopn9e3uo 16?>late(dynamic)
    context</emphasis> denotes annotations decided upon at runtime.</para>
  </section>
</chapter>
