Monday, November 28, 2005

Formal Whirl Program Definition




Formal Whirl Program Definition



Formal Whirl Program Definition



The execution model of a Whirl program ("Whirl program" is a term
that means either the execution model or the sequence of
instructions which is a composition of "0" and "1" symbols) depend
on the instructions themselves as well as two levels of state:
one state level determines which table to use to determine the
instruction's command (these tables are called the "ops ring" and
the "math ring"), the other state level determines for that table
a set of conditions that determine which command with which
argument (if any) is to be selected for execution. A Whirl
program also contains "memory" of an indeterminate number of
mutable cells, each cell contains a numeric value initialized to
0.

Program



The above description can be summarized precisely by the
following tuple equivalence:













PWhirl = { Ring-typeactive,
Hist, Rings,
MemHT(indexed),
InstHT(indexed)
}
 where:
 





















PWhirl is the execution model of this Whirl Program ("the
program")
Ring-typeactive one-of([ops, math]) indicates which ring is currently active
Histhist(State, last_instruction(Inst)) the results of interpretation of the previous
instruction
 where: 
 







Stateone-of([quescient, executed]) was a command selected for execution?
 'quescient'
means a command was not selected for execution
 'executed'
means a command was selected and executed
Instone-of(["0", "1"]) the last interpreted instruction

Rings { Ringops,
Ringmath }
the current state of each ring
(rings described below)
MemHT(indexed) is A list of memory cells
(described below); current active
one at the head
InstHT(indexed) is Indexed (unsorted) program instructions; current active
one at the head (structure
described below
).




Instructions



Semantics



Whirl has two instructions "0", and "1". The meanings of these
instructions are captured here:










1

Rotate the currently active ring in its indicated direction
and set the history to "hist(quescient,
last_instruction(1))"



ex 1:









GIVEN the current ring is "ops"
 and its direction is "clockwise spin"
 and
the currectly selected command is "3 - zero"
THEN the ops ring's newly selected command is
"4 - load"


ex 2:









GIVEN the current ring is "math"
 and its direction is "counterclockwise spin"
 and
the currectly selected command is "0 - noop"
THEN the math ring's newly selected command is
"11 - neg"



0




First, Reverse the spin of the currently active ring
And then, perform the test:
 















IF the last instruction was "0",
 and the last instruction did not result in a
command execution,
  (i.e.: the command history is
"hist(quescient, last_instruction(0))"
)
THEN execute the currently selected command
 and activate the inactive ring and deactivate this one (i.e.:
switch rings
)
 and set the history to "hist(executed, last_instruction(0))"
OTHERWISE set the history to
"hist(quescient, last_instruction(0))"








ex 1: 
 










GIVEN the current ring is "math"
 and its direction is "counterclockwise spin"
 and
the command history is
"hist(executed, last_instruction(0))"
THEN the math ring's new direction is
"clockwise spin"
 and the command history is set to
"hist(quescient, last_instruction(0))"

ex 2: 
 

















GIVEN the current ring is "ops"
 and its direction is "clockwise spin"
 and the currently selected command is "2 - one"
 and
the command history is
"hist(quescient, last_instruction(0))"
THEN the ops ring's new direction is
"counterclockwise spin"
 and the "one" command is executed
 
(i.e.: the ops Accumulator is set to 1)
 and the ops ring is deactivated; the math ring, activated
 and the command history is set to
"hist(executed, last_instruction(0))"

ex 3: 
 










GIVEN the current ring is "math"
 and its direction is "clockwise spin"
 and
the command history is
"hist(quescient, last_instruction(1))"
THEN the math ring's new direction is
"counterclockwise spin"
 and the command history is set to
"hist(quescient, last_instruction(0))"





Traversal



Whirl instructions are executed in sequence (a
padd command alters the sequence by a
relative amount for the next instruction to be executed), and to
enforce this discipline, we store the sequence of instructions
decorated with an index (such storage is normally referred to as an
"array", but such a term has a grossly overloaded meaning
(particularly when it comes to element access) in the software
engineering field). Individual elements are of the form:



{ Index, Instruction }






where: 
 Index indicates this instruction is ith in
the program source
 Instruction is one-of(["0", "1"])




