Serge D. Mechveliani wrote:
>
> Dear Axiom/FriCAS developers,
>
> The archive http://botik.ru/pub/local/Mechveliani/axiQuest/DParse.zip
>
<snip>
> This parser, -- the function dParseL, --
> (1) is for the String Interface of Foo --> Axiom --> Foo
> (2) aims to become much faster than the current parse * interpret
> by FriCAS.
<snip>
> Concerning (2)
> --------------
> a) The performance must be achieved by providing a special syntax in
> which a data is described closely to the internal Axiom form, so that
> most of an usual parsing is not needed.
> * This syntax is not for human reading, and it is not for manual input.
> * On the other hand, the syntax should be safe: not to be based on the
> Axiom implementation features that are likely to change.
> * Also the parser needs not to do any expensive check for errors:
> the input is supposed to be correct.
>
> b) If the parser is fast, it can be used in Axiom independently from Foo
> (so far, I do not know of a possible example!).
>
> As the Axiom part does not know the target domain before analysing
> the input string, I was forced to set `Type' and `Any' in the argument
> and result of the parser function respectively:
>
> LexList ==> List String
> MaybeType ==> Union(Type, "failed")
> ParseRes ==> Record(dDom : Type, val : Any, remLexs : LexList)
>
> dParseL (mbDom : MaybeType, lexemes LexList) : ParseRes
>
> (before this, String is broken to lexemes by lexLots).
> `Any' is used as an exception, because the aim is very particular:
> I need from Axiom only a single function dParseL,
> (this is expected to support the interface usage of several selected
> functions from the Axiom mathematical library).
>
> `Any' is used because val : T, for T = mbDom :: Type,
> and T is not known initially.
>
> Method
> ------
> It is as in
> Example. x^3 + (3/4)*x^2 + 2/5 :: UP(x, Fraction Integer)
> is input as
> "(UP x (Fr (I 1) (I 1))
> [(Fr (I 1) (I 1)) (Fr (I 3) (I 4)) (Fr (I 2) (I 5))]
> [3 2 0]
> )"
>
> -- ( UP <sampleCoefficient> <coefficients> <exponents> ).
> dParse sees the tag lexeme "UP", then -- "x", and puts for the final
> result: d : UP(x, D), where
> D : CommutativeRing needs to be defined further
> (dParseL is ready to deal with D[x] only for D : CommutativeRing).
>
> Furher, it sees in the sample coefficient the tag "Fr" and puts
> D := Fraction D2, where D2 : IntegralDomain
> needs to be defined further.
> It sees in the sample coefficient "(" "I" "1" ")" for the numerator.
> And it puts D2 := Integer, by the "I" tag.
> After this, the full target concrete domain is defined:
> UPol(x, Fraction Integer).
> The further denominator is parsed by dParseL(D2 := Integer, ...),
> because D2 is already found. Similarly, each coefficient is parsed by
> dParseL(D := Fraction Integer, ...).
>
> Why domain is in the result
> ---------------------------
> To build a fraction coefficient from the found numerator n and
> denominator d, the target D := Fraction D2 needs to be set in the
> Spad program for dParseL: `(n/d) :: Fraction D2'
> -- or something similar.
> A similar construction is expected for other type constructors.
> I understand this as a nature of the Spad language.
> At least, I do not know how to avoid this explicit coercion, or a package
> calling. And for this coercion, the domain must be found recursively,
> hence it must be in the result: the domains are computed dynamically.
>
> Further, each exponent is parsed by repeated applying of
> parseInteger = READ_-FROM_-STRING(str) $ Lisp,
> because its domain is defined from the "UP" tag.
>
> Currently, only the constructors Integer, Fraction, UP
>
> are possible in a composition defining a target domain.
> If the parser proves all right, then more constructors will need to
> join.
>
> `Any', `retract', `pretend'
> ---------------------------
> To build a fraction, a polynomial, etc., dParseL needs to use
> operations from a more special categories than Type.
> This contradicts to the signature of dParse.
> So, it applies coerce/retract between Any and some currently found
> domain D, and applies pretend SuchAndSuchCategory to D
> (see the source).
> I
> a) have seen in the book the words about dynamic types,
> b) observed `Any', `retract' and `pretend' in some materials,
> c) noticed that the compiler is often calm, when the program
> _operates with types as with data_
> (the feature new for me, and totally impossible in Haskell).
> So, I wrote this, with an intuitive hope, still being almost sure that
> this building will be ruined. Because such extremal features usually
> need to obey some subtle restrictions, of which retrictions I am not
> currently aware.
> For 3-4 days I could not make it working. But then it has occured that
> this particular fail was not due to the domain extremism, but it was
> due to a) misused Spad syntax, beginner errors,
> b) may be, some compiler bug, c) enigmatic compiler messages.
> Now it seems to work.
>
> Before this, I have been healthy and was running skies up to hills.
> And with dParse, I have been cussing like a good Russian navy boatswain,
> got ill of radiculitis of sitting with tension. Now starting to recover,
> yesterday tried skiing.
> Programming in an unknown and rich language is harmful.
>
> Waldek wrote that this my usage of domains will lead to troubles,
> because T : Type contradicts to the used functionality of more
> special domains.
>
> Question: as the examples in testParse.spad work,
> where are the troubles?
>
> (apart from the boatswain ones). Is this program safe?
I wrote "troubles" not "unsolvable problems". AFAICS you
found correct solution.
> Several beginner questions on details are marked in the source by the
> key word "debug".
>
You asked "How to continue the string to the next line without
inserting blanks and with keeping indentation". If you want
literal string, then there is no way. But you can get
similar effect:
coefPref : String :=
"[(Fr (I 1) (I 1)) (Fr (I 4) (I 3)) (Fr (I 1) (I 1)) "
" (Fr (I 3) (I 4)) (Fr (I 2) (I 5)) (Fr (I 1) (I "
The cost is that now you have two strings which get concatenated at
runtime.
You get error in test1Fr. The problem is that interpreter saw
(3/4), first tried to make UPolFr from 3 and 4 (which works fine),
then tried to divide 3 by 4 searching for '/' (division) in UPolFr.
But UPolFr contains no '/', so interpreter took is from
Fraction(UPolFr), and the final result was a Fraction(UPolFr)
causing error.
The soultion is to add more coercions to Fraction Integer, like:
pref := "x^5 + ((4/3) :: Fraction Integer)*x^4 + x^3 + ((3/4)::Fraction
Integer)*x^2 + ((2/5)::Fraction Integer)*x + (1/" :: String
and
str := concat[pref, iStr, ") :: UP(x, Fraction Integer)"]
With the two line changed to forms above test1Fr worked fine.
It seems that you would like to know FriCAS type for monomials.
However, real type of monomials is internal to the polynomial
domains. In the FriCAS library normally monomial is just
polynomial with one term. Few performance critical routines
copy type definition from polynomial domain and use 'preted'
to convert from representation type to polynomial. If you
want to see an example of this look in 'polycat.spad.pamphlet'
at 'UnivariatePolynomialCategoryFunctions2'.
You ask: "What is the fastest in Spad way to make f : UP(x, R) from
its _term (monomial) list_ free of zero coefficients and ordered
decreasingly by the exponent part?". If you have list of pairs
(exponent, coefficient) then using 'pretend' to
SparseUnivariatePolynomial and then coerce to
UnivariatePolynomial is fastest (but depends on internal details).
The second fastest way is to reverse the list and add
monomials one by one in _increasing_ order of exponents.
You wrote:
D := triple.dDom pretend IntegralDomain -- ? debug
This is corrent way to resolve difficulty that I mentioned
writing about "troubles".
You want to avoid gcd when creating fractions -- it is not
possible in type-safe way. If you really want you can do:
fr := CONS(n, d)$Lisp pretend FDom
You wrote: "char "%" does not work!". '%' is normal character
in strings and 'char "%"' works fine. However, FriCAS output
routines treat '%' in special way and get confused when
printing result of 'char "%"' which results in error.
One extra remark: AFAICS your 'zipWith' from DList3 is the same
as 'map' from ListFunctions3.
--
Waldek Hebisch
[email protected]
--
You received this message because you are subscribed to the Google Groups
"FriCAS - computer algebra system" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/fricas-devel?hl=en.