Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F4819011
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
Sun, Aug 23, 10:18 PM
Size
13 KB
Mime Type
text/xml
Expires
Tue, Aug 25, 10:18 PM (11 h, 58 s)
Engine
blob
Format
Raw Data
Handle
286624
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">
<?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->x::int, 0->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 > 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 > 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>
Event Timeline
Log In to Comment