Some time I wrote about scope markers.  Now I have trial
implementation (attached patch).

With the patch one can do:

P1 := SUP(INT)
P2 := SUP(P1)
p1 := monomial(monomial(1, 1)$P1, 0)$P2
p2 := monomial(1$P1, 1)$P2
rl := [message(a)$OutputForm for a in ["p", "q", "r", "s", "t"]]
set_replacements(rl)$OutputFormTools

Then:

(7) -> p1

   (7)  q
        Type: SparseUnivariatePolynomial(SparseUnivariatePolynomial(Integer))
(8) -> p2

   (8)  p
        Type: SparseUnivariatePolynomial(SparseUnivariatePolynomial(Integer))

That is "?" gets replaced by names from 'rl' depending on nesting
level.

The patch only handles SUP.  There is regression: 'precodition'
replaces scope markers as needed, but when outputting type we
do not call 'precodition', so scope markers appear in output of
types.   I am working on this, will write a separate message.



-- 
                              Waldek Hebisch

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/20230417005240.m3faaoixh36pn7zb%40fricas.math.uni.wroc.pl.
diff --git a/src/algebra/outform.spad b/src/algebra/outform.spad
index a0f9823..9526cfd 100644
--- a/src/algebra/outform.spad
+++ b/src/algebra/outform.spad
@@ -256,6 +256,8 @@ OutputForm() : Join(SetCategory, ConvertibleTo InputForm) with
           ++ infix(op, a, b) creates a form which prints as: a op b.
         postfix : (%, %)    -> %
           ++ postfix(op, a)  creates a form which prints as: a op.
+        scope : (%, %)    -> %
+          ++ scope(v, a) delimits scope of v to a.
         infix? : % -> Boolean
           ++ infix?(op) returns true if op is an infix operator,
           ++ and false otherwise.
@@ -550,6 +552,8 @@ OutputForm() : Join(SetCategory, ConvertibleTo InputForm) with
         vconcat(a, b)  == convert [eform 'VCONCAT, a, b]
         vconcat l     == cons_form(eform 'VCONCAT, l)
 
+        scope(v, a) == cons_form(eform('SCOPE), [v, a])
+
         (a ~= b) : % == convert [eform '_~_=,    a, b]
         a < b       == convert [eform '_<,     a, b]
         a > b       == convert [eform '_>,     a, b]
diff --git a/src/algebra/outform2.spad b/src/algebra/outform2.spad
index c50d056..a170c34 100644
--- a/src/algebra/outform2.spad
+++ b/src/algebra/outform2.spad
@@ -48,6 +48,9 @@ OutputFormTools : with
       ++ and arguments la
     precondition : OutputForm -> OutputForm
       ++ precondition(f) prepares form for formatting.
+    set_replacements : List(OutputForm) -> Void
+      ++ set_replacements(rl) sets rl as replacement list for
+      ++ scoped "?" variables.
   == add
 
     atom?(x) == ATOM(x)$Lisp
@@ -119,7 +122,9 @@ OutputFormTools : with
 
     import from OutputForm
 
-    precondition(x) ==
+    precondition0(x : OutputForm, rv : OutputForm, rl : List(OutputForm)
+                 ) : OutputForm ==
+        x = message("?") => rv
         string?(x) => x
         integer?(x) =>
             xi := integer(x)
@@ -128,11 +133,20 @@ OutputFormTools : with
         atom?(x) => x
         op := operator(x)
         args := arguments(x)
+        is_symbol?(op, 'SCOPE) =>
+            args(1) ~= message("?") =>
+                error "precondition: unexpected scoped variable"
+            if not(empty?(rl)) then
+                rv := first(rl)
+                rl := rest(rl)
+            else
+                rv := message("?")
+            precondition0(args(2), rv, rl) 
         if is_symbol?(op, '+) then
             args := flaten_op('+, args)
         if is_symbol?(op, '*) then
             args := flaten_op('*, args)
-        args := [precondition(arg) for arg in args]
+        args := [precondition0(arg, rv, rl) for arg in args]
         is_symbol?(op, 'construct) => bracket(args)
         n := #args
         is_symbol?(op, 'SEGMENT) and n > 0 and n <= 2 =>
@@ -172,7 +186,7 @@ OutputFormTools : with
                 nargs :=
                     integer?(a11) and integer(a11) = 1 => rest(args)
                     cons(a11, rest(args))
-                precondition(construct(op1, [construct(op, nargs)]))
+                precondition0(construct(op1, [construct(op, nargs)]), rv, rl)
             construct(op, flaten_op('*, args))
         is_symbol?(op, '/) =>
             n ~= 2 => error "precodition: division must have two arguments"
@@ -192,4 +206,12 @@ OutputFormTools : with
                 a11 := first(args1)
                 construct(op1, [construct(op, [a11, a2])])
             construct(op, args)
-        construct(precondition(op), args)
+        construct(precondition0(op, rv, rl), args)
+
+    rl0 : List(OutputForm) := []
+
+    set_replacements(rl) ==
+        rl0 := rl
+
+
+    precondition(x) == precondition0(x, message("?"), rl0)
diff --git a/src/algebra/poly.spad b/src/algebra/poly.spad
index 286da0c..b1409f3 100644
--- a/src/algebra/poly.spad
+++ b/src/algebra/poly.spad
@@ -827,7 +827,10 @@ SparseUnivariatePolynomial(R : Join(SemiRng, AbelianMonoid)
      empty?(l) => (0$Integer)::OutputForm -- else FreeModule 0 problems
      reduce(_+, l)
 
-   coerce(p:%):OutputForm == outputForm(p, message("?"))
+   coerce(p:%):OutputForm ==
+       v := message("?")
+       scope(v, outputForm(p, v))
+
    elt(p : %, val : R) ==
       empty?(p) => 0$R
       co := p.first.c

Reply via email to