Post Reply 
HP48 programming: use values from stack in expression
12-04-2018, 02:44 AM (This post was last modified: 12-05-2018 01:15 PM by Giuseppe Donnini.)
Post: #8
RE: HP48 programming: use values from stack in expression
But of course! Lists become procedure class objects when "evaluated"--as opposed to being merely "executed". Excellent suggestion, Thomas, thanks! I already changed my post accordingly.

For multiple variable substitutions, I use the following program which indeed relies on MATCH and works almost the same as your DOLIST example, except that it uses an explicit loop.

Code:
@ SUBST (version A)
@ ( 'old' { { name1 val1 } { name2 val2 } ... { namen valn } } --> 'new' )
@ Example: ( 'X+Y' { { X 1 } { Y 2 } } --> '1+2' )
\<<
  REVLIST         @ Needed since sublists will be handled in reverse order (*).
  OBJ\->          @ Explode list.
  DUP 2 + ROLL    @ Roll original expression to level 1.
  SWAP 1 SWAP     @ Set up loop counter.
  START           @ Repeat n times:
    SWAP          @ - Get next sublist.
    \|^MATCH DROP @ - Do substitution.
  NEXT
\>>

@ (*) Without REVLIST, one would get
@       ( 'X+Y' { { X Y+1 } { Y 2 } } --> 'Y+1+2' )
@     instead of
@       ( 'X+Y' { { X Y+1 } { Y 2 } } --> '2+1+2' )
@     because the Y=2 substitution would be done first.

MATCH is a very powerful command, whose full potential I did not realize until studying Bill Wickes' "Insights" books. Because it uses MATCH, SUBST is in fact much more flexible than it at first appears. Actually, its level 1 argument allows the more general form:

{ { 'pattern1' 'replacement1' } ... { 'patternn' 'replacementn' } }

of which

{ { name1 value1 } ... { namen valuen } }

is only a small subset. You can therefore easily replace entire sub-expressions, as in the following example:

( 'COS(X)/SIN(X)+3*Y' { { 'COS(X)/SIN(X)' 'COT(X)' } { Y 5 } } --> 'COT(X)+3*5' )

The most powerful feature of MATCH, however, is that it allows you to use wild cards to target specific sub-expressions inside the main algebraic expression. Any name that begins with the ampersand character "&" is interpreted as a wild card. Suppose you have the following expression:

'(SIN(X^2+1/Y))'


and you want to replace X with 9, Y with 2, and then expand the sum according to the addition law for sines. This is easily done with the following level 1 argument:

{ { X 9 } { Y 2 } { 'SIN(&1+&2)' 'SIN(&1)*COS(&2)+COS(&1)*SIN(&2)' } }


The result will be:

'SIN(9^2)*COS(1/2)+COS(9^2)*SIN(1/2)'


Or, suppose you want to replace every square root in an expression with a cubic root. This simple level 1 argument: { { '\v/&1' 'XROOT(3,&1)' } } will carry out all the replacements.

As a further refinement, you may specify an optional third algebraic in each list which, when evaluated, must return a user flag determining whether the replacement should take place or not. For example, while simplifying square roots of squares, you may want to make sure that the arguments of the square function are actually positive:

{ { '\v/(&1^2)' &1 '&1\>=0' } }

Since the optional test argument is less often needed, and since one might prefer a more mathematical look and feel, here's an alternative version of SUBST, which uses a list of equations instead of a list of lists as its level 1 argument. For convenience, a single equation may also be entered without list delimiters.

Code:
@ SUBST (version B)
@ [A] ( 'old' 'name=value' --> 'new' )
@ [B] ( 'old' { 'name1=val1' 'name2=val2' ... 'namen=valn' } --> 'new' )
@ Examples: ( 'SIN(X)' 'X=30' --> 'SIN(30)' )
@           ( 'X+Y' { 'X=1' 'Y=COS(60)' } --> '1+COS(60)' )
\<<
  IF DUP TYPE 9 SAME @ If single equation (case A),
  THEN { } + END     @   embed it in a list (reduction to case B).
  REVLIST            @ Needed since equations will be handled in reverse order.
  OBJ\->             @ Explode list.
  DUP 2 + ROLL       @ Roll original expression to level 1.
  SWAP 1 SWAP        @ Set up loop counter.
  START              @ Repeat n times:
    SWAP             @ - Get next equation.
    EQ\-> 2 \->LIST  @ - Take it apart and build list for MATCH.
    \|^MATCH DROP    @ - Do substitution.
  NEXT
\>>

The more elaborate constructs described above, involving entire expressions and wild cards, are also available in this version of SUBST, albeit with the following restrictions:
1. Since the list elements have the general form 'pattern=replacement', pattern and replacement may not be equations themselves.
2. The optional test argument is not available.
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: HP48 programming: use values from stack in expression - Giuseppe Donnini - 12-04-2018 02:44 AM



User(s) browsing this thread: 1 Guest(s)