axiom-developer
[Top][All Lists]

Re: [Axiom-developer] pointers//Decontructing domains

 From: William Sit Subject: Re: [Axiom-developer] pointers//Decontructing domains Date: Tue, 10 Nov 2009 15:12:39 -0500

```Tim:

Thanks, your method works. For me at least, it is much
easier to handle strings than SExpression.

Waldek also provided a working method using opOf (but that
involves SExpression, and the output in SExpression can be
Waldek).

To summarize:
It is possible to deconstruct a domain (that is, trace its
constructor and the parameters to that constructor) using
Lisp primitives. Given an identifier whose value at turn
time is an Axiom domain, the function devaluate\$Lisp returns
its value as an SExpression, and the function deconstrut
further turns the result into a list of SExpressions (which
may be useful to extract the first level of parameters, but
not necessary). The components can then be analyzed.
However, testing for equality of SExpressions can be
hazardous when the SExpressions are constructed in different
ways but the outputForms look identical. There are (at
least?) two ways to get around the problem. Assume we have
a, b defined below (but the value of the identifier a is not
really assumed known at compile time):

a:=Fraction Integer
b:=devaluate(a)\$Lisp
(Fraction (Integer))   Type SExpression

(1) (Waldek): use opOF to pick out the constructor of the
domain and test against a candidate using a quote expression
in Lisp coerced to an SExpression:

testW:='Fraction::SEX
c:=opOf(b)\$Lisp
(c=testW)@Boolean

(2) (Tim): use a Lisp function SYMBOL_-NAME and then convert
the result into a string before testing:

testT:="Fraction"
c:=string(SYMBOL_-NAME(b.1)\$Lisp)
(c=testT)@Boolean

In either method, do not set testW or testT to
"Fraction"::SEX, which would not test correctly.

William

Tim Daly wrote:
>
> I'm not sure what you are asking. Are you having trouble with working in
> the SExpression domain?
> You can move the SExpressions out to other domains. Sometimes it is
> painful but it works. So:
>
> a:=FiniteField(5,2)
> b:=devaluate(a)
> string(SYMBOL_-NAME(b.1)\$Lisp) ==> "FiniteField" (of type String)
> integer(b.1) ==> 5  (of type PositiveInteger)
>
> Does this help?
>
> Tim
>
> William Sit wrote:
> > It appears that to test the constructor, one must test a candidate
> > against a known one via the constructor itself, and not be "fiat" by
> > using a SExpression. Is this related to hashing of pointers?
> > Continuing with script in the previous email (attached):
> >
> > (11) -> EQ(c.1,d)\$Lisp
> >
> >    (11)  ()
> >                                                            Type:
> > SExpression
> > (12) -> EQ(c1.1,d)\$Lisp
> >
> >    (12)  ()
> >
> > Type: SExpression
> > -- So EQ\$Lisp returns () in both cases, even for -- EQ(c.1,c1.1)\$Lisp
> >
> > -- (19)  ()
> >                                                            --Type:
> > SExpression
> >
> > (13) -> e:=(c.1=d)
> >
> >    (13)  false
> >                                                                Type:
> > Boolean
> >
> > (14) -> e:=(c1.1=d)
> >
> >    (14)  false
> >                                                               Type:
> > Boolean
> > -- same problem with = using SExpression.
> > 15) -> e:=(c1.1=c1.1)
> >
> >    (15)  true
> >                                                                Type:
> > Boolean
> > (16) -> d
> >
> >    (16)  Fraction
> >                                                            Type:
> > SExpression
> > (17) -> c1.1
> >
> >    (17)  Fraction
> >                                                            Type:
> > SExpression
> >
> > So it seems there is some distinction: d (defined explicitly as
> > Fraction::SExpression) is different from c1.1 defined using
> > devaluate/destruct from a domain. A user should not need to know the
> > various way "equal" is tested if the two arguments for "equal" come
> > from the same domain SExpression. So is this a bug?
> >
> > William
> >
> > On Tue, 10 Nov 2009 12:00:58 -0500
> >  "William Sit" <address@hidden> wrote:
> >> Tim:
> >>
> >> The problem is solved (I was simply not being careful) and made some
> >> false claims on the results.
> >>
> >> (16) -> )clear all
> >>    All user variables and function definitions have been cleared.
> >> (1) -> a:=FiniteField(5,2)
> >>
> >>    (1)  FiniteField(5,2)
> >>
> >>      Type: Domain
> >> (2) -> b:=devaluate(a)\$Lisp
> >>
> >>    (2)  (FiniteField 5 2)
> >>
> >>  Type: SExpression
> >> (3) -> c:=destruct(b)
> >>
> >>    (3)  [FiniteField,5,2]
> >>                                                        Type: List
> >> SExpression
> >> (4) -> c.1
> >>
> >>    (4)  FiniteField
> >>
> >>  Type: SExpression
> >> (5) -> d:="Fraction"::SExpression
> >>
> >>    (5)  Fraction
> >>
> >>  Type: SExpression
> >> (6) -> e:Boolean
> >>
> >>        Type: Void
> >> (7) -> e:=EQ(c.1,d)\$Lisp
> >>
> >>    (7) ()
> >>                                                     Type: SExpression
> >> (7) -> e:=(c.1=Fraction) -- message above
> >>
> >>    Although Fraction is the name of a constructor, a full type must be
> >>       specified in the context you have used it. Issue )show Fraction
> >> (7) -> e:= (c.1=d\$Lisp)
> >>
> >>    >> System error:
> >>    The variable |d| is unbound.
> >>
> >> protected-symbol-warn called with (NIL)
> >> (7) -> a1:=Fraction Integer
> >>
> >>    (7)  Fraction Integer
> >>
> >>      Type: Domain
> >> (8) -> b1:=devaluate(a1)\$Lisp
> >>
> >>    (8)  (Fraction (Integer))
> >>
> >>  Type: SExpression
> >> (9) -> c1:=destruct(b1)
> >>
> >>    (9)  [Fraction,(Integer)]
> >>                                                        Type: List
> >> SExpression
> >> (10) -> e:=(c.1=c1.1)
> >>
> >>    (10)  false
> >>
> >>     Type: Boolean
> >>
> >> William
> >> ----
> >>
> >> On Tue, 10 Nov 2009 11:38:25 -0500
> >>  "William Sit" <address@hidden> wrote:
> >>> Thanks, Tim. That is exactly what I am looking for. Now I would like
> >>> to compare c.1 with some known constructor, say Fraction. (In other
> >>> words, given a domain of category Field, I would like to know if it
> >>> comes from the constructor Fraction). I tried a few variations and
> >>> each time, Axiom says:
> >>>
> >>> Although Fraction is the name of a constructor, a full type must be
> >>> specified in the context you have used it. Issue )show Fraction for
> >>>
> >>> Things I tried:
> >>>
> >>> a:=FiniteField(5,2)
> >>> b:=devaluate(a)\$Lisp
> >>> c:=destruct(b)
> >>> c.1
> >>> d:="Fraction"::SExpression
> >>> e:Boolean
> >>> e:=EQ(c.1,d)  -- message above
> >>> e:=(c.1=Fraction)  -- message above
> >>> e:= (c.1=d\$Lisp) -- message above
> >>> a1:=Fraction Integer
> >>> b1:=devaluate(a1)\$Lisp
> >>> c1:=destruct(b1)
> >>> e:=(c.1=c1.1) -- message above
> >>>
> >>> I confess that I'm still using a very old Window version (Version of
> >>> Tuesday November 30, 2004 at 21:11:14) but I don't think that makes
> >>> a difference in these examples.
> >>>
> >>> William
> >>>
> >>> On Mon, 09 Nov 2009 21:24:48 -0500
> >>> Tim Daly <address@hidden> wrote:
> >>>> I'm not sure what you want. Perhaps you'd like to say:
> >>>>
> >>>> a:=Fraction(Polynomial(Integer))
> >>>> b:=devaluate(a)\$Lisp
> >>>>
> >>>> which returns the list (actually of type SExpression)
> >>>>
> >>>> (Fraction (Polynomial (Integer)))
> >>>>
> >>>> c:=destruct(b)
> >>>> c.2
> >>>>
> >>>> which returns (Polynomial (Integer))
> >>>>
> >>>> Does that help?
> >>>>
> >>>> Tim
> >>>>
> >>>>
> >>>> William Sit wrote:
> >>>>> Tim:
> >>>>>
> >>>>> Interesting. Is there a similar function that is more structural?
> >>>>> say, can I test whether some domain (which may be passed as a
> >>>>> parameter of type Field) is of the form Fraction(something) and if
> >>>>> so, extract "something" (that is, assign it to a variable and
> >>>>> further test it), sort of a deconstruction?
> >>>>>
> >>>>> William
> >>>>>
> >>>>> On Mon, 09 Nov 2009 19:51:45 -0500
> >>>>> Tim Daly <address@hidden> wrote:
> >>>>>> You can get a memory pointer to a lisp object.
> >>>>>>
> >>>>>> a:=Fraction(Integer)
> >>>>>>
> >>>>>> returns the "memory location of Fraction(Integer)"
> >>>>>> You can prove this with
> >>>>>>
> >>>>>> b:=Fraction(Integer)
> >>>>>> EQ(a,b)\$Lisp
> >>>>>>
> >>>>>> The lisp function EQ compares memory pointers.
> >>>>>>
> >>>>>> There is a lisp function to get the hash value of any object
> >>>>>> call sxhash. You can call it.
> >>>>>>
> >>>>>> SXHASH(a)\$Lisp
> >>>>>>
> >>>>>> Note that if
> >>>>>>
> >>>>>> c:=Integer
> >>>>>>
> >>>>>> then
> >>>>>> EQ(a,c)\$Lisp is false
> >>>>>> SXHASH(a)\$Lisp is not equal to SXHASH(c)\$Lisp
> >>>>>>
> >>>>>> Thus the hash function you seek already exists.
> >>>>>> You just have to accept the fact that Spad is only syntactic
> >>>>>> sugar for lisp code and lisp is not evil.
> >>>>>>
> >>>>>> Tim
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> _______________________________________________
> >>>>>> Axiom-developer mailing list
> >>>>>> http://lists.nongnu.org/mailman/listinfo/axiom-developer
> >>>>>
> >>>>> William Sit, Professor Emeritus
> >>>>> Mathematics, City College of New York               Office:
> >>>>> R6/202C Tel: 212-650-5179
> >>>>>
> >>>>
> >>>
> >>> William Sit, Professor Emeritus
> >>> Mathematics, City College of New York                Office: R6/202C
> >>> Tel: 212-650-5179
> >>
> >> William Sit, Professor Emeritus
> >> Mathematics, City College of New York                 Office: R6/202C
> >> Tel: 212-650-5179
> >
> > William Sit, Professor Emeritus
> > Mathematics, City College of New York                  Office: R6/202C
> > Tel: 212-650-5179
> >

--
William Sit