I asked the SMT solver Z3 to provide a function that is not associative but commutative. The way to do this is to assert commutativity for all possible inputs and ask for a counter-example for the associativity property.
The Z3 script in SMTlib format is:
(declare-fun f (Int Int) Int) ;We are looking for a function f
(assert (forall ((a Int) (b Int)) (= (f a b) (f b a)))) ;That's commutative
;With one non-associative counter-example
(declare-fun a () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(assert (not (= (f a (f b c)) (f (f a b) c))))
(check-sat)
(get-model) ;Find the function
And the resulting model is:
(model
(define-fun b () Int ;Counter-example
1)
(define-fun a () Int ;Counter-example
0)
(define-fun c () Int ;Counter-example
2)
(define-fun f!1 ((x!1 Int) (x!2 Int)) Int ;Sub-function
(ite (and (= x!1 0) (= x!2 3)) 4
(ite (and (= x!1 0) (= x!2 1)) 5
(ite (and (= x!1 5) (= x!2 2)) 6
(ite (and (= x!1 3) (= x!2 0)) 4
(ite (and (= x!1 1) (= x!2 0)) 5
(ite (and (= x!1 2) (= x!2 5)) 6
3)))))))
(define-fun k!0 ((x!1 Int)) Int ;Sub-function
(ite (= x!1 0) 0
(ite (= x!1 2) 2
(ite (= x!1 3) 3
(ite (= x!1 5) 5
1)))))
(define-fun f ((x!1 Int) (x!2 Int)) Int ;Resulting function
(f!1 (k!0 x!1) (k!0 x!2)))
)
define-fun f
marks the generated function with the desired properties. If you sift through its definition you can see that it is defined for a few points only. On almost all inputs the function returns 3 but it has a few special points that give the resulting properties.
define-fun a/b/c
marks the counter-example to associativity.
ite
means if-then-else. If argument 1 is true, then return argument 2. Else argument 3.
The function works over the integers but any other domain with enough values works as well. There are no algebraic operations being performed.
I lack the syntax skills to put the function into a nice format that is customary on this site. I can translate to C, however:
int k(int x) { return
x == 0 ? 0 :
x == 2 ? 2 :
x == 3 ? 3 :
x == 5 ? 5 :
1;
}
int f1(int x, int y) { return
x == 0 && y == 3 ? 4 :
x == 0 && y == 1 ? 5 :
x == 5 && y == 2 ? 6 :
x == 3 && y == 0 ? 4 :
x == 1 && y == 0 ? 5 :
x == 2 && y == 5 ? 6 :
3;
}
int f(int x, int y) {
return f1(k(x), k(y));
}
Mostly, tables of inputs and outputs with a "catch-all" case for all otherwise unhandled cases.
You can execute the code and play with it online.
I thought this would be an interesting example of such a function because it is so simple. It's only structure is basically a point-wise definition with just a few such points. Many of the other answers have given much more complicated mathematical examples. I hope this is an interesting complement to them.
It was mentioned in the comments that IEEE floats pose another example. Z3 can reason precisely about floats. In case you're interested here's a proof that float addition is commutative: http://rise4fun.com/Z3/CplfO This could be extended to check non-associativity as well.