next up previous contents
Nächste Seite: 3.3 Evaluation Aufwärts: 3 Grundlagen Vorherige Seite: 3.1 Everything is an   Inhalt

Unterabschnitte


3.2 Muster (Patterns)

Ein Muster steht für eine Klasse von Ausdrücken mit derselben internen Struktur.

Beispiel

In[1]:= 3/a^2 + a/(2b^2)
Out[1]= 3/a^2 + a/(2b^2)

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]

Arten von Mustern


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.

Beispiel

In[5]:= Clear[f]
Out[5]=

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] $\rightarrow$ Integer
x_Real Head[4.3] $\rightarrow$ Real
x_List Head[{1, 4, 6}] $\rightarrow$ List
x_Symbol Head[a] $\rightarrow$ Symbol
x_Automat Automat[expr$_1$,...]

Beispiel

In[14]:= aut=Automat[{1, 2, 3, 4}, {1 -> 2, 2 -> 3}]
Out[14]= Automat[{1, 2, 3, 4}, {1 -> 2, 2 -> 3}]

{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.

Beispiel

In[21]:= IntegerQ[1]
Out[21]= True

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.

Beispiele verschiedener Kombinationen

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$_1$|pattern$_2$|...

Beispiel

In[49]:= h[a|b]:=2
Out[49]=

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]=

Transformation Rules

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]}

Nebenbedingungen (Constraints)

pattern /; cond
lhs := rhs /; cond

Die Nebenbedingung cond muß True liefern, damit das Muster paßt bzw. die Definition angewendet wird.

Beispiel

Fakultät händisch nachprogrammiert: In[56]:= f[1]:=1
Out[56]=

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]=

Default-Werte

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.

Beispiel

In[62]:= get[x_, n_:1]:=x[[n]]
Out[62]= General::spell1: Possible spelling error: new symbol name "get" is similar to existing symbol "Get".

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]=

Mehrere beliebige Ausdrücke

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

Beispiel

In[76]:= Clear[h]
Out[76]=

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]

Muster für viele (beliebige) Ausdrücke

___ ,,Triple Blank``
name___
name___head
name___?testf

Beispiel

In[88]:= h[{a_Integer, b_Integer, c_Integer, r___Integer}]:={a, b, c, r}
Out[88]=

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


next up previous contents
Nächste Seite: 3.3 Evaluation Aufwärts: 3 Grundlagen Vorherige Seite: 3.1 Everything is an   Inhalt
Werner Scholz 2000-06-21