weixin_39747383 2020-11-29 23:26
浏览 0

Pattern-matching with Flat Attribute: Different from Mathematica

Please consider

SetAttributes[eqv, Flat]
eqv[p, q, q, p] /. eqv[x_, y_] :> {x, y}

which produces

{q, eqv[q, q, p]}

in mathics, and

{eqv[q], eqv[q, q, p]}

in Mathematica. This has ramifications in symbolic manipulations with custom associative operators because the missing head eqv is observable in semantics layers.

该提问来源于开源项目:mathics/Mathics

  • 写回答

5条回答 默认 最新

  • weixin_39747383 2020-11-29 23:26
    关注

    Looks like mathics assumes OneIdentity. Let's consider Mathematica's built-in Or, first. Its relevant attributes are just Flat, OneIdentity:

    
    In[97]:= Attributes[Or]
    Out[97]= {Flat, HoldAll, OneIdentity, Protected}
    

    It also has no Default:

    
    In[99]:= Default[Or]
    Out[99]= Default[Or]
    

    That produces the following behavior:

    
    In[107]:= Or[p, p, p] /. Or[a_, b_] :> {a, b}
    Or[p, p, p] /. Or[a_., b_.] :> {a, b}
    
    Out[107]= {p, p || p}
    Out[108]= {p, p} || p
    
    In[109]:= Or[p, p, p]
    Out[109]= p || p || p
    
    In[112]:= Or[p, q] === Or[q, p]
    Out[112]= False
    

    This is similar to, but not exactly the same, as mathics; Pattern produces a nodef message by side effect when presented with Optional[Blank[]] patterns (syntax: _., underscore-dot) and reduces as if the patterns were not optional.

    
    In[9]:= Or[p, p, p] /. Or[a_, b_] :> {a, b}
    Out[9]= {p, p || p}
    
    In[10]:= Or[p, p, p] /. Or[a_., b_.] :> {a, b}
    Pattern::nodef: No default setting found for Or in position 1 when length is 2.
    Out[10]= {p, p || p}
    
    In[11]:= Or[p, p, p]
    Out[11]= p || p || p
    
    In[12]:= Or[p, q] === Or[q, p]
    Out[12]= False
    

    We want our or to be symmetric, so we will add Orderless. First, here is what Mathematica says, in stages, adding the attributes one at a time:

    
    In[43]:= ClearAll[or]; SetAttributes[or, {Flat}]
    or[p, p, p] /. or[a_, b_] :> {a, b}
    or[p, p, p] /. or[a_., b_.] :> {a, b}
    
    Out[44]= {or[p], or[p, p]}     {a, b}
    or[p, p, p] /. or[a_., b_.] :> {a, b}
    
    Out[41]= {p, or[p, p]}     {a, b}
    or[p, p, p] /. or[a_., b_.] :> {a, b}
    
    Out[47]= {p, or[p, p]}    

    Mathics disagrees right away:

    
    In[13]:= ClearAll[or]; SetAttributes[or, {Flat}]
    In[14]:= or[p, p, p] /. or[a_, b_] :> {a, b}
    Out[14]= {p, or[p, p]}
    
    In[15]:= or[p, p, p] /. or[a_., b_.] :> {a, b}
    Pattern::nodef: No default setting found for or in position 1 when length is 2.
    Out[15]= {p, or[p, p]}
    
    In[16]:= ClearAll[or]; SetAttributes[or, {Flat, OneIdentity}]
    In[17]:= or[p, p, p] /. or[a_, b_] :> {a, b}
    Out[17]= {p, or[p, p]}
    
    In[18]:= or[p, p, p] /. or[a_., b_.] :> {a, b}
    Pattern::nodef: No default setting found for or in position 1 when length is 2.
    Out[18]= {p, or[p, p]}
    
    In[19]:= ClearAll[or]; SetAttributes[or, {Flat, Orderless, OneIdentity}]
    In[20]:= or[p, p, p] /. or[a_, b_] :> {a, b}
    Out[20]= {p, or[p, p]}
    
    In[21]:= or[p, p, p] /. or[a_., b_.] :> {a, b}
    Out[21]= {p, or[p, p]}
    
    评论

报告相同问题?