Exploiting functional dependencies in declarative problem specifications