mul(zz, zz, zz). mul(qq, qq, qq). mul(zz, qq, qq). mul(poly(A), poly(A), poly(A)) :- ring(A). mul(A, vec(B), vec(C)) :- mul(A, B, C). mul(vec(A), B, vec(C)) :- mul(A, B, C). mul(A, poly(B), poly(C)) :- mul(A, vec(B), vec(C)). mul(poly(A), B, poly(C)) :- mul(vec(A), B, vec(C)). mul(mat(A), mat(B), mat(C)) :- mul(A, B, C), add(C, C, C). mul(A, mat(B), mat(C)) :- mul(A, vec(B), vec(C)). mul(A, B, B) :- coerce(A, B), mul(B, B, B). coerce(A, poly(A)). coerce(poly(A), poly(B)) :- coerce(A, B). coerce(zz, qq). add(zz, zz, zz). add(qq, qq, qq). add(poly(A), poly(B), poly(C)) :- add(A, B, C), zero(A), zero(B). add(A, poly(B), poly(B)) :- add(A, B, B), zero(B). add(mat(A), mat(B), mat(C)) :- add(A, B, C). add(A, B, B) :- coerce(A, B), add(B, B, B). add(vec(A), vec(B), vec(C)) :- add(A, B, C). zero(zz). zero(qq). zero(poly(_)). zero(vec(A)) :- zero(A). zero(mat(A)) :- zero(vec(A)). ring(A) :- mul(A, A, A), add(A, A, A), zero(A). module(A, M) :- ring(A), mul(A, M, M), add(M, M, M), zero(M).