Ein Muster steht für eine Klasse von Ausdrücken mit derselben internen Struktur.
f[x_]:=x^3
expr /.\
lhs ->
rhs
Jedes Auftreten von lhs in expr wird durch rhs ersetzt. Der Ausdruck wird jedoch nur einmal durchlaufen.
expr //.\
lhs ->
rhs
Jedes Auftreten von lhs in expr wird durch rhs ersetzt. Und zwar so lange bis sich sich der resultierende Ausdruck nicht mehr ändert.
In[2]:= % /. x_^2 -> x
Out[2]= 3/a^2 + a/(2b^2)
Warum werden die quadratischen Terme nicht korrekt ersetzt?
In[3]:= %% // FullForm
Out[3]= Plus[
Times[3, Power[a, -2]],
Times[Rational[1, 2], a,
Power[b, -2]]
]
a wird intern in den Zähler gehoben und mit der
negativen Potenz versehen!
In[4]:= FullForm[x_^2]
Out[4]= Power[Pattern[x, Blank[]], 2]
Beliebige Ausdrücke
Das Blank _ steht für einen einzigen, aber beliebigen Ausdruck. Um im weiteren auf diesen zugreifen zu können, muß er benannt werden:
name_
Ausdrücke mit einem bestimmten Kopf
Das Muster kann zusätzlich auf jene Ausdrücke eingeschränkt werden, die einen bestimmten Kopf (head) haben:
name_head.
In[6]:= f[a_Integer]:= a-1
Out[6]=
a muß den Kopf Integer haben, damit dieses Muster angewendet
werden kann.
In[7]:= f[5]
Out[7]= 4
In[8]:= Head[u]
Out[8]= Symbol
In[9]:= f[u]
Out[9]= f[u]
u hat offenbar den falschen Kopf.
In[10]:= f[1, 4]
Out[10]= f[1, 4]
In[11]:= f[a]:=a-1
Out[11]=
Hier fehlt das blank!
In[12]:= f[5]
Out[12]= 4
f[a] paßt nicht, aber das zuvor definierte f[a_Integer].
In[13]:= f[a]
Out[13]= -1 + a
Wichtige Köpfe
x_Integer | Head[5] ![]() |
x_Real | Head[4.3] ![]() |
x_List | Head[{1, 4, 6}] ![]() |
x_Symbol | Head[a] ![]() |
x_Automat | Automat[expr![]() |
{1, 2, 3, 4}
könnte etwa eine Menge von vier verschiedenen Zuständen
repräsentieren.
In[15]:= States[a_]:=Length[a[[1]]]
Out[15]=
In[16]:= States[5]
Out[16]= Part::partd: Part specification 5[[1]] is longer than depth of object.
2
In[17]:= Clear[States]
Out[17]=
In[18]:= States[a_Automat]:=Length[a[[1]]]
Out[18]=
In[19]:= States[5]
Out[19]= States[5]
In[20]:= States[aut]
Out[20]= 4
Ausdrücke mit bestimmten Eigenschaften
name_?testf
testf ist eine Funktion, deren Ergebnis True oder False sein kann.
In[22]:= IntegerQ[a]
Out[22]= False
In[23]:= IntegerQ[{a, 1}]
Out[23]= False
In[24]:= NumberQ[1]
Out[24]= True
In[25]:= NumberQ[3.5]
Out[25]= True
In[26]:= NumberQ[4/5]
Out[26]= True
In[27]:= NumberQ[Pi]
Out[27]= False
In[28]:= Pi > E
Out[28]= Pi > E
Symbolische Konstanten können nicht direkt miteinander verglichen werden.
In[29]:= Pi > E //N
Out[29]= True
Weitere ,,Testfunktionen``:
EvenQ[] | Argument gerade ? |
OddQ[] | Argument ungerade ? |
PrimeQ[] | Primzahl ? |
VectorQ[] | Vektor / Liste ? |
MatrixQ[] | Matrix / Liste von Listen geeigneter Länge ? |
PrimeQ[] arbeitet mit einem probabilistischen Algorithmus. Daher wird bei großen Argumenten möglicherweise False geliefert, obwohl es sich um eine Primzahl handelt. Der umgekehrte Fall kann nicht auftreten.
In[30]:= Clear[f]
Out[30]=
In[31]:= f[x_?syma]:=1
Out[31]=
Da die Funktion nur eine Konstante liefert, kann die Benennung x der
,,beliebigen expression`` auch unterbleiben.
In[32]:= f[_?syma]:=1
Out[32]=
In[33]:= syma[x_]:=x===a
Out[33]=
Selbstdefinierte Testfunktion.
=== vergleicht, ob die beiden Ausdrücke
identisch sind.
In[34]:= f[u]
Out[34]= f[u]
In[35]:= syma[u]
Out[35]= False
In[36]:= f[a]
Out[36]= 1
In[37]:= Clear[f]
Out[37]=
In[38]:= f[x_Symbol?syma]:=x
Out[38]=
In[39]:= f[1]
Out[39]= f[1]
In[40]:= Head[1]
Out[40]= Integer
In[41]:= f[u]
Out[41]= f[u]
In[42]:= f[a]
Out[42]= a
In[43]:= f[{u_List, n_Integer}]:=u[[n]]
Out[43]=
In[44]:= f[{{A}, 1}]
Out[44]= A
In[45]:= f[A, 1]
Out[45]= f[A, 1]
Hier werden zwei Argumente übergeben. Es wird jedoch eine Liste mit zwei
Elementen erwartet.
In[46]:= f[{A, 1}, 2]
Out[46]= f[{A, 1}, 2]
Abermals zwei Argumente statt einer Liste.
In[47]:= f[{A, 5}]
Out[47]= f[{A, 5}]
Es wird zwar eine Liste übergeben,
aber A ist keine Liste.
In[48]:= f[{{A, B}, 3}]
Out[48]= Part::partw: Part 3 of A, B does not exist.
{A, B}[[3]]
Alternative Schreibweise
pattern|pattern
|...
In[50]:= h[c]
Out[50]= h[c]
In[51]:= h[a]
Out[51]= 2
Eine bessere, übersichtlichere Schreibweise ist:
In[52]:= h[a]:=2
Out[52]=
In[53]:= h[b]:=2
Out[53]=
In[54]:= {a, b, c, d} /. {(a|c)->A}
Out[54]= {A, b, A, d}
In[55]:= {a[2],b[3],c[4],d[5]} /. {(f:(a|b))[x_]->r[f, x]}
Out[55]= {r[a, 2], r[b, 3], c[4], d[5]}
pattern /; cond
lhs := rhs /; cond
Die Nebenbedingung cond muß True liefern, damit das Muster paßt bzw. die Definition angewendet wird.
In[57]:= f[n_ /; n>1]:=n f[n-1]
Out[57]=
oder
In[58]:= f[n_]:=n f[n-1] /; n>1
Out[58]=
oder
In[59]:= f[n_Integer]:=n f[n-1] /; n>1
Out[59]=
oder
In[60]:= f[n_]:=n f[n-1] /; IntegerQ[n] && n>1
Out[60]=
oder
In[61]:= f[n_Integer /; n>1]:=n f[n-1]
Out[61]=
name_:value
name_head:value
Bisher mußten immer alle Argumente übergeben werden, damit ein Muster erkannt oder ein Definition verwendet wurde. Durch die Festsetzung von Default-Werten kann man mehrere Argumente als optional deklarieren und bestimmte Voreinstellungen vorgeben.
In[63]:= get[{1, 2}]
Out[63]= 1
Da n nicht übergeben wurde wird dafür 1 eingesetzt.
In[64]:= get[{a, b}, 2]
Out[64]= b
In[65]:= get[{a, b}, 3]
Out[65]= Part::partw: Part 3 of a, b does not exist.
{a, b}[[3]]
Die Liste enthält nur zwei Elemente.
In[66]:= Clear[get]
Out[66]=
In[67]:= get[x_, n_:1]:=x[[n]] /; Length[x]>=n
Out[67]=
In[68]:= get[{a, b}, 3]
Out[68]= get[{a, b}, 3]
In[69]:= get[{a, b}, E]
Out[69]= get[{a, b}, E]
In[70]:= get[{a, b, c}, -2]
Out[70]= b
In[71]:= get[h[u, v], -3]
Out[71]= Part::partw: Part -3 of h[u, v] does not exist.
h[u, v][[-3]]
In[72]:= get[h[u, v], -2.6]
Out[72]= Part::pspec: Part specification -2.6 is neither an integer
nor a list of non-zero integers.
h[u, v][[-2.6]]
In[73]:= get[x_, n_Integer:1]:=x[[n]] /; Positive[n] && Length[x]>=n
Out[73]=
In[74]:= get[x_, n_Integer?Positive:1]:=x[[n]] /; Length[x]>=n
Out[74]=
In[75]:= get[x_, n:(_Integer?Positive):1]:=x[[n]] /; Length[x]>=n
Out[75]=
Das double blank ,,__`` steht für einen oder mehrere beliebige Ausdrücke. Analog zum einfachen blank kann das Muster näher spezifiziert werden:
name__
name__head
name__?testf
In[77]:= h[x__]:={x} /; Length[{x}]>2
Out[77]=
In[78]:= h[a]
Out[78]= h[a]
In[79]:= h[a, 1, b]
Out[79]= {a, 1, b}
Fehlerhafte Beispiele
In[80]:= Clear[h]
Out[80]=
In[81]:= h[x__]:={x} /; Length[x]>2
Out[81]=
In[82]:= h[1, a, 2, b]
Out[82]= Length::argx: Length called with 4 arguments; 1 argument is expected.
h[1, a, 2, b]
In[83]:= Clear[h]
Out[83]=
In[84]:= h[x__Integer]:=x
Out[84]=
In[85]:= h[a]
Out[85]= h[a]
In[86]:= h[5]
Out[86]= 5
In[87]:= h[5, 9]
Out[87]= Sequence[5, 9]
___ ,,Triple Blank``
name___
name___head
name___?testf
In[89]:= h[{1, 2}]
Out[89]= h[{1, 2}]
Das dritte Argument c fehlt. Daher kann obiges
Muster nicht verwendet werden
In[90]:= h[{1, 2, 3}]
Out[90]= {1, 2, 3}
In[91]:= h[{1, 2, 3, 4, 5, 6, 7}]
Out[91]= {1, 2, 3, 4, 5, 6, 7}
In[92]:= h[{a_Integer, b_Integer, c_Integer, r___Integer}]:=r
Out[92]=
In[93]:= h[{1, 2, 3, 4, 5, 6, 7}]
Out[93]= Sequence[4, 5, 6, 7]
r wird intern nicht als Liste, sondern als Sequence gespeichert.
Grundregeln für die Verwendung von ,,___`` (aus der Praxis gewonnen):
___ sollte auf beiden Seiten begrenzt sein:
Belegungsregeln für Mehrfachmuster
Mit folgendem Befehl kann man die Belegung herausfinden
In[94]:= h[x__, y__]:={x, y} /; Print["x=", x, "y=", y]
Out[94]=
Das Ergebnis einer Nebenbedingung muß True ergeben, damit sie als zutreffend erkannt wird. Print wird nie True zurückliefern, erlaubt uns jedoch, die Belegung der Argumente zu untersuchen. Wird eine sinnvolle Nebenbedingung verwendet, dann werden alle Möglichkeiten, die Argumente zu verteilen, durchprobiert, bis die Nebenbedingung erfüllt ist. Alle weiteren Möglichkeiten, auch wenn sie die Nebenbedingung erfüllen, werden ignoriert.
h[x__, y__] | x | y |
h[a, b] | a | b |
h[a, b, c] | a | b, c |
a, b | c | |
h[a, b, c, d] | a | b, c, d |
a, b | c, d | |
a, b, c | d |
h[x__, y___] | x | y |
h[a] | a | |
h[a, b] | a | b |
a, b | ||
h[a, b, c] | a | b, c |
a, b | c | |
a, b, c |