How to specify display



> I don't really want to have everything ... stored as maxima lisp.
> It would be cumbersome for the rest of my package .... Is there
> some way to hide everything?

You can hide all you want in the cdar.  Most of Maxima doesn't touch
cdar's: it neither examines nor modifies them.  This means (among other
things) that two things are considered (syntactically) equal iff their
visible parts are equal.  This has bad consequences.  So it is better to
have the visible part fully represent the value.

As I mentioned to you in December, Maxima doesn't really support opaque
objects.  It would be nice if it did, but for now, by following the
existing conventions, new code takes best advantage of other parts of
Maxima.  The conventions are:

  1 The caar represents the object constructor or type.
  2 The cdr is a list of GRs, fully representing the object's semantics.
  3 Expressions are simplified to a quasi-canonical form, such
    that syntactic equality (ALIKE1) always implies semantic equality,
    and semantic equality often implies syntactic equality.
  4 The cdar contains additional information which does not change
    the meaning of the expression.
  5 Objects are immutable: operations on objects create new objects,
they
    don't modify existing ones.

MRAT and MPOIS violate 2 and 4; MLIST violates 5.  But best if new code
doesn't violate any of them.

More detail below.

       -s

--------------------

The simplest way to hide things is to put them in the cdar:

    ((%hypergraph simp edges (a b c) vertices ((a b 4) (b c 2))))

Maxima generally preserve things in the cdar through simplification and
other operations.  ***BUT*** the contents of the cdar are not considered
in comparing two objects.  Consider:

   :lisp (setq |$q1| '(($graph vertices (a b) edges ((a b))))
               |$q2| '(($graph vertices (a b c) edges ((a b) (b c)))))

Now

   q1+q2 => 2 GRAPH()        (!!!)

and

   set(q1,q2) => { GRAPH() }    (!!!)

That is, you can't create sets of graphs... not so good.  You could get
around this through expedients like assigning serial numbers to your
graphs:

   :lisp (setq |$q1| '(($graph vertices (a b) edges ((a b))) 128)
               |$q2| '(($graph vertices (a b c) edges ((a b) (b c)))
129))

Then

   q1+q2 => GRAPH(128) + GRAPH(129)

and

   set(q1,q2) => { GRAPH(128), GRAPH(129)}

but the user shouldn't see the serial numbers -- they are ugly.  So you
could suppress the display of the serial numbers, and instead give some
useful information:

(displa-def $graph dimension-graph)

(defun dimension-graph (form result)
  (let ((vertices (cadr (memq 'vertices (cdar form))))
	(edges (cadr (memq 'edges (cdar form)))))
    (dimension-function
     `(($graph simp)
       ((msetq simp) $vertices ,(length vertices))
       ((msetq simp) $edges ,(length edges)))
     result)))

Now

   set(q1,q2) => { GRAPH(VERTICES : 2, EDGES : 1) ,
                   GRAPH(VERTICES : 3, EDGES : 2) }

which is better.

But if we create two identical graphs independently, they will still
compare as not equal:

  set(complete_graph(5),complete_graph(5))
        => { GRAPH(VERTICES : 5, EDGES : 10), GRAPH(VERTICES : 5, EDGES
: 10) }

Now this brings up a host of other issues.  For example, do you have a
canonical form for graphs such that you can use ALIKE1 (Maxima's
standard syntactic comparison function) to compare them?  Maxima is very
fond of such canonical forms.  Forgive the anthropomorphizing: what I
mean is that Maxima works well with representations where syntactical
equality (ALIKE1) is a good approximation to semantic equality.  As a
general rule, Maxima takes advantage of syntactic properties without
asking the user (e.g. during general simplification), but the user must
explicitly ask for semantic properties.  (There are exceptions; compare
<<< assume(equal(a,b))$ a-b => a-b >>> vs <<< assume(a<0)$  abs(a) => -a
>>>.)

Another issue: what is the meaning of your vertex names?  Are they part
of the graph, or simply a convenient way to enter graphs.  For example,
do you consider the undirected graph a-b (two vertices, one edge) to be
the "same graph" as b-c (same structure, different labels)?  How about
b-a?  How do you label vertices in generated graphs (like
complete_graph(5))?

If vertex labels are *not* part of the semantics, then how do you
represent your graph so that ALIKE1 works properly?  At that point, you
should use the cdr to represent the canonical form, and the cdar to
represent the labelling, e.g.

    (($graph simp labels ($a $b))
     3
     ((mlist simp) ((mlist simp) 2 3) ))
        ;; note that this is a graph of three vertices, one of which is
not
        ;; connected to any others

> I don't know right now how I should deal with subst, ev, map, part,
...

If you use a GR-type structure, all these becomes trivial.  They just
work -- but they will only really be useful if vertex labels are part of
the value.

For example,

    g1: graph([a,b],[[a,b]]) => graph(vertices:2,edges:2)
    g2: subst('a,'a,g1) => graph(vertices:1,edges:0)
                               (or edges:1 if you allow self-edges)

Subst will return something like graph([a,a],[[a,a]]) and it is up to
your simplification function to simplify that to graph([a],[[]]).

> However, I would have to keep in sync the internal form of
> vertices and edges with these mlists...

Are you saying you have a separate internal form?  If so, yes,
synchronization is an issue if your objects are mutable.  Maxima doesn't
really have a good solution for that; it "prefers" immutable objects.

> I thought that the output of the linear display routine would
> be assigned to Dnnn, but in fact, its really better to have
>
> (c1) complete_graph(5);
>
> assign the graph to d1. Kill(d1); will remove it. This is
> more consistent with the rest of maxima.

Yes.  What is displayed after (Dnnn) is just a display of the returned
value, not the value itself.

     -s