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