;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; The data in this file contains enhancments. ;;;;; ;;; ;;;;; ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;; ;;; All rights reserved ;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; (c) Copyright 1981 Massachusetts Institute of Technology ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (in-package "MAXIMA") (macsyma-module utils) ;;; General purpose Lisp utilities. This file contains runtime functions which ;;; are simple extensions to Lisp. The functions here are not very general, ;;; but generalized forms would be useful in future Lisp implementations. ;;; ;;; No knowledge of the Macsyma system is kept here. ;;; ;;; Every function in this file is known about externally. ;;; N.B. this function is different than the lisp machine ;;; and maclisp standard one. (for now). ;;; temporary until the new lispm make-list is installed (DEFMFUN *MAKE-LIST (SIZE &OPTIONAL (VAL NIL) ) (DO ((L NIL (CONS VAL L))) ((< (SETQ SIZE (f1- SIZE)) 0) L))) ;;; F is assumed to be a function of two arguments. It is mapped down L ;;; and applied to consequtive pairs of elements of the list. ;;; Useful for iterating over property lists. (DEFMFUN MAP2C (F L) (DO ((LLT L (CDDR LLT)) (LANS)) ((NULL LLT) LANS) (SETQ LANS (CONS (FUNCALL F (CAR LLT) (CADR LLT)) LANS)))) ;;; (ANDMAPC #'INTEGERP '(1 2 3)) --> T ;;; (ANDMAPC #'INTEGERP '(1 2 A)) --> NIL ;;; (ORMAPC #'INTEGERP '(1 2 A)) --> T ;;; (ORMAPC #'INTEGERP '(A B C)) --> NIL ;;; If you want the do loop generated inline rather than doing a function call, ;;; use the macros SOME and EVERY. See LMLisp manual for more information. ;;; Note that the value returned by ORMAPC is slightly different from that ;;; returned by SOME. (DEFMFUN ANDMAPC (F L) (DO ((L L (CDR L))) ((NULL L) T) (IF (NOT (FUNCALL F (CAR L))) (RETURN NIL)))) (DEFMFUN ORMAPC (F L &AUX ANSWER) (DO ((L L (CDR L))) ((NULL L) NIL) (SETQ ANSWER (FUNCALL F (CAR L))) (IF ANSWER (RETURN ANSWER)))) ;;; Like MAPCAR, except if an application of F to any of the elements of L ;;; returns NIL, then the function returns NIL immediately. (DEFMFUN ANDMAPCAR (F L &AUX D ANSWER) (DO ((L L (CDR L))) ((NULL L) (NREVERSE ANSWER)) (SETQ D (FUNCALL F (CAR L))) (IF D (PUSH D ANSWER) (RETURN NIL)))) ;;; Returns T if either A or B is NIL, but not both. (DEFMFUN XOR (A B) (OR (AND (NOT A) B) (AND (NOT B) A))) ;;; A MEMQ which works at all levels of a piece of list structure. ;;; ;;; Note that (AMONG NIL '(A B C)) is T, however. This could cause bugs. ;;; > This is false. (AMONG NIL anything) returns NIL always. -kmp (DEFMFUN AMONG (X L) (COND ((NULL L) NIL) ((ATOM L) (EQ X L)) (T (OR (AMONG X (CAR L)) (AMONG X (CDR L)))))) ;;; Similar to AMONG, but takes a list of objects to look for. If any ;;; are found in L, returns T. (DEFMFUN AMONGL (X L) (COND ((NULL L) NIL) ((ATOM L) (MEMQ L X)) (T (OR (AMONGL X (CAR L)) (AMONGL X (CDR L)))))) ;;; (RECONC '(A B C) '(D E F)) --> (C B A D E F) ;;; Like NRECONC, but not destructive. ;;; ;;; Is this really faster than macroing into (NCONC (REVERSE L1) L2)? ;;; > Yes, it is. -kmp (DEFMFUN RECONC (L1 L2) #+NIL (revappend l1 l2) #-NIL (DO () ((NULL L1) L2) (SETQ L2 (CONS (CAR L1) L2) L1 (CDR L1)))) ;;; (FIRSTN 3 '(A B C D E)) --> (A B C) ;;; ;;; *NOTE* Given a negative first arg will work fine with this definition ;;; but on LispM where the operation is primitive and defined ;;; differently, bad things will happen. Make SURE it gets a ;;; non-negative arg! -kmp #+(OR PDP10 Franz) (DEFMFUN FIRSTN (N L) (SLOOP FOR I FROM 1 TO N FOR X IN L COLLECT X)) ;;; Reverse ASSQ -- like ASSQ but tries to find an element of the alist whose ;;; cdr (not car) is EQ to the object. To be renamed to RASSQ in the near ;;; future. (DEFMFUN ASSQR (OBJECT ALIST) (DOLIST (PAIR ALIST) (IF (EQ OBJECT (CDR PAIR)) (RETURN PAIR)))) ;;; Should be open-coded at some point. (Moved here from RAT;FACTOR) (DEFMFUN LOG2 (N) (f1- (HAULONG N))) ;;; Tries to emulate Lispm/NIL FSET. Won't work for LSUBRS, FEXPRS, or ;;; FSUBRS. #+PDP10 (DEFMFUN FSET (SYMBOL DEFINITION) (COND ((SYMBOLP DEFINITION) (PUTPROP SYMBOL DEFINITION 'EXPR)) ((EQ (ml-typep DEFINITION) 'RANDOM) (PUTPROP SYMBOL DEFINITION 'SUBR)) ((consp DEFINITION) (PUTPROP SYMBOL DEFINITION 'EXPR)) (T (MAXIMA-ERROR "Invalid symbol definition - FSET" DEFINITION 'WRNG-TYPE-ARG)))) ;;; Takes a list in "alist" form and converts it to one in ;;; "property list" form, i.e. ((A . B) (C . D)) --> (A B C D). ;;; All elements of the list better be conses. (DEFMFUN DOT2L (L) (COND ((NULL L) NIL) (T (LIST* (CAAR L) (CDAR L) (DOT2L (CDR L)))))) ;;; (A-ATOM sym selector value ) ;;; (C-PUT sym value selector) ;;; ;;; They make a symbol's property list look like a structure. ;;; ;;; If the value to be stored is NIL, ;;; then flush the property. ;;; else store the value under the appropriate property. ;;; ;;; >>> Note: Since they do essentially the same thing, one (A-ATOM) ;;; >>> should eventually be flushed... (DEFMFUN A-ATOM (BAS SEL VAL) (CPUT BAS VAL SEL)) (DEFMFUN CPUT (BAS VAL SEL) (COND ((NULL VAL) (zl-REMPROP BAS SEL) NIL) (T (PUTPROP BAS VAL SEL)))) ;;; This is like the function SYMBOLCONC except that it binds base and *nopoint #-Franz (progn 'compile #-NIL (DEFMFUN CONCAT N (LET ((*print-base* 10.) #-cl (*NOPOINT T)) (IMPLODE (MAPCAN 'EXPLODEN (LISTIFY N))))) #+NIL ;In NIL, symbolconc does indeed effectively bind the base and *nopoint. ; This definition may not work if more generality is needed (flonums? ; random Lisp object?) (deff concat #'symbolconc) ) ;#-franz #-cl (progn 'compile (DECLARE (SPECIAL ALPHABET)) ; This should be DEFVAR'd somewhere. Sigh. -kmp ;It is DEFVAR'd in Nparse-wfs (DEFMFUN ALPHABETP (N) (DECLARE (FIXNUM N)) (OR (AND (>= N #\A) (<= N #\Z)) ; upper case (AND (>= N #\a) (<= N #\z)) ; lower case (zl-MEMBER N ALPHABET))) ; test for %, _, or other declared ; alphabetic characters. (DEFMFUN ASCII-NUMBERP (NUM) (DECLARE (FIXNUM NUM)) (AND (<= NUM #\9) (>= NUM #\0))) )