9
$\begingroup$

The document says:

OneIdentity is an attribute that can be assigned to a symbol f to indicate that f[x], f[f[x]], etc. are all equivalent to x for the purpose of pattern matching.

Consider the expressions below:

In[1]:= SetAttributes[f, OneIdentity]
In[2]:= Nest[f, x, 10]    
Out[2]= f[f[f[f[f[f[f[f[f[f[x]]]]]]]]]]

We cannot get f[x] as the document says.

In[1]:= MatchQ[x, Times[n_. , x_]]
Out[1]= True

Also, the example in the document seems a little confusing. What does the pattern Times[n_.,x_] mean?

I'm quite confused about it. Please explains this.

$\endgroup$
  • 4
    $\begingroup$ It treats the expression as equivalent to x for the purpose of pattern matching. It doesn't evaluate to x. $\endgroup$ – march Aug 20 '16 at 5:11
7
$\begingroup$

What the documentation means is that for a symbol f with attribute OneIdentity, pattern forms like f[_.,x], f[_.,f[_.,x]], etc. (Note the Possible Issues section!) will not only match expression like f[4,a] but also an expression without a Head f.

Take the CirclePlus, which has no built-in meaning or any attribute, as an example.

Clear[CirclePlus]
ClearAttributes[CirclePlus, Attributes@CirclePlus];
DefaultValues[CirclePlus] = {};
Attributes[CirclePlus]
{}

This will work as expected:

k⊕y /. a_⊕x_ :> {a, x}
k⊕y /. a_.⊕x_ :> {a, x}
{k, y}
{k, y}

But this won't work because a_.⊕x_ or (a_:1)⊕x_ won't match y:

y /. a_.⊕x_ :> {a, x}
y /. (a_: 1)⊕x_ :> {a, x}
y
y

Instead of introducing a special rule like x_:>{1,x}, we can add the OneIdentity to CirclePlus:

SetAttributes[CirclePlus, OneIdentity]

Now this works as well:

y /. (a_: 1)⊕x_ /; (Echo[a]; True) :> {a, x}
1
{1, y}

This still won't work

y /. a_.⊕x_ :> {a, x}

until CirclePlus gets DefaultValues:

Default[CirclePlus] := RandomReal[];

Now a_.⊕x_ will match y:

y /. a_.⊕x_ /; (Echo[a]; True) :> {a, x}
0.217426
{0.217426, y}

And nested CirclePlus will also match y:

y /. a_.⊕(b_.⊕x_) /; (Echo[{a, b}]; True) :> {a, b, x}
{0.934169, 0.157904}
{0.934169, 0.157904, y}
y /. a_.⊕(x_⊕b_.) /; (Echo[{a, b}]; True) :> {a, b, x}
{0.319821, 0.490549}
{0.319821, 0.490549, y}

or match 4⊕y:

4⊕y /. a_.⊕(x_⊕b_.) /; (Echo[{a, b}]; True) :> {a, b, x}
{4, 0.861579}
{4, 0.861579, y}
| improve this answer | |
$\endgroup$
  • $\begingroup$ @ShutaoTang I'm a bit of busy this year. (But I still visit the site regularly!) $\endgroup$ – Silvia Aug 20 '16 at 16:00
  • $\begingroup$ @Silvia 膜巨神……话说还有那些中国人在这里?感觉完全认不全 $\endgroup$ – Wjx Aug 22 '16 at 3:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.