login  home  contents  what's new  discussion  bug reports     help  links  subscribe  changes  refresh  edit

Edit detail for SymbolsAndVariables revision 1 of 4

1 2 3 4
Editor: kratt6
Time: 2008/01/03 05:32:51 GMT-8
Note: moved from #110

changed:
-
<B>Interpreter</B><br><br>

In IssueTracker #99, I made some incorrect comments on how the Interpreter treats coercion between elements of the two domains <code>Variable(x:Symbol)</code> and 'Symbol'. This new page consists of experiments to find out more, in regard to both the Interpreter and the Compiler. Note that the domain constructor <code>Variable(x:Symbol)</code> contains a unique element with output representation 'x' which may be coerced to the symbol 'x'. The domain 'Symbol' consists of all symbols (I know this does not say anything, but I won't dare to say it consists of all undeclared identifiers or all variables).


\begin{axiom}
)clear all
)set output tex off
)set output algebra on
)set mess bot on
t:Boolean:= x = y
\end{axiom}

Note when an undeclared identifier 'x' is used, the interpreter temporarily turns it into the only element of <code>Variable(x:Symbol)</code>, see (1) where 'x' and 'y' are interpreted as of type <code>Variable()</code>, not 'Symbol'. Unlike 'Symbol', there is no equality testing across different <code>Variable()</code> domains and so in (1) both 'x' and 'y' are coerced to 'Symbol'. 
\begin{axiom}
x:Variable(y):= y
\end{axiom}

This is confirmed by (2), where the assignment is immediate because <code>y:Variable(y)</code>.  Thus from 'Symbol' to <code>Variable()</code> seems to me automatic *in the interpreter* but temporarily. Temporarily, because you can reassign the identifier to any other typed value. This is different than manually declaring the identifier as <code>y: Variable(y)</code>. You cannot reassign with <code>y:=1</code> later without changing the declaration of its type.

However, I was not able to find any function that does this: <code>y +->Variable(y)</code> and we know why: the target domain is dependent on the input.  
\begin{axiom}
t:= ((x::Symbol)=y)
t:= (x = (y::Symbol))
)set mess bot off
\end{axiom}

The absence of this map's signature may be why in (3), the Interpreter did not coerce <code>x:Symbol</code> to <code>x:Variable(y)</code>, but did the opposite. Same for (4), it coerces <code>x:Variable(y)</code> to <code>x:Symbol</code>.

The difference between  <code>y:Variable(y)</code> and <code>y:Symbol</code> for the interpreter is thus that an undefined identifier 'y' behaves as 'Symbol' only transiently on its way to 'Variable(y)', and need to be explicitly coerced back to 'Symbol'.


<B>Compiler</B><br><br>

Now, the real confusion is when one starts using the compiler! (By the way, in Windows 0.1.4 version, all compiling of the test packages, a message appears:

'The syntax of the command is incorrect.'

This does not appear below. Also there is a problem with MathAction/Wiki processing a comment line such as

<code>--%SymbolVariableTest1</code>

So these are omitted from below.)

(a) Without any prior declarations or assignments, you can compile within a routine, <code>y: Variable(y):= y</code> ('SVT1' below) but not <code>x: Variable(y):= y</code> ('SVT2'). Both are acceptable in the interpreter. So in the first case, the 'y' on the rhs is of type <code>Variable(y)</code>, but not in the second case ('SVT2'), where it is untyped and unassigned. According to Section 6.16 of the Axiom book, I think both 'y' on the rhs is free (global) the first time it is encountered in the subroutines.


\begin{spad}
)abbrev package SVT1 SymbolVariableTest1
SymbolVariableTest1(): Spec == Imp where
  Spec ==  with 
    symVar1:() -> Boolean
  Imp == add
    symVar1()==
      y: Variable(y) := y
      x: Variable(y) := y
      t: Boolean := (x = y)
\end{spad}

\begin{axiom}
symVar1()
\end{axiom}


