Finite model reasoning on UML class diagrams via constraint programming