These elements are stored in a list with the only ordering being
that the current instruction is at the head of the list. The
next instruction is obtained by incrementing the Index by an
offset (the offset is either 1 or the amount in the ops
accumulator if the command executed is a 'padd') and then moving
that corresponding element to the head of the list.



Program Termination



The program will terminate when any of the following conditions
are met:




  • The exit command is executed; or,

  • The next index sought is not in
    InstHT(indexed); or,

  • The program encounters an error (e.g. the user enters
    non-numeric input on a intIO input
    command)




Rings



Whirl programs interact with two rings, the "ops" ring and the
"math" ring. Each ring has its own
(not necessarily orthogonal) set of commands, a selector pointing
to the command to be executed, an accumulator, and a (reversible)
direction of spin. The general structure of each ring is as
follows:










RingType = { CommandsHT, Direction, Accumulator }
 where:
 







Typeone-of([ops, math])which ring this tuple represents
CommandsHT isList of indexed (unsorted) commands; the command at the head is considered
selected for execution
Directionone-of([clockwise spin, counterclockwise spin]) the direction in which the ring rotations for next command selection
Accumulatorvalue(Number) Number is initially 0 and changes when commands are executed









The indexed commands for the ops ring are: The indexed commands for the math ring are:















0-noop 4-load 8-logic
1-exit 5-store 9-if
2-one 6-padd 10-intIO
3-zero 7-dadd 11-ascIO















0-noop 4-mult 8->
1-load 5-div 9-=
2-store 6-zero 10-not
3-add 7-< 11-neg




Ring Command Semantics



Not only is command selection dependent on a dual state layer from the instruction, but also
the command itself may have meaning dependent on the state. The commands are described as follows:



































































IndexCommandPreconditionsEffect
Ops Ring
0noopn/a(no effect)
1exitn/aprogram halts
2oneAccumulator = any valueAccumulator = 1
3zeroAccumulator = any valueAccumulator = 0
4load Accumulator = any value; Current Memory cell = NumAccumulator = Num
5store Accumulator = Num; Current Memory cell = any valueCurrent Memory cell = Num
6padd Accumulator = Num1; program index = Num2 program index = Num1 + Num2
(relative jump)
7dadd Accumulator = Num1; memory index = Num2 memory index = Num1 + Num2
(relative access)
8logic


current memory index = 0
otherwise (Accumulator = Val)



Accumulator = 0
Accumulator = Val & 1
9if


current memory index = 0
otherwise



noop
padd
10intIO


Accumulator = 0
otherwise



current memory value = input integer
current memory value printed as an integer
11ascIO


Accumulator = 0
otherwise



current memory value = input ASCII character
current memory value printed as an ASCII character
Math Ring
0noop n/a(no effect)
1load Accumulator = any value; Current Memory cell = Num Accumulator = Num
2store Accumulator = Num; Current Memory cell = any value Current Memory cell = Num
3add Accumulator = A; Current Memory cell = B Accumulator = A + B
4mult Accumulator = A; Current Memory cell = B Accumulator = AB
5div Accumulator = A; Current Memory cell = B Accumulator = A / B
6zero Accumulator = any valueAccumulator = 0
7<


Accumulator < current memory value
otherwise



Accumulator = 1
Accumulator = 0
8>


Accumulator > current memory value
otherwise



Accumulator = 1
Accumulator = 0
9=


Accumulator = current memory value
otherwise



Accumulator = 1
Accumulator = 0
10not


Accumulator = 0
otherwise



Accumulator = 1
Accumulator = 0
11neg Accumulator = NumAccumulator = -Num



Memory



The Whirl specification states that Whirl program memory is
infinite; we obey by accumulating memory on an as-needed basis
("lazily"). Memory follows a similar structural and allocation
scheme as with program
instruction storage
: decorated with an index when the head
element being the currently selected one.



The difference with memory is that:




  1. instructions are of the binary form "0" or "1", but memory may
    store any (Rational) numeric value; and,

  2. it starts initially with one tuple: { 0, 0.0 }; and,

  3. when another element is selected (with
    dadd) that is not present, that element
    is added to the memory store, initialized to { Index, 0.0 }



It is implementation-dependent as to how memory values are
converted to integral or to (ASCII) character
near-equivalents.









author:Douglas M. Auclair
date:November 28, 2005
whirl@ href="http://www.bigzaphod.org/whirl">http://www.bigzaphod.org/whirl


No comments:

Post a Comment