When creating a metamodel instance (ie. model), the structure of the metamodel can be used to automatically validate the structure of the corresponding model. Basically every class, association and attribute value can be interpreted as a constraint (validation rule) to enforce certain properties and characteristics of the model (metadata). As metamodels are often seen as 'defining languages for model descriptions' we might consider these rules a syntax check for a model expressed in this language.  
Constraints (validation rules) can be materialized and enforced during metadata scanning/loading process, during a dedicated validation maintenence task, on demand etc. In MMX framework the rules are implemented on database level as a set of data constraints of the metadata repository and form a protective layer transaparent to a user or an application built on the framework. Only 'structural' properties of a metamodel have been implemented - 'semantic' properties (homonyms, synonyms, reflexivity, transitivity etc.) and their use as validation rules is a separate (and much more complex) topic not covered yet. The rules for model validation implemented in MMX (and how they are enforced through constraints) are as follows: 
:{M1} objects inherit their type codes from corresponding classes in {M2} metamodel(s). Only concrete classes can have corresponding objects.
object.Type *partof(objectClass.Type) & objectClass.IsAbstractClass = False
relation.Type *partof(relationClass.Type)
property.Type *partof(propertyClass.Type)
:{M2} class names are unique within a namespace, ie. {M2} metamodel and are never empty.

objectClass.Name *isunique(objectClass.Name) & objectClass.Name <> nil

:{M1} parent-child relations between objects are derived from designated associations between their superclasses in {M2} metamodel(s). 
object.parent.Type *partof(*tree(relationClass.relatedObject.Type)) & relationClass.IsTaxonomy = True

:{M1} related objects inherit their type codes from {M2} classes and/or their superclasses related through {M2} associations and/or {M2} attributes.
relation.object.Type *partof(*tree(relationClass.object.Type))
relation.relatedObject.Type *partof(*tree(relationClass.relatedObject.Type))
property.object.Type *partof(*tree(propertyClass.object.Type))
property.domain.Type *partof(*tree(propertyClass.domain.Type))

:{M1} linear properties as well as significiant elements of hierarchical properties with empty (null) value inherit the default value from the corresponding {M2} attributes.

property.Value *coalesce(property.Value, propertyClass.defaultValue)

:The number of {M1} objects participating in a relation cannot exceed or subcede the one expressed by the multiplicity property of the corresponding {M2} association on both ends.

*numberof(relation.object) *ge(relationClass.multiplicity.minValue)
*numberof(relation.relatedObject) *ge(relationClass.multiplicity.minValue)
*numberof(relation.object) *le(relationClass.multiplicity.maxValue)
*numberof(relation.relatedObject) *le(relationClass.multiplicity.maxValue)

:When the 'whole' object of a {M1} relation (descending from a {M2} association of type 'aggregation') is deleted, the relation itself is also deleted. When the 'whole' object of a {M1} relation (descending from a {M2} association of type 'composition') is deleted, both the relation and the 'parts' object are deleted.

*isdeleted(relation.object) & relationClass.Type = 'AGGR' -> relation := nil
*isdeleted(relation.object) & relationClass.Type = 'COMP' -> relation := nil
*isdeleted(relation.object) & relationClass.Type = 'COMP' -> relation.relatedObject := nil

The implementations are defined in an intuitive semi-formal notation. The operators *isunique, *partof, *tree, *isdeleted, *numberof, *ge and *le denote abstract pseudo-operations of uniqueness, being part of, tree of ancestors, deletion, count, greater-than-or-equal and less-than-or-equal.