\begin{spad}
)abbrev package SVT2 SymbolVariableTest2
SymbolVariableTest2(): Spec == Imp where
  Spec ==  with 
    symVar2:() -> Boolean
  Imp == add
    symVar2()==
      x: Variable(y):=y
      t:Boolean:= true
\end{spad}

(b) We can compile <code>x:Variable(y):=y</code> if we first declare <code>y: Variable(y)</code> (without assignment, SVT3). 

\begin{spad}
)abbrev package SVT3 SymbolVariableTest3
SymbolVariableTest3(): Spec == Imp where
  Spec ==  with 
    symVar3:() -> Boolean
  Imp == add
    symVar3()==
      y: Variable(y)
      x: Variable(y):=y
      t:Boolean:= true
\end{spad}

Even though 'y' was never defined, the function <code>symVar3()</code> still runs. Actually the local variable 'x' is assigned 'Nil'.

\begin{axiom}
symVar3()
\end{axiom}

But we cannot <code>x:Variable(y):=y</code> if we declare <code>y: Symbol</code> (without assignment, 'SVT4'). 

\begin{spad}
)abbrev package SVT4 SymbolVariableTest4
SymbolVariableTest4(): Spec == Imp where
  Spec ==  with 
    symVar4:() -> Boolean
  Imp == add
    symVar4()==
      y: Symbol
      x: Variable(y):=y
      t:Boolean:= true
\end{spad}

Not even if we assign a value to 'y' and we specify a coercion afterwards ('SVT5'). This is because no such coercion function exists (even if the target is <code>Union("failed", Variable(y))</code>. So this differs from the interpreter.

\begin{spad}
)abbrev package SVT5 SymbolVariableTest5
SymbolVariableTest5(): Spec == Imp where
  Spec ==  with 
   symVar5:() -> Boolean
  Imp == add
    symVar5()==
      y: Symbol := y
      x: Variable(y):=y::Variable(y)
      t:Boolean:= true
\end{spad}

(c) Although we can compile <code>x:Variable(y):=y</code> after declaring <code>y:Variable(y)</code> without assigning a value to 'y' ('SVT3') and in fact run <code>symVar3()</code>, we cannot compile a line actually using 'x' ('SVT6').

\begin{spad}
)abbrev package SVT6 SymbolVariableTest6
SymbolVariableTest6(): Spec == Imp where
  Spec ==  with 
   symVar6:() -> Boolean
  Imp == add
    symVar6()==
      y: Variable(y)
      x: Variable(y):=y
      t:Boolean:= x = y
\end{spad}

Not even testing <code>x=x</code> ('SVT7'). Note that the compiler was apparently trying to use equality from 'Symbol', not equality from <code>Variable(y)</code>. This is a bit bizarre. The identfiers 'x' and 'y' even after declaration to be of type  <code>Variable(y)</code> may still be of type 'Symbol'. On the other hand, an inspection of the code generated for 'SVT3' shows the equality is in fact from <code>Variable(y)</code>. So, why does the compiler try to convert 'y' to 'Symbol'? Why does 'SVT6' fail to compile? (I would expect it to compile, but give a run-time error.)

\begin{spad}
)abbrev package SVT7 SymbolVariableTest7
SymbolVariableTest7(): Spec == Imp where
  Spec ==  with 
   symVar7:() -> Boolean
  Imp == add
    symVar7()==
      y: Variable(y)
      x: Variable(y):=y
      t:Boolean:= x = x
\end{spad}

(d) But if we stay with the domain 'Symbol', we can compile without a problem even if 'y' is never assigned ('SVT8').

\begin{spad}
)abbrev package SVT8 SymbolVariableTest8
SymbolVariableTest8(): Spec == Imp where
  Spec ==  with 
    symVar8:() -> Boolean
  Imp == add
    symVar8()==
      y:Symbol
      x:Symbol:= y
      t:Boolean:= (x=y)
\end{spad}

Computing the next result, which produces the error below in Windows version,
is not displayed properly by MathAction because the system error causes Axiom
to return an error condition.
<pre>
  symVar8()
</pre>

