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$
1
  • 5
    $\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, 2016 at 5:11

1 Answer 1

8
$\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}
$\endgroup$
2
  • $\begingroup$ @ShutaoTang I'm a bit of busy this year. (But I still visit the site regularly!) $\endgroup$
    – Silvia
    Aug 20, 2016 at 16:00
  • $\begingroup$ @Silvia 膜巨神……话说还有那些中国人在这里?感觉完全认不全 $\endgroup$
    – Wjx
    Aug 22, 2016 at 3:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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