Function definition interrupts pattern matching?

I'm trying to redefine NonCommutativeMultiply (NCM) to behave like an anticommuting operator, based on the question here. This involves calling Unprotect on NCM and adding a definition that leaves a**b**c as-is, but changes a**c**b to -a**b**c. The simplifications all work fine, but after doing all this MatchQ behaves a bit weirdly, returning False when I think it should return true. If I call Block[{NonCommutativeMultiply},MatchQ[...]] then the pattern does indeed match! This solution works, but I'd really like to know what's going on here. Why is my MatchQ returning False?

Minimal example:

(* Before adding the canonical ordering definition, this expression is matched *)
Print[MatchQ[NonCommutativeMultiply[s[1],s[2],s[3]],NonCommutativeMultiply[s[1],d___]]];
(* Out[] := True*)

(* Add a canonical ordering definition (leave a**z as a**z, but change z**a to -a**z) *)
Unprotect[NonCommutativeMultiply];
ClearAttributes[NonCommutativeMultiply,Flat]
NonCommutativeMultiply[H___,B_,A_,T___]:=-NonCommutativeMultiply[H,A,B,T]/;Not[OrderedQ[{B,A}]]

(* After defining canonical ordering, the expression isn't matched any more! This is the problem line. *)
Print[MatchQ[NonCommutativeMultiply[s[1],s[2],s[3]],NonCommutativeMultiply[s[1],d___]]];
(* Out[] := False *)

(* Oddly enough, if s[1] is replaced with a simpler variable, we again match *)
Print[MatchQ[NonCommutativeMultiply[a,s[2],s[3]],NonCommutativeMultiply[a,d___]]];
(* Out[] := True *)

(* It can also be fixed with Block. *)
Print[Block[{NonCommutativeMultiply},MatchQ[NonCommutativeMultiply[s[1],s[2],s[3]],NonCommutativeMultiply[s[1],d___]]]];
(* Out[] := True *)


It should be noted that s[1]**s[2]**s[3] is not changed or reordered by the rule I've added.

• The issue is that nothing stops your definition being applied when an object like d___ appears in NonCommutativeMultiply. You can combat this with HoldPattern. – jjc385 Mar 15 '18 at 0:51

1. There is no need to use Print.
2. There is no need to remove the Flat attribute

NonCommutativeMultiply[s[1], d___]


-d___ ** s[1]

Clearly, NonCommutativeMultiply[s[1], s[2], s[3]] will not match this pattern. To avoid this evaluation, you can use HoldPattern:

MatchQ[
NonCommutativeMultiply[s[1],s[2],s[3]],
HoldPattern@NonCommutativeMultiply[s[1],d___]
]


True

Note that I don't use Print.

By the way, you might try the following alternative instead:

NonCommutativeMultiply[a__] /; !OrderedQ[{a}] := Signature[{a}] NonCommutativeMultiply @@ Sort[{a}]