Like <code>Variable(y)</code>, in 'SVT8', 'y' is considered undefined, but unlike 'SVT1', 'SVT8' produces a run time error. Which one is a bug?

<pre>
   >> System error:
   equal: x is a NULL pointer

protected-symbol-warn called with (NIL)
</pre>

Interpreter

In IssueTracker? #99, I made some incorrect comments on how the Interpreter treats coercion between elements of the two domains Variable(x:Symbol) and Symbol. This new page consists of experiments to find out more, in regard to both the Interpreter and the Compiler. Note that the domain constructor Variable(x:Symbol) contains a unique element with output representation x which may be coerced to the symbol x. The domain Symbol consists of all symbols (I know this does not say anything, but I won't dare to say it consists of all undeclared identifiers or all variables).

axiom
)clear all All user variables and function definitions have been cleared. )set output tex off )set output algebra on )set mess bot on t:Boolean:= x = y Function Selection for = Arguments: (VARIABLE x,VARIABLE y) Target type: BOOLEAN -> no appropriate = found in Variable x -> no appropriate = found in Variable y -> no appropriate = found in Boolean [1] signature: (SYMBOL,SYMBOL) -> BOOLEAN implemented: slot (Boolean)$$ from SYMBOL (1) false
Type: Boolean

Note when an undeclared identifier x is used, the interpreter temporarily turns it into the only element of Variable(x:Symbol), see (1) where x and y are interpreted as of type Variable(), not Symbol. Unlike Symbol, there is no equality testing across different Variable() domains and so in (1) both x and y are coerced to Symbol.

axiom
x:Variable(y):= y (2) y
Type: Variable y

This is confirmed by (2), where the assignment is immediate because y:Variable(y). Thus from Symbol to Variable() seems to me automatic in the interpreter but temporarily. Temporarily, because you can reassign the identifier to any other typed value. This is different than manually declaring the identifier as y: Variable(y). You cannot reassign with y:=1 later without changing the declaration of its type.

However, I was not able to find any function that does this: y +->Variable(y) and we know why: the target domain is dependent on the input.

axiom
t:= ((x::Symbol)=y) Function Selection for = Arguments: (SYMBOL,VARIABLE y) Target type: BOOLEAN -> no appropriate = found in Variable y -> no appropriate = found in Boolean [1] signature: (SYMBOL,SYMBOL) -> BOOLEAN implemented: slot (Boolean)$$ from SYMBOL (3) true
Type: Boolean
axiom
t:= (x = (y::Symbol)) Function Selection for = Arguments: (VARIABLE y,SYMBOL) Target type: BOOLEAN -> no appropriate = found in Variable y -> no appropriate = found in Boolean [1] signature: (SYMBOL,SYMBOL) -> BOOLEAN implemented: slot (Boolean)$$ from SYMBOL (4) true
Type: Boolean
axiom
)set mess bot off

The absence of this map's signature may be why in (3), the Interpreter did not coerce x:Symbol to x:Variable(y), but did the opposite. Same for (4), it coerces x:Variable(y) to x:Symbol.

The difference between y:Variable(y) and y:Symbol for the interpreter is thus that an undefined identifier y behaves as Symbol only transiently on its way to Variable(y), and need to be explicitly coerced back to Symbol.

Compiler

Now, the real confusion is when one starts using the compiler! (By the way, in Windows 0.1.4 version, all compiling of the test packages, a message appears:

The syntax of the command is incorrect.

This does not appear below. Also there is a problem with MathAction?/Wiki processing a comment line such as

--%SymbolVariableTest1

So these are omitted from below.)

(a) Without any prior declarations or assignments, you can compile within a routine, y: Variable(y):= y (SVT1 below) but not x: Variable(y):= y (SVT2). Both are acceptable in the interpreter. So in the first case, the y on the rhs is of type Variable(y), but not in the second case (SVT2), where it is untyped and unassigned. According to Section 6.16 of the Axiom book, I think both y on the rhs is free (global) the first time it is encountered in the subroutines.

