Currently coercion of types to OutputForm is fake: it uses
an interpreter function to produce a string and this string
serves as OutputForm.  This is problematic because:
- resulting OutputForm has no structure
- interpreter has limited understanding of types and may
  produce wrong results or crash on some types.

Attached is my attempt to do proper coercion.  'nformat.boot'
contains main new function, that is 'constructor_to_OutputForm'
and patch to 'i-output.boot' uses this function.

The patch couses significant change to how types are output.
For example instead of:

Record(svz: Symbol,sm: U32Vector,sp: Integer)

we get

Record(svz:Symbol,sm:U32Vector,sp:Integer)

that is there are no spaces after ":" (that is default behaviour
of our formatters).  Insteread of:

ModularAlgebraicGcd(PrimitiveArray(U32Vector),Record(svz: Symbol,sm: U32Vecto
r,sp: Integer),ModularAlgebraicGcdTools2)

(that is single string which is broken between lines by output
formatter) we get:

   ModularAlgebraicGcd
      PrimitiveArray(U32Vector)
  ,
      Record(svz:Symbol,sm:U32Vector,sp:Integer)
  ,
      ModularAlgebraicGcdTools2

which is default handling of compound forms that are too big to fit on
a single line.

Instead of

IndexedMatrix(Polynomial(Integer),7,-3)

we get

IndexedMatrix(Polynomial(Integer),7,- 3)

that is minus sign is separated from the number.

Instead of

DeRhamComplex(Integer,[x,y,z])

we get

DeRhamComplex(Integer,[x, y, z])

Currently the code for handling categories is fake (throws error).
It seems that currently there is no way to have cateries coerced
to OutputForm, so corresponging code is not needed and
untestable.

-- 
                              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/ZS8hR/OjTCe569Cq%40fricas.org.
)package "BOOT"

any_to_string(u) == WRITE_-TO_-STRING(u)

arg_to_OutputForm(arg, t, c) ==
    c => constructor_to_OutputForm(arg)
    isValidType(t) and PAIRP(t) and
            (GETDATABASE(first(t),'CONSTRUCTORKIND) = 'domain) =>
        (val := coerceInteractive(objNewWrap(arg, t), $OutputForm)) =>
            objValUnwrap(val)
        -- Wrong, but we try to produce something
        any_to_string(arg)
    -- Wrong, but we try to produce something
    any_to_string(arg)

prefix_to_string(con) ==
    u := prefix2String(con)
    atom(u) => u
    concatenateStringList([object2String(x) for x in u])

-- fake, to catch possible use
mkCategory_to_OutputForm(argl) ==
    throwMessage('"mkCategory_to_OutputForm called")

-- fake, to catch possible use
Join_to_OutputForm(argl) ==
    throwMessage('"Join_to_OutputForm called")

Record_to_OutputForm(argl) ==
    rres := []
    for [":", name, type] in argl repeat
        r1 := ['CONCAT, name, '":", constructor_to_OutputForm(type)]
        rres := cons(r1, rres)
    cons('Record, reverse(rres))

Union_to_OutputForm(argl) ==
    not(null(argl)) and (first(argl) is [":", name, type]) =>
        -- new style Union
        nargs := [['CONCAT, name, '":", constructor_to_OutputForm(type)]
                  for [":", name, type] in argl]
        ['Union, :nargs]
    -- old style
    nargs := [constructor_to_OutputForm(arg) for arg in argl]
    ['Union, :nargs]

Mapping_to_OutputForm(argl) ==
    -- should we allow this ???
    null(argl) => ['PAREN, ['CONCAT, '"()", "->", '"()"]]
    rt := constructor_to_OutputForm(first(argl))
    nargs := [constructor_to_OutputForm(arg) for arg in rest(argl)]
    if #nargs > 1 then
        nargs := ['PAREN, ['AGGLST, :nargs]]
    else if null(nargs) then
        nargs := '"()"
    else
        nargs := first(nargs)
    ['PAREN, ['CONCAT, nargs, "->", rt]]

constructor_to_OutputForm(con) ==
    if VECTORP(con) then
        con := devaluate(con)
    STRINGP(con) => CONCAT("", con, "")
    ATOM(con) =>
        -- Wrong, but we try to produce something printable
        any_to_string(con)
    op := first(con)
    argl := rest(con)

    op = 'Join => Join_to_OutputForm(argl)
    op = 'mkCategory => mkCategory_to_OutputForm(argl)
    op = 'Record => Record_to_OutputForm(argl)
    op = 'Union => Union_to_OutputForm(argl)
    op = 'Mapping => Mapping_to_OutputForm(argl)
    (abb := constructor?(op)) =>
        null(argl) => constructorName(op)
        con_sig := getConstructorSignature(op)
        cosig := GETDATABASE(op,'COSIG)
        null(con_sig) or null(cosig) =>
            -- Wrong, but we try to produce something
            prefix_to_string(con)
        con_sig := rest(con_sig)
        cosig := rest(cosig)
        if not freeOfSharpVars(con_sig) then
            con_sig := SUBLIS([[s_var, :val]
                               for s_var in $FormalMapVariableList
                               for val in argl], con_sig)
        n_argl := [arg_to_OutputForm(arg, t, c) for arg in argl
                   for t in con_sig for c in cosig]
        [constructorName(op), :n_argl]
    -- Wrong, but we try to produce something
    prefix_to_string(con)
diff --git a/src/interp/Makefile.in b/src/interp/Makefile.in
index 72d19ac..42798fd 100644
--- a/src/interp/Makefile.in
+++ b/src/interp/Makefile.in
@@ -29,7 +29,7 @@ OBJ_files= macros setq \
 	i-coerce i-coerfn i-eval i-funsel i-intern \
 	i-map i-output i-resolv	i-spec1 i-spec2 i-syscmd \
 	i-toplev incl interop int-top lisplib macex match \
-	msg msgdb nlib nrunfast \
+	msg msgdb nformat nlib nrunfast \
 	nrungo nrunopt pathname pf2sex pile \
 	posit ptrees rulesets scan \
 	serror server setvars sfsfun simpbool slam \
diff --git a/src/interp/i-output.boot b/src/interp/i-output.boot
index c0d1910..6cd9528 100644
--- a/src/interp/i-output.boot
+++ b/src/interp/i-output.boot
@@ -1316,9 +1334,9 @@ output(expr,domain) ==
   isMapExpr expr and not(domain is ["FunctionCalled", .]) => BREAK()
   categoryForm? domain or domain = ["Mode"] =>
     if $algebraFormat then
-      mathprintWithNumber outputDomainConstructor expr
+      mathprintWithNumber(constructor_to_OutputForm(expr))
     if $texFormat     then
-      texFormat outputDomainConstructor expr
+      texFormat(constructor_to_OutputForm(expr))
   T := coerceInteractive(objNewWrap(expr,domain),$OutputForm) =>
     x := objValUnwrap T
     if $fortranFormat then fortranFormat x

Reply via email to