TTYOFF:TRUE$
DIMENSION(W) := BLOCK(/* W is an equation or a list of
      equations with an indeterminate on the left and a product of
      powers of MASS, LENGTH, TYME, TEMPERATURE, and CHARGE on
      the right.  Globally establishes corresponding row(s) for
      exponent matrices, returning DONE. */
   [V, ACTUAL, VALID],
   VALID: '[MASS, LENGTH, TYME, CHARGE, TEMPERATURE],
   W:LISTIFY(W),
   FOR U IN W DO (
      V:RHS(U), U:LHS(U),
      ACTUAL: LISTOFVARS(V),
      FOR AC IN ACTUAL DO IF NOT MEMBER(AC,VALID) THEN PRINT(
         "WARNING:", AC, "NOT MEMBER OF", VALID),
      PUT(U,V,'DIMENSION))) $

LISTIFY(W) := IF LISTP(W) THEN W ELSE [W] $

%PURE: '[BOLTZMANNSCONSTANT, ELECTRICPERMITTIVITYOFAVACUUM] $

NONDIMENSIONALIZE(U) := BLOCK(/* U is a list of indeterminates
      representing classes of physical quantities such as VELOCITY or
      LENGTH, for which dimensions have previously been established
      by the DIMENSION function.  Returns a list of nondimensional
      combinations of the physical quantities in U. */
   [B, C, V, W, M, N, I, R, BASIS, LOGEXPAND, RATMX, SCALARMATRIXP],
   U: LISTIFY(U),

   /* Determine basis: */
   M:N:0,
   BASIS:[LENGTH, TYME, MASS, TEMPERATURE, CHARGE],
   IF MEMBER('BOLTZMANNSCONSTANT, %PURE) THEN (M:M+1,
       BASIS:DELETE('TEMPERATURE,BASIS)),
   IF MEMBER('ELECTRICPERMITTIVITYOFAVACUUM,%PURE) THEN (M:M+1,
       BASIS:DELETE('CHARGE,BASIS)),
   IF MEMBER('GRAVITYCONSTANT,%PURE) THEN (N:N+1,
      BASIS:DELETE('MASS,BASIS)),
   IF MEMBER('PLANCKSCONSTANT,%PURE) THEN (N:N+1,
      BASIS:DELETE('TYME,BASIS)),
   IF MEMBER('SPEEDOFLIGHT,%PURE) THEN (N:N+1,
      BASIS:DELETE('LENGTH,BASIS)),
   IF BASIS=[] THEN RETURN(U),
   IF N>0 AND M<2 THEN ERROR("INVALID TO INCLUDE GRAVITYCONSTANT",
      "PLANCKSCONSTANT OR SPEEDOFLIGHT WITHOUT ALSO INCLUDING",
      "BOLTZMANNSCONSTANT & ELECTRICPERMITTIVITYOFAVACUUM"),
   C:B:V:W: [],
   LOGEXPAND:RATMX:TRUE,  SCALARMATRIXP:FALSE,
   N:0, M:LENGTH(BASIS),

   /* Construct matrix of exponents: */
   FOR UU IN U DO (B: GET(UU, 'DIMENSION),
      IF B=FALSE THEN ERROR("FIRST DO AN APPROPRIATE DIMENSION(",''UU,
      "= TERM WITH POWERS OF MASS, LENGTH, TYME, TEMPERATURE & CHARGE"
         ),
      IF MEMBER('BOLTZMANNSCONSTANT, %PURE) THEN
         B: SUBST(TEMPERATURE=MASS*LENGTH^2/TYME^2, B),
      IF MEMBER(ELECTRICPERMITTIVITYOFAVACUUM,%PURE) THEN
         B: SUBST(CHARGE=LENGTH^(3/2)*MASS^(1/2)/TYME, B),
      IF MEMBER(SPEEDOFLIGHT,%PURE) THEN
         IF MEMBER(PLANCKSCONSTANT,%PURE) THEN
            B: SUBST([LENGTH=1/MASS,TYME=1/MASS], B)
         ELSE IF MEMBER(GRAVITYCONSTANT,%PURE) THEN
            B: SUBST([MASS=TYME,LENGTH=TYME], B)
         ELSE B: SUBST(LENGTH=TYME, B)
      ELSE IF MEMBER(PLANCKSCONSTANT,%PURE) THEN
         IF MEMBER(GRAVITYCONSTANT,%PURE) THEN
            B: SUBST([MASS=LENGTH^(-1/3), TYME=LENGTH^(-5/3)], B)
         ELSE B: SUBST(TYME=MASS*LENGTH^2, B)
      ELSE IF MEMBER(GRAVITYCONSTANT,%PURE) THEN
         B: SUBST(MASS=LENGTH^3/TYME^2, B),
      B:LOG(B),  R:[],
      FOR UU IN BASIS DO R:CONS(COEFF(B,LOG(UU)), R),
      C:CONS(R,C), W:CONS(UU,W), N:N+1),
   C:SUBSTINPART('MATRIX,C,0),
   R:RANK(C),
   IF R=0 THEN RETURN(U),
   IF R=N THEN RETURN([]),

   /* Delete dependent columns: */
   I:1,
   WHILE R<M DO (B:SUBMATRIX(C,I),
      WHILE RANK(B)<R DO (I:I+1,
         B:SUBMATRIX(C,I)),
      M:M-1,
      C:B),

   /* Partition into a nonsingular part and the other rows: */
   C:SUBSTINPART("[",C,0),  B:[], 
   FOR J:1 THRU R DO(
      B:CONS(FIRST(C),B),
      WHILE RANK(SUBSTINPART('MATRIX,B,0))<J DO(
         C:ENDCONS(FIRST(C),REST(C)),
         B:CONS(FIRST(C),REST(B)),
         W:ENDCONS(FIRST(W),REST(W))),
      C:REST(C), V:CONS(FIRST(W),V), W:REST(W)),
   C:SUBSTINPART('MATRIX,C,0),  B:SUBSTINPART('MATRIX,B,0),

   /* Form the matrix of physical-quantity exponents and the
      corresponding dimensionless products: */
   C: C.B^^-1,  B:[],
   FOR L:1 THRU N-R DO
      B: CONS(W[L]/PRODUCT(V[K]^C[L,K],K,1,R), B),
   RETURN(B)) $

DIMENSION([
ACCELERATION = LENGTH/TYME^2,
ANGLE = 1,
ANGULARACCELERATION = 1/TYME^2,
ANGULARMOMENTUM = MASS*LENGTH^2/TYME^2,
ANGULARVELOCITY = 1/TYME,
AREA = LENGTH^2,
BOLTZMANNSCONSTANT = MASS*LENGTH^2/TYME^2/TEMPERATURE,
CAPACITANCE = TYME^2*CHARGE^2/MASS/LENGTH^2,
CHARGE = CHARGE,
CURRENT = CHARGE/TYME,
CURRENTDENSITY = CHARGE/TYME/LENGTH^2,
DENSITY = MASS/LENGTH^3,
DISTANCE = LENGTH,
ELECTRICFIELD = MASS*LENGTH/TYME^2/CHARGE,
ELECTRICPERMITTIVITY = TYME^2*CHARGE^2/MASS/LENGTH^3,
ELECTRICPERMITTIVITYOFAVACUUM = TYME^2*CHARGE^2/MASS/LENGTH^3,
ENERGY = MASS*LENGTH^2/TYME^2,
ENTHALPY = LENGTH^2/TYME^2,
FREQUENCY = 1/TYME,
FILMCOEFFICIENT = MASS/TYME^3/TEMPERATURE,
FLOW = LENGTH^3/TYME,
GRAVITYCONSTANT = LENGTH^3/MASS/TYME^2,
HEAT = MASS*LENGTH^2/TYME^2,
HEATCAPACITY = MASS*LENGTH^2/TYME^2/TEMPERATURE,
HEATTRANSFERCOEFFICIENT = 1/TYME,
INDUCTANCE = MASS*LENGTH^2/CHARGE^2,
INTERNALENERGY = LENGTH^2/TYME^2,
KINEMATICVISCOSITY = LENGTH^2/TYME,
LENGTH = LENGTH,
MASS = MASS,
MOMENT = MASS*LENGTH^2/TYME^2,
MOMENTUM = MASS*LENGTH/TYME,
MAGNETICINDUCTION = MASS/TYME/CHARGE,
MAGNETICPERMITTIVITY = MASS*LENGTH/CHARGE^2,
PLANCKSCONSTANT = MASS*LENGTH^2/TYME,
POISSONSRATIO = 1,
POWER = MASS*LENGTH^2/TYME^3,
PRESSURE = MASS/LENGTH/TYME^2,
RESISTANCE = MASS*LENGTH^2/TYME/CHARGE^2,
SPECIFICHEAT = LENGTH^2/TYME^2/TEMPERATURE,
SPEEDOFLIGHT = LENGTH/TYME,
SHEARMODULUS = MASS/LENGTH/TYME^2,
SURFACETENSION = MASS/TYME^2,
STEFANBOLTZMANNCONSTANT = MASS/TYME^3/TEMPERATURE^4,
STRESS = MASS/LENGTH/TYME^2,
STRAIN = 1,
TEMPERATURE = TEMPERATURE,
THERMALCONDUCTIVITY = MASS*LENGTH/TYME^3/TEMPERATURE,
THERMALEXPANSIONCOEFFICIENT = 1/TEMPERATURE,
THERMALDIFFUSIVITY = LENGTH^2/TYME,
TYME = TYME,
VELOCITY = LENGTH/TYME,
VOLUME = LENGTH^3,
VOLTAGE = MASS*LENGTH^2/TYME^2/CHARGE,
VISCOSITY = MASS/TYME/LENGTH,
WORK = MASS*LENGTH^2/TYME^2,
YOUNGSMODULUS = MASS/LENGTH/TYME^2]) $
ALIAS(TIME,TYME,CPUTIME,TIME)$
TTYOFF: FALSE$