spad
)abbrev package SVT1 SymbolVariableTest1 SymbolVariableTest1(): Spec == Imp where Spec == with symVar1:() -> Boolean Imp == add symVar1()== y: Variable(y) := y x: Variable(y) := y t: Boolean := (x = y)
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/2836962772639158623-25px004.spad using 
      old system compiler.
   SVT1 abbreviates package SymbolVariableTest1 
------------------------------------------------------------------------
   initializing NRLIB SVT1 for SymbolVariableTest1 
   compiling into NRLIB SVT1 
   compiling exported symVar1 : () -> Boolean
Time: 0 SEC.
(time taken in buildFunctor:  0)
;;;     ***       |SymbolVariableTest1| REDEFINED
;;;     ***       |SymbolVariableTest1| REDEFINED
Time: 0 SEC.
   Warnings: 
      [1] symVar1:  y has no value
   Cumulative Statistics for Constructor SymbolVariableTest1
      Time: 0 seconds
   finalizing NRLIB SVT1 
   Processing SymbolVariableTest1 for Browser database:
--->-->SymbolVariableTest1((symVar1 ((Boolean)))): Not documented!!!!
--->-->SymbolVariableTest1(constructor): Not documented!!!!
--->-->SymbolVariableTest1(): Missing Description
------------------------------------------------------------------------
   SymbolVariableTest1 is now explicitly exposed in frame initial 
   SymbolVariableTest1 will be automatically loaded when needed from 
      /var/zope2/var/LatexWiki/SVT1.NRLIB/code

axiom
symVar1() (5) true
Type: Boolean

spad
)abbrev package SVT2 SymbolVariableTest2 SymbolVariableTest2(): Spec == Imp where Spec == with symVar2:() -> Boolean Imp == add symVar2()== x: Variable(y):=y t:Boolean:= true
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/2427935065936506711-25px006.spad using 
      old system compiler.
   SVT2 abbreviates package SymbolVariableTest2 
------------------------------------------------------------------------
   initializing NRLIB SVT2 for SymbolVariableTest2 
   compiling into NRLIB SVT2 
   compiling exported symVar2 : () -> Boolean
****** comp fails at level 3 with expression: ******
error in function symVar2 
(SEQ (LET (|:| |x| (|Variable| | << y >> |)) | << y >> |)
     (|exit| 1 (LET (|:| |t| (|Boolean|)) |true|)))
****** level 3  ******
$x:= y
$m:= (Variable y)
$f:=
((((|x| #) (|$Information| #) (|symVar2| # #) (|$DomainsInScope| # # #)
   ...)))
   >> Apparent user error:
   NoValueMode
    is an unknown mode

(b) We can compile x:Variable(y):=y if we first declare y: Variable(y) (without assignment, SVT3).

spad
)abbrev package SVT3 SymbolVariableTest3 SymbolVariableTest3(): Spec == Imp where Spec == with symVar3:() -> Boolean Imp == add symVar3()== y: Variable(y) x: Variable(y):=y t:Boolean:= true
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/8532403455899499600-25px007.spad using 
      old system compiler.
   SVT3 abbreviates package SymbolVariableTest3 
------------------------------------------------------------------------
   initializing NRLIB SVT3 for SymbolVariableTest3 
   compiling into NRLIB SVT3 
   compiling exported symVar3 : () -> Boolean
Time: 0 SEC.
(time taken in buildFunctor:  0)
;;;     ***       |SymbolVariableTest3| REDEFINED
;;;     ***       |SymbolVariableTest3| REDEFINED
Time: 0 SEC.
   Warnings: 
      [1] symVar3:  y has no value
   Cumulative Statistics for Constructor SymbolVariableTest3
      Time: 0 seconds
   finalizing NRLIB SVT3 
   Processing SymbolVariableTest3 for Browser database:
