One other issue is that mathml.spad.pamphlet has comments mixed in
with the code and '>' is represented by '$>$' and so on. It therefore
requires a lot of changes to get it to compile in the 'old' compiler.
Martin Baker
-----------------------------------
test case:
(1) -> )set output mathml on
(1) -> a[1,2]
(1) a
1,2
>> System error:
Cannot take first of an empty list
(1) -> )library CLIF
CliffordAlgebra is now explicitly exposed in frame frame1
CliffordAlgebra will be automatically loaded when needed from
/home/martin/CLIF.NRLIB/CLIF
(1) -> B1 := CliffordAlgebra(2,Fraction(Integer),[[1,0],[0,1]])
(1) CliffordAlgebra(2,Fraction(Integer),[[1,0],[0,1]])
Type: Type
(2) -> e(1)$B1
(2) e
1
>> System error:
Cannot take first of an empty list
Arthur
Arthur,
While you are doing that is it worth adding /\ and \/ to the list of binary
operations in the binaryOps, binaryPrecs lists?
At the moment I don't know a way to get these to be sent to the output, but
even if they are not output at present, perhaps they might be in the future?
Martin Baker
Currently .pamphlet need to be unpacked by noweb. You need something
like:
/path/to/notangle -R"package MMLFORM MathMLForm" mathml.spad.pamphlet > MMLFORM.spad
Resulting MMLFORM.spad should compile without any need for manual
changes. And yes, it is inconvenient, but some folks here consider
it the only right way to write programs...
--
Waldek Hebisch
heb...@math.uni.wroc.pl
> Martin Baker wrote:
>>
>> One other issue is that mathml.spad.pamphlet has comments mixed in
>> with the code and '>' is represented by '$>$' and so on. It therefore
>> requires a lot of changes to get it to compile in the 'old' compiler.
>
> Currently .pamphlet need to be unpacked by noweb. You need something
> like:
>
> /path/to/notangle -R"package MMLFORM MathMLForm" mathml.spad.pamphlet> > MMLFORM.spad
I would rather do
fri-build/build/scripts/document mathml.spad.pamphlet
where fri-build is the directory in which you you built fricas. I
always put the document script into my bin directory, and added it to my
TeX-command-list in emacs.
> And yes, it is inconvenient, but some folks here consider it the only
> right way to write programs...
I don't find it inconvenient, but I understand well that Waldek does.
On the other hand, I find it very inconvenient to look for documentation
outside of the source file, which Waldek seems to prefer (see
fricas/doc/sttaylor.txt).
Martin
I think I'm with Waldek on this, I find this way of mixing in documentation
very inconvenient, it may be useful to read the level of detail in
sttaylor.txt once but I don't think I would want to wade though that, every
time I wanted to find a piece of code once I understood the program.
I found Arthur Ralfs documentation in the mathml pamphlet extremely useful and
I could not have written my html formatter without it. But a lot of the
documentation in the pamphlet is not specific to mathml, it belongs somewhere
where any potential writer of a formatter will see it.
The temptation is to duplicate this information into all the formatters where
some copies will get updated and others won't. The end result will be more
quantity but less quality of documentation.
I find this is made worse because in SPAD the declarations and definitions are
split up. So where do the explanations of the functions go, with the
declaration or definition? Or is it duplicated? Or do I have to jump between
them, over pages of detailed documentation, to find an explanation of the
function or parameter?
My solution would be to have a web of information, like hyperdoc, but for
programmers. But this can't be done if the documentation is in pamphlet files.
It seems to me that ordinary comments are good enough to help the programmer
or maintainer work on the code which could contain links into the other types
of information below.
It seems to me that there are lots of types of documentation, like:
User Guide
----------------
When to use
How to use
What functions are available.
Programmers Guide
----------------------------
Overall architecture of the domain.
Why a given category is used.
How to build
Known problems
Mathematicians Guide
-------------------------------
Text book stuff, definitions and so on
An excerpt from a paper by an expert in the field
Examples
I've only looked at a few pamphlet files but they seem to have odd bits of all
these types. If you are going to put this all in with the code then I think
you would have to be very prescriptive about what goes where and I don't think
that is likely to work in an open source environment.
So I would have separate hyperlinked User Guide, Programmers Guide and
Mathematicians Guide. I can see some problems with this, in that people might
not feel such a sense of ownership with these documents as they might feel
with pamphlet files.
Anyway these are my first thoughts on the subject, I may grow to love pamphlet
files but it seems unlikely at the moment.
Martin Baker
> On Sunday 31 Jan 2010 16:59:14 Martin Rubey wrote:
>> Waldek Hebisch <heb...@math.uni.wroc.pl> writes:
>> > And yes, it is inconvenient, but some folks here consider it the only
>> > right way to write programs...
>>
>> I don't find it inconvenient, but I understand well that Waldek does.
>> On the other hand, I find it very inconvenient to look for documentation
>> outside of the source file, which Waldek seems to prefer (see
>> fricas/doc/sttaylor.txt).
>
> I think I'm with Waldek on this, I find this way of mixing in documentation
> very inconvenient, it may be useful to read the level of detail in
> sttaylor.txt once but I don't think I would want to wade though that, every
> time I wanted to find a piece of code once I understood the program.
The trouble is that I will not update documentation if it's not right
next to the source. As much as I admire Waldek skills, and although I
call myself mathematician (well, combinatorialist), I was unable to
understand most of modhpsol.spad so far.
I admit that the documentation in mantepse.spad is a mess, but moving
the mess into a separate directory won't help, I think.
I would really like to discuss changing the documentation policy of
FriCAS, but I cannot do so before the project I'm currently working on
is done.
Martin
I support the idea of literate programming but I don't like the present
tools. I also don't like mandatory latex although optional latex is
fine. I have some ideas I'm working on but don't hold your breath.
Arthur
Probably not. However as soon as someone can send me an example which
produces /\ and \/ in output I will do so.
Arthur
regards,
Franz
Can you give me some example commands that produce output not currently
handled by mathml?
Arthur
)set out tex on
)set out mathml on
(1) -> M:=FreeModule(Integer,Symbol);
Type: Domain
(2) -> N:=FreeModule(Integer,Symbol);
Type: Domain
(3) -> MxN ==> TensorProduct(Integer,Symbol,Symbol,M,N)
Type: Void
(4) -> a:='a::M;
Type: FreeModule(Integer,Symbol)
(5) -> b:='b::M;
Type: FreeModule(Integer,Symbol)
(6) -> tensor(a,b)$MxN
(6) a # b
$$
a \otimes b
\leqno(6)
$$
<math xmlns="http://www.w3.org/1998/Math/MathML" mathsize="big" display="block">
<mrow><mo><mi>TENSOR</mi></mo><mo>(</mo><mrow><mi>a</mi><mo>,</mo><mi>b</mi></mrow><mo>)</mo></mrow>
</math>
Type: TensorProduct(Integer,Symbol,Symbol,FreeModule(Integer,Symbol),FreeModule(Integer,Symbol))
regards,
Franz
presub(F::OutputForm,2::OutputForm)
scripts(F::OutputForm,[2::OutputForm,empty()$OutputForm,empty()$OutputForm,1::OutputForm])
--
Waldek Hebisch
heb...@math.uni.wroc.pl
> Arthur Ralfs wrote:
>>
>> Can you give me some example commands that produce output not currently
>> handled by mathml?
>>
>
>
> presub(F::OutputForm,2::OutputForm)
> scripts(F::OutputForm,[2::OutputForm,empty()$OutputForm,empty()$OutputForm,1::OutputForm])
PLEASE put all of this into test files. It will make FriCAS quite a bit
more reliable...
Martin
Arthur,
I am interested to hear what you have in mind for the rewrite. Do you plan to
modify OutputForm to have more semantic information? I can't think of any
other way to avoid problematic code like this, which tries to guess if the
output was created from partial derivatives.
Martin Baker
This should definitively be added to OutputForm. After all, partial
derivative *should* be typeset differently than a subscript.
Martin
In mathml.spad partial derivatives are typeset in the function
'formatSub1'. The function 'formatSub', which is currently not used,
formats partials using the Leibniz notation. Ideally the user should
probably be able to switch between what type of derivative notation in
desired.
For the maybe immediate future I was just thinking about cleaning up and
reorganizing the present package.
Arthur
I'm confused - I cannot reproduce the problem. It doesn't seem that sub
is called except for derivatives - am I mistaken? Hm,
grep "sub(.*,.*)" *
does find a use in pattern and in clifford... But I do not see the
problem with scripts.
(1) -> f := operator 'f;
Type: BasicOperator
(2) -> a := D(f(x,y), x)::OUTFORM;
Type: OutputForm
(3) -> b := (x[1,2])::OUTFORM;
Type: OutputForm
(4) -> )tr OUT
Parameterized constructors traced:
OUT
(4) -> output(a)
1<enter OutputPackage.output,9
: ((SUB |f| (CONCAT |,| 1)) |x| |y|)
f (x,y)
,1
1>exit OutputPackage.output,9
: "()"
Type: Void
(5) -> output(b)
1<enter OutputPackage.output,9
: (|*02x| 1 2)
x
1,2
1>exit OutputPackage.output,9
: "()"
Type: Void
Martin
precondition expr ==
outputTran$Lisp expr
I didn't delve into it deeply. It was and still is obscure to me.
(1) -> f := operator 'f;
Type:
BasicOperator
(2) -> a := D(f(x,y),x)::OUTFORM;
Type:
OutputForm
(3) -> b := (x[1,2])::OUTFORM;
Type:
OutputForm
(4) -> exprex(a)
(4) "{{{SUB}{f}{{CONCAT}{,}{1}}}{x}{y}}"
Type:
String
(5) -> exprex(b)
(5) "{{SUB}{x}{1}{2}}"
Arthur
That is 3 of us confused then.
I don't really know enough about the way that trace works to comment sensibly
but as OutputForm creates a tree structure of representations:
sub: (%, %) -> %
++ sub(f,n) creates a form for f subscripted by n.
Would the trace command properly traverse through this tree structure to find
the sub?
Martin B.
Which problem? The thread started because of error when MathML
output is active. You were not using MathML output, so you
must be thinking about different problem.
--
Waldek Hebisch
heb...@math.uni.wroc.pl
> I'm confused too. I wrote a function 'exprex' to help me see the
> 'preconditioned' OutputForm I found in tex.spad. Maybe it's the
> 'precondition' function, or rather 'outputTran$Lisp':
>
> precondition expr ==
> outputTran$Lisp expr
>
> I didn't delve into it deeply. It was and still is obscure to me.
>
> (1) -> f := operator 'f;
> (2) -> a := D(f(x,y),x)::OUTFORM;
> (3) -> b := (x[1,2])::OUTFORM;
> (4) -> exprex(a)
>
> (4) "{{{SUB}{f}{{CONCAT}{,}{1}}}{x}{y}}"
> (5) -> exprex(b)
>
> (5) "{{SUB}{x}{1}{2}}"
OK. I guess the handling of Symbols is not ideal... I guess you know,
but outputTran is defined in i-output.boot and seems to "prepare" the
OutputForm for further processing. The next-to-last clause in it,
namely
IDENTP op and not (op in '(_* _*_*) ) and char("*") = (PNAME op).0 =>
mkSuperSub(op,l)
does the processing of symbols -- note that you can trace Lisp
functions:
)tr outputTran
)tr mkSuperSub
I'm not sure what's best. In LaTeX, there are also only sub- and
superscripts, no special notation for derivatives or exponents. Well,
if you want to introduce it, you would need to:
* invent a name, say: DIFF
* introduce an appropriate operation in OUTFORM
* tell fspace.spad and perhaps elsewhere about the new display
properties. in fspace it's in ddiff:
ddiff l ==
rec := dispdiff l
opname :=
zero?(rec.level) => sub(rec.name, rec.sub)
differentiate(rec.name, rec.level)
prefix(opname, rec.arg)
* add an appropriate clause to outputTran that transforms it into SUB,
or, better, extend the language charybdis appropriately. You need to
look at property.lisp for that, I think Franz knows most about this --
he added (TENSOR APP |tensorApp|) and (TENSOR WIDTH |tensorWidth|).
Good luck,
Martin
> Mathml comes in two flavours, display and content, and originally I
> planned to do the present display mathml package and then move on to a
> content mathml package. I started working on that but soon ran into the
> problem that OutputForm doesn't have the semantic information necessary.
> It seemed like more than I wanted to get into by myself but I'd be
> interested in a project to modify OutputForm.
What I would like is a way for a user to specify preferences. I'm not saying
that all formaters would have to implement these user preferences but they
would be able to read them if they wished. I suspect that this would require
some code outside OutputForm as the preferences would need to be persistent
for the life of the interpreter session.
The sort of user preferences I would like for my html formatter would be
things like:
)set output operator precedence {op:value}
)set output vector {row | column | list}
)set output matrix { open | grid | bracket | determinant | spacing}
)set output cliff ordering {bit | grade}
)set output zag {hierarchical over | _| , min max fontsize}
)set output generate header {on | off}
)set output generate css {on | off}
)set output indent {on | off}
)set output linewrap value
)set output debug {on | off}
Is there a way for me to implement this at present?
Martin B.
> On Wednesday 10 Feb 2010 16:54:27 Arthur Ralfs wrote:
>> Martin Rubey wrote:
>> > Martin Baker <ax8...@martinb.com> writes:
>> >> On Monday 08 Feb 2010 18:36:10 Arthur Ralfs wrote:
>
>> Mathml comes in two flavours, display and content, and originally I
>> planned to do the present display mathml package and then move on to a
>> content mathml package. I started working on that but soon ran into the
>> problem that OutputForm doesn't have the semantic information necessary.
>> It seemed like more than I wanted to get into by myself but I'd be
>> interested in a project to modify OutputForm.
>
> What I would like is a way for a user to specify preferences. I'm not saying
> that all formaters would have to implement these user preferences but they
> would be able to read them if they wished. I suspect that this would require
> some code outside OutputForm as the preferences would need to be persistent
> for the life of the interpreter session.
You do not (and I think should not) modify the interpreter for such
things. Just introduce state to your constructor. To see how it's
done, look at the digits functions from float.
> The sort of user preferences I would like for my html formatter would
> be things like:
>
> )set output operator precedence {op:value}
This one I don't understand at all.
At first glance I can't see how this is done?
digits(n) == (t := digits(); bits (1 + ceillog10base2 n); t)
It seems to encode this in a variable 't' but I haven't yet noticed where it
is defined. Is it made persistent in some way?
I think part of my problem is that I am not clear about domains like Float and
OutputForm that are not explicitly created by the user, are instances created
when needed by the system, or does the same one remain active through the
session?
> > )set output operator precedence {op:value}
>
> This one I don't understand at all.
>
All the output formaters that I have seen have operator precedence hard coded
into each one in the form of a list of numbers. I would think that it would be
better if these formaters could all read the same precedence that is used by
the matching algorithm and even better if that could be set by the user.
Martin
Do you know how to put multiple scripts in one position?
Arthur
I am not sure what you want. FriCAS has four positions for scripts
and you can put any compound item, for example list in them:
(54) -> sl0 := [1, 2, 3]
(54) [1,2,3]
Type: List(PositiveInteger)
(55) -> sl := commaSeparate(sl0::List(OutputForm))
(55) 1,2,3
Type: OutputForm
(56) -> sub(p::OutputForm, sl)
(56) p
1,2,3
Type: OutputForm
(57) -> sub(p::OutputForm, sl)::SEX
(57) (SUB p (AGGLST 1 2 3))
Type: SExpression
--
Waldek Hebisch
heb...@math.uni.wroc.pl
Such variables are stored inside domain. When domain is destroyed the
variable is gone. Variables (as opposed to quantities which are
morally constant but re stored in initialized variables) stored in
domains do cause some problems for implementation (in particular
they will require re-thinking when we will want multithreading).
> I think part of my problem is that I am not clear about domains like Float and
> OutputForm that are not explicitly created by the user, are instances created
> when needed by the system, or does the same one remain active through the
> session?
>
When you write '1::OutputForm', you in particular request sytem to
create (possibly new) instance of OutputForm. Basically any code
that uses some domain is in some sense requesting creating this domain.
However, actual creation is done in lazy way (and split into several
steps), and AFAIK typicall domains are actually in a strange "almost
done" state. Domain creation is rather expensive, so once FriCAS
stared creating a domain (that is created a stub ready to fill
details in lazy way) it will normally reuse the already created
part. Some domains are marked as "mutable", FriCAS will not
re-use such domains but create new instance.
Above I wrote "normally" because cache (such caches are per
constructor) holding already created domains may overflow and
then FriCAS will remove the oldest position for the cache.
And user may explicitly clear caches using ')clear completely'.
Also Spad complation clears caches.
Because OutputForm has no parameters, it needs cache with single
slot and this cache will never overflow, so normally you will
re-use old version. But if caches are cleared, new instance
is created.
BTW: Normally persistent state is stored in Lisp variables, you
can access them from Spad (but they must be created from Boot or
Lisp). Float is not really good example, basically I think it
is better to avoid variables in domains (but Float has specific
needs so it is not clear if we can do better).
--
Waldek Hebisch
heb...@math.uni.wroc.pl
What ')set' is doing depends on interpreter variable '$setOptions'
(basically the whole content of 'setvart.boot' is to give initial
values to this varible), if you append extra entries ')set' will
handle them.
It seems that you would like to have very detailed options, so
you will probably need hundreds of them. In such case you
probably should use a single variable holding something like Table.
--
Waldek Hebisch
heb...@math.uni.wroc.pl
Thanks, $setOptions is what I need, I will do some research to find out how
best to use it.
> It seems that you would like to have very detailed options, so
> you will probably need hundreds of them. In such case you
> probably should use a single variable holding something like Table.
To some extent this depends on whether you would wish to put this html
formatter into the main code. If not I would probably have a small number of
options which I could change at runtime with the rest being hard coded for my
own requirements. If it is to be useful for others then I think it would make
it more useful if there were a lot more options, most of which would be left
at default values, but where the user could change a few with name-value
string pairs.
Martin B.
I have put html.spad.pamphlet here:
http://github.com/martinbaker/multivector/
> Some domains are marked as "mutable", FriCAS will not re-use such
> domains but create new instance.
Maybe it would be good to have a rule that FriCAS always re-uses
domains/packages which are not marked mutable?
I must say I somehow dislike the idea of having certain options in the
interpreter, but I cannot make this more precise right now.
Martin
Conceptually Spad domains are immutable, so it should make no
difference if we use cached version or not. Both not caching
at all and always caching would have bad performance impact.
Always caching risks filling memory with garbage domains and
long lookup times due to cache size.
> I must say I somehow dislike the idea of having certain options in the
> interpreter, but I cannot make this more precise right now.
>
The point is that we need variables outside domains. At some
moment we will have to extend Spad to have them. ATM we have
to use workarounds.
BTW: It seems that one can actully define variable in Spad:
DEFVAR(MyVariable$Lisp)$Lisp
at top level of a domain seem to do the right thing.
--
Waldek Hebisch
heb...@math.uni.wroc.pl