1 /******************************************************************************/
5 /* Copyright (C) 2000 : Eckhard Hennig, Ralf Sommer */
6 /* This library is free software; you can redistribute it and/or modify it */
7 /* under the terms of the GNU Library General Public License as published */
8 /* by the Free Software Foundation; either version 2 of the License, or (at */
9 /* your option) any later version. */
11 /* This library is distributed in the hope that it will be useful, but */
12 /* WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
14 /* Library General Public License for more details. */
16 /* You should have received a copy of the GNU Library General Public */
17 /* License along with this library; if not, write to the Free Software */
18 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
19 /******************************************************************************/
20 /* Author(s) : Eckhard Hennig, Ralf Sommer */
21 /* Project start: 17.01.1995 */
22 /* Completed : 17.01.1995 */
23 /* last change : 17.08.1995 */
25 /******************************************************************************/
26 /* Changes : ||||| | */
27 /******************************************************************************/
29 put( 'SLVRTBOX, 1, 'Version )$
31 /* Version information: see below function definition of SetVersion */
33 /******************************************************************************/
34 /* last change: 17.08.1995 */
36 /* By : Eckhard Hennig */
37 /* Description: Function Position now accepts non list arguments */
38 /******************************************************************************/
39 /* last change: 28.06.1995 */
41 /* By : Eckhard Hennig */
42 /* Description: Function SortSolveOrder added. */
43 /******************************************************************************/
44 /* last change: 28.05.1995 */
46 /* By : Eckhard Hennig */
47 /* Description: Default function for Solver_Break_Test added. */
48 /******************************************************************************/
49 /* last change: 13.02.1995 */
51 /* By : Eckhard Hennig */
52 /* Description: Initial value of MsgLvl set to 0. */
53 /******************************************************************************/
54 /* last change: 31.01.1995 */
56 /* By : Eckhard Hennig */
57 /* Description: Problem with Solver_Verbose:false fixed. */
58 /******************************************************************************/
59 /* last change: 24.01.1995 */
61 /* By : Eckhard Hennig */
62 /* Description: Version property added. */
63 /******************************************************************************/
64 /* last change: 17.01.1995 */
66 /* By : Eckhard Hennig, Ralf Sommer */
67 /* Description: Most functions moved from AI's TOOLBOX.MAC into SLVRTBOX.MAC */
68 /* Variable Solver_Verbose added (linked to MsgLevel via */
69 /* value_check property) */
70 /******************************************************************************/
72 /******************************************************************************/
73 /* SetProp does the same as Put but the order of arguments is different. This */
74 /* is useful because sometimes the Property is a rather lengthy segment of */
75 /* code which would otherwise have to be scrolled through to inspect the */
77 /******************************************************************************/
79 SetProp( Atom, Indicator, Property ) := put( Atom, Property, Indicator )$
82 /******************************************************************************/
83 /* SetVersion stores some information about the loaded Analog Insydes package */
84 /* for online version inspection. */
85 /******************************************************************************/
87 SetVersion( [ InfoList ] ) := (
101 assoc( x, rest( InfoList ), "???" )
104 [ 'MODULE, 'DESCRIPTION, 'AUTHORS, 'DATE, 'LASTCHANGE, 'TIME, 'PLAN ]
111 /* KEY = */ 'SLVRTBOX,
112 'MODULE = "SLVRTBOX",
113 'DESCRIPTION = "Collection of utility functions for SOLVER",
114 'AUTHORS = "Eckhard Hennig, Ralf Sommer",
115 'DATE = "17.01.1995",
116 'LASTCHANGE = "17.08.1995",
122 /******************************************************************************/
123 /* Global variables */
124 /******************************************************************************/
126 define_variable( MsgLvl, 0, fixnum )$
128 /******************************************************************************/
129 /* MsgLevel controls the amount of output AI generates. If MsgLevel is */
130 /* 'OFF there will be no screen output at all. 'SHORT restricts the output to */
131 /* some important messages only whereas 'DETAIL allows extended information */
132 /* to be printed. The priority corresponding with a message must be supplied */
133 /* by the PrintMsg command: */
134 /* PrintMsg( <'OFF | 'FALSE |'SHORT | 'DETAIL | 'ALWAYS>, <stuff> ). */
135 /******************************************************************************/
137 define_variable( MsgLevel, 'FALSE, any_check )$
143 if member( x, [ 'OFF, 'FALSE, 'SHORT, 'DETAIL ] )
144 or ( debugmode and ( x = 'DEBUG ) )
146 MsgLvl : mode_identity(
151 'OFF = 0, 'FALSE = 0, false = 0,
152 'SHORT = 1, 'DETAIL = 2, 'DEBUG = 10
157 ErrorHandler( "InvMsgLvl", x, 'Fatal )
163 define_variable( Solver_Verbose, false, any_check )$
173 [ FALSE, MsgLevel : 'FALSE ],
174 [ TRUE, MsgLevel : 'SHORT ],
175 [ ALL, MsgLevel : 'DETAIL ],
176 [ OTHERWISE, ErrorHandler( "InvVerbMode", VerboseMode, 'Fatal ) ]
179 if VerboseMode=false then MsgLevel : 'FALSE
180 else if VerboseMode=true then MsgLevel : 'SHORT
181 else if VerboseMode='all then MsgLevel : 'DETAIL
182 else ErrorHandler( "InvVerbMode", VerboseMode, 'Fatal)
188 /******************************************************************************/
189 /* GetUserProperties retrieves the list of user properties associated with */
191 /******************************************************************************/
193 GetUserProperties( Symbol ) := (
206 /* get all properties of Symbol and extract the sublist which begins */
207 /* with the keyword "User Properties". */
210 apply( 'properties, [ Symbol ] ),
212 listp(x) and ( length(x) > 1 ) and ( first(x) = "User Properties" )
216 /* If the list of user properties is nonempty then return the list with */
217 /* the "User Properties" keyword removed. Otherwise, return an empty list.*/
219 if not empty( UserProps ) then
220 return( rest( first( UserProps ) ) )
227 /******************************************************************************/
228 /* GetVersion prints out the information stored by SetVersion. */
229 /******************************************************************************/
231 GetVersion() := block(
233 [ Package, VersionInfo, Fancy_Display : false ],
240 print( "Analog Insydes version information:" ),
242 for Package in GetUserProperties( 'AI ) do (
244 VersionInfo : get( 'AI, Package ),
246 print( "Module name :", VersionInfo[1] ),
247 print( "Description :", VersionInfo[2] ),
248 print( "Author(s) :", VersionInfo[3] ),
249 print( "Implemented :", VersionInfo[4] ),
250 print( "Last change :", VersionInfo[5] ),
251 print( "Time :", VersionInfo[6] ),
252 print( "Plan :", VersionInfo[7] )
258 /******************************************************************************/
259 /* The ErrorHandler prints out the error message belonging to ErrorCode and */
260 /* displays Arg as the error cause. Then the function variable Action is */
261 /* applied to Arg so corrective actions can be taken if necessary. If no */
262 /* action is required then use 'Ignore or 'Fatal as Action. */
263 /******************************************************************************/
265 ErrorHandler( ErrorCode, Arg, Action ) := (
268 [ ErrorCode, Arg, Action ], any
271 print( "Error:", ErrMsg[ErrorCode] ),
274 print( "Cause:", Arg ),
276 apply( Action, [ Arg ] )
280 /******************************************************************************/
281 /* Error handler: ignore error and continue program execution. */
282 /******************************************************************************/
284 Ignore( Arg ) := print( ErrMsg["Ignore"] )$
287 /******************************************************************************/
288 /* Error handler: abort program execution and return to Macsyma toplevel. */
289 /******************************************************************************/
291 Fatal( Arg ) := error( ErrMsg["FatalErr"] )$
294 /******************************************************************************/
295 /* AssocP tests whether Object is an association list. */
296 /******************************************************************************/
299 listp( Object ) and not member( 'false, map( 'EquationP, Object ) )$
302 /******************************************************************************/
303 /* SumP tests whether Exp is a sum. */
304 /******************************************************************************/
307 if part( Exp, 0 ) = "+" then
313 /******************************************************************************/
314 /* FunctionP tests whether Object is a function. */
315 /******************************************************************************/
317 FunctionP( Object ) := (
331 ObjectProps : apply( 'properties, [ Object ] ),
334 member( 'transfun, ObjectProps ) or member( 'function, ObjectProps )
340 /******************************************************************************/
341 /* Empty tests whether a list is empty. */
342 /******************************************************************************/
351 /******************************************************************************/
352 /* RowSize determines the row dimension of a matrix. */
353 /******************************************************************************/
359 function( length ), fixnum
366 /******************************************************************************/
367 /* ColSize determines the column dimension of a matrix. */
368 /******************************************************************************/
374 function( length), fixnum
377 length( first( Mat ) )
381 /******************************************************************************/
382 /* AppendRows appends an additional row to a matrix. */
383 /******************************************************************************/
385 AppendRows( Mat, r ) := (
389 [ r, function( ColSize ) ], fixnum
392 addrow( Mat, zeromatrix( r, ColSize( Mat ) ) )
396 /******************************************************************************/
397 /* AppendCols appends an additional column to a matrix. */
398 /******************************************************************************/
400 AppendCols( Mat, c ) := (
404 [ c, function( RowSize ) ], fixnum
407 addcol( Mat, zeromatrix( RowSize( Mat ), c ) )
411 /******************************************************************************/
412 /* PrintMsg prints a message on the screen if MsgLevel is set appropriately. */
413 /******************************************************************************/
415 PrintMsg( Level, [ Messages ]) := (
427 [ MsgPriority, function( assoc ) ], fixnum
433 [ 'ALWAYS = 0, 'SHORT = 1, 'DETAIL = 2, 'DEBUG = 10 ]
436 if MsgPriority <= MsgLvl then
437 apply( 'print, Messages )
443 /******************************************************************************/
444 /* Flatten flattens out hierarchical lists. */
445 /******************************************************************************/
458 if listp( Sublst ) then
469 /******************************************************************************/
470 /* ListMatrix transforms a matrix into a list of lists. */
471 /******************************************************************************/
474 if matrixp( Mat ) then
475 substpart( "[", copymatrix(Mat), 0 )
480 /******************************************************************************/
481 /* Position determines the position of Element within the list Lst. */
482 /* If Element does not exist, Position returns 0. */
483 /******************************************************************************/
485 Position( Element, Lst ) := (
488 [ Element, Lst ], any
500 if not listp( Lst ) then
504 for i thru length( Lst ) unless Found do
505 if Element = Lst[i] then (
518 /******************************************************************************/
519 /* SolverJustDoIt is the default Solver_Break_Test function. It simply returns*/
520 /* false, hence the Solver never stops. */
521 /******************************************************************************/
523 SolverJustDoIt( Eq, Var, Val ) := false$
526 /******************************************************************************/
527 /* SortSolveOrder sorts the list of valuations by least valuation. */
528 /******************************************************************************/
530 SortSolveOrder( SlvOrd ) :=
533 lambda( [a, b], third( a ) < third( b ) )