--->-->SymbolVariableTest3((symVar3 ((Boolean)))): Not documented!!!!
--->-->SymbolVariableTest3(constructor): Not documented!!!!
--->-->SymbolVariableTest3(): Missing Description
; (DEFUN |SVT3;symVar3;B;1| ...) is being compiled.
;; The variable |y| is undefined.
;; The compiler will assume this variable is a global.
------------------------------------------------------------------------
   SymbolVariableTest3 is now explicitly exposed in frame initial 
   SymbolVariableTest3 will be automatically loaded when needed from 
      /var/zope2/var/LatexWiki/SVT3.NRLIB/code

Even though y was never defined, the function symVar3() still runs. Actually the local variable x is assigned Nil.

axiom
symVar3() (6) true
Type: Boolean

But we cannot x:Variable(y):=y if we declare y: Symbol (without assignment, SVT4).

spad
)abbrev package SVT4 SymbolVariableTest4 SymbolVariableTest4(): Spec == Imp where Spec == with symVar4:() -> Boolean Imp == add symVar4()== y: Symbol x: Variable(y):=y t:Boolean:= true
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/5583142712275742882-25px009.spad using 
      old system compiler.
   SVT4 abbreviates package SymbolVariableTest4 
------------------------------------------------------------------------
   initializing NRLIB SVT4 for SymbolVariableTest4 
   compiling into NRLIB SVT4 
   compiling exported symVar4 : () -> Boolean
****** comp fails at level 2 with expression: ******
error in function symVar4 
(SEQ (|:| |y| (|Symbol|)) | << | (LET (|:| |x| (|Variable| |y|)) |y|)
     | >> | (|exit| 1 (LET (|:| |t| (|Boolean|)) |true|)))
