Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F4819634
context.xml
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Aug 24, 4:02 AM
Size
10 KB
Mime Type
text/xml
Expires
Wed, Aug 26, 4:02 AM (19 h, 4 m)
Engine
blob
Format
Raw Data
Handle
286679
Attached To
rXR Xreate
context.xml
View Options
<?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">
<title>Context</title>
<para>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>context</emphasis> in Xreate.</para>
<para>Data that can be captured from analysing control flow consists of two
parts as follows:</para>
<itemizedlist>
<listitem>
<para>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>
<para>Historical data determined by all previous visited code
blocks</para>
</listitem>
</itemizedlist>
<para>Xreate allows to express Context and reason about it by employing
block level annotations. See <link
xlink:href="/w/transcend#code-blocks-and-context">syntax</link>.</para>
<section>
<title>Examples of Context Usage: Suggestions and Requirements</title>
<programlisting xml:id="Examples_1">//someStringFn = function:: string {...}
main = function:: string; entry
{
context:: env(utf8).
someStringFn()
}</programlisting>
<para>Example shows annotation <code>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>someStringFn</code> has different specializations for
different environments. Now it's possible to invoke specialization
tailored for UTF8 environment.</para>
<para>Different story with the next example. Here we want to stipulate
context properties:</para>
<programlisting xml:id="Examples_2">guard:: safe
{
crucialOperation = function:: int
{0}
}
main = function:: int; entry
{
context:: env(safe).
crucialOperation()
}</programlisting>
<para>Function <code>crucialOperation</code> has only one specialization
<code>safe</code> in the example. If context does not provide required
environment <code>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>contract</emphasis> to a
context it works within.</para>
</section>
<section>
<title>Context Propagation</title>
<para>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>context propagation</emphasis>.</para>
<para>Context propagation means that nested blocks
<emphasis>inherit</emphasis> context of parents. Moreover callee
function's context inherits caller's one. Example:</para>
<programlisting xml:id="ContextPropagation1">//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->x::int, 0->acc):: int {
//blockB
crucialOperation(x, acc) // In the nested scope env(safe) context still accessible
}
} </programlisting>
<para>This is example of <emphasis>nested scope context
propagation</emphasis>. It demonstrates availability of a
<code>env(safe)</code> annotation in the context of the nested block
<code>blockB</code> despite being declared in <code>blockA</code>.</para>
<para>More complicated case is <emphasis>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">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>Suppose <code>calculate()</code>works with values measured in
different units. It normalizes each value by invoking <code>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>units(millimeters)</code>in this example, and
<code>calculate()</code> and its callees inherit context allowing compiler
to generate code tailored for specific units only.</para>
<para>Context is determined by reasoning over control flow graph of a
program during compilation. Let's consider example:</para>
<programlisting xml:id="ContextPropagation3">calcInches = function:: int
{
context:: precision(accurate); units(inches).
calculate()
}
calcMillis = function:: int
{
context:: precision(accurate); units(millimeters).
calculate()
}
calculate = function:: int
{ 0 }</programlisting>
<para>Client functions <code>calcInches()</code> and
<code>calcMillis()</code> each define context with a configuration options
for a main routine <code>calculate()</code>. Unlike in previous example,
there are several callers with different context here.</para>
<para>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>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>However the other annotation <code>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>Late Context</emphasis> or <emphasis>Latex</emphasis> for
short.</para>
</section>
<section>
<title>Latex (Late Context)</title>
<para>Static(compile-time) context reasoning is <emphasis>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>It leads to a necessity of having //late context// - context data
gathered on relevant occasion at runtime to determine right
decisions.</para>
<para>However, for any cases it's crucial to consider //possible
contexts// that is, contexts valid only under certain conditions.</para>
<para>Latex approach can be described as follows:</para>
<itemizedlist>
<listitem>
<para>All possible alternative contexts for the given scope computed
during compile time used as input for Latex</para>
</listitem>
<listitem>
<para>All possible paths are numerated and specific latex parameter
created to keep data about current path.</para>
</listitem>
<listitem>
<para>Late parameter used as guard for Late Transcend facts context
consists of.</para>
</listitem>
</itemizedlist>
<para>As of now, to convey late context data latex parameter injected into
function signature as hidden parameter.</para>
<programlisting xml:id="Latex1">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 > 0)::int {computePrecisely()} else {computeFast()}
}</programlisting>
<para>Static scope</para>
<para/>
<programlisting>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 > 0)::num {
context:: computation(fast).
executeComputation()
} else {
context:: computation(precise).
executeComputation()
}
}</programlisting>
<para>To sum up, context consists of two complements parts: on the one
hand //static(early) context// denotes compile time inferences,</para>
<para>and on the other hand, //late(dynamic) context// denotes annotations
decided upon at runtime.</para>
<note>
<para>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>
<title>Remarks on late context implementation</title>
<para/>
<para>To return to a last example, in order to correcly determine
`compute`'s context it's necessary:</para>
<para>After such transformation signature of `executeComputation` looks
like `executeComputation(__hidden_context_data__)`,</para>
<para>where `hidden_context_data` holds data enough to determine within
`executeComputation` which one of possible contexts it encountered
with.</para>
<para>Consequently, `executeComputation` decides which specialization of
`compute` should be called based on `hidden_context_data` value.</para>
<para>Only at run-time there is enough information for
`executeComputation` to decide what specialization of `compute` to
call.</para>
</section>
</chapter>
Event Timeline
Log In to Comment