****** level 2  ******
$x:= (LET (: x (Variable y)) y)
$m:= NoValueMode
$f:=
((((|y| #) (|$Information| #) (|symVar4| # #) (|$DomainsInScope| # # #)
   ...)))
   >> Apparent user error:
   CANNOT ASSIGN: y
   OF MODE: (Symbol)
   TO: x
   OF MODE: (Variable y)

Not even if we assign a value to y and we specify a coercion afterwards (SVT5). This is because no such coercion function exists (even if the target is Union("failed", Variable(y)). So this differs from the interpreter.

spad
)abbrev package SVT5 SymbolVariableTest5 SymbolVariableTest5(): Spec == Imp where Spec == with symVar5:() -> Boolean Imp == add symVar5()== y: Symbol := y x: Variable(y):=y::Variable(y) t:Boolean:= true
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/2956805564468662474-25px010.spad using 
      old system compiler.
   SVT5 abbreviates package SymbolVariableTest5 
------------------------------------------------------------------------
   initializing NRLIB SVT5 for SymbolVariableTest5 
   compiling into NRLIB SVT5 
   compiling exported symVar5 : () -> Boolean
****** comp fails at level 3 with expression: ******
error in function symVar5 
(SEQ (LET (|:| |y| (|Symbol|)) |y|)
     (LET (|:| |x| (|Variable| |y|))
       | << |
       (|::| |y| (|Variable| |y|))
       | >> |)
     (|exit| 1 (LET (|:| |t| (|Boolean|)) |true|)))
****** level 3  ******
$x:= (:: y (Variable y))
$m:= $EmptyMode
$f:=
((((|x| #) (|y| # #) (|$Information| #) (|symVar5| # #) ...)))
   >> Apparent user error:
   Cannot coerce y 
      of mode (Symbol) 
      to mode (Variable y)

(c) Although we can compile x:Variable(y):=y after declaring y:Variable(y) without assigning a value to y (SVT3) and in fact run symVar3(), we cannot compile a line actually using x (SVT6).

spad
)abbrev package SVT6 SymbolVariableTest6 SymbolVariableTest6(): Spec == Imp where Spec == with symVar6:() -> Boolean Imp == add symVar6()== y: Variable(y) x: Variable(y):=y t:Boolean:= x = y
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/7214572082810698305-25px011.spad using 
      old system compiler.
   SVT6 abbreviates package SymbolVariableTest6 
------------------------------------------------------------------------
   initializing NRLIB SVT6 for SymbolVariableTest6 
   compiling into NRLIB SVT6 
   compiling exported symVar6 : () -> Boolean
****** comp fails at level 1 with expression: ******
error in function symVar6 
(|y|)
****** level 1  ******
$x:= y
$m:= (Symbol)
$f:=
((((|t| #) (|x| # #) (|y| #) (|$Information| #) ...)))
   >> Apparent user error:
   Cannot coerce y 
      of mode (Variable y) 
      to mode (Symbol)

Not even testing x=x (SVT7). Note that the compiler was apparently trying to use equality from Symbol, not equality from Variable(y). This is a bit bizarre. The identfiers x and y even after declaration to be of type Variable(y) may still be of type Symbol. On the other hand, an inspection of the code generated for SVT3 shows the equality is in fact from Variable(y). So, why does the compiler try to convert y to Symbol? Why does SVT6 fail to compile? (I would expect it to compile, but give a run-time error.)

spad
)abbrev package SVT7 SymbolVariableTest7 SymbolVariableTest7(): Spec == Imp where Spec == with symVar7:() -> Boolean Imp == add symVar7()== y: Variable(y) x: Variable(y):=y t:Boolean:= x = x
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/4490168181249298181-25px012.spad using 
      old system compiler.
   SVT7 abbreviates package SymbolVariableTest7 
------------------------------------------------------------------------
   initializing NRLIB SVT7 for SymbolVariableTest7 
   compiling into NRLIB SVT7 
   compiling exported symVar7 : () -> Boolean
****** comp fails at level 1 with expression: ******
error in function symVar7 
(|y|)
****** level 1  ******
$x:= y
$m:= (Symbol)
$f:=
((((|t| #) (|x| # #) (|y| #) (|$Information| #) ...)))
   >> Apparent user error:
   Cannot coerce y 
      of mode (Variable y) 
      to mode (Symbol)

(d) But if we stay with the domain Symbol, we can compile without a problem even if y is never assigned (SVT8).

spad
)abbrev package SVT8 SymbolVariableTest8 SymbolVariableTest8(): Spec == Imp where Spec == with symVar8:() -> Boolean Imp == add symVar8()== y:Symbol x:Symbol:= y t:Boolean:= (x=y)
spad
   Compiling FriCAS source code from file 
      /var/zope2/var/LatexWiki/6938772839598774218-25px013.spad using 
      old system compiler.
   SVT8 abbreviates package SymbolVariableTest8 
------------------------------------------------------------------------
   initializing NRLIB SVT8 for SymbolVariableTest8 
   compiling into NRLIB SVT8 
   compiling exported symVar8 : () -> Boolean
Time: 0.01 SEC.
(time taken in buildFunctor:  0)
;;;     ***       |SymbolVariableTest8| REDEFINED
;;;     ***       |SymbolVariableTest8| REDEFINED
Time: 0 SEC.
   Warnings: 
      [1] symVar8:  y has no value
   Cumulative Statistics for Constructor SymbolVariableTest8
      Time: 0.01 seconds
   finalizing NRLIB SVT8 
   Processing SymbolVariableTest8 for Browser database:
--->-->SymbolVariableTest8((symVar8 ((Boolean)))): Not documented!!!!
--->-->SymbolVariableTest8(constructor): Not documented!!!!
--->-->SymbolVariableTest8(): Missing Description
; (DEFUN |SVT8;symVar8;B;1| ...) is being compiled.
;; The variable |y| is undefined.
;; The compiler will assume this variable is a global.
------------------------------------------------------------------------
   SymbolVariableTest8 is now explicitly exposed in frame initial 
   SymbolVariableTest8 will be automatically loaded when needed from 
      /var/zope2/var/LatexWiki/SVT8.NRLIB/code

Computing the next result, which produces the error below in Windows version, is not displayed properly by MathAction? because the system error causes Axiom to return an error condition.

  symVar8()

Like Variable(y), in SVT8, y is considered undefined, but unlike SVT1, SVT8 produces a run time error. Which one is a bug?

   >> System error:
   equal: x is a NULL pointer

protected-symbol-warn called with (NIL)