well-formed member of the argument will cause the predicate to bail out
with an exception during traversal.
"""
- t_root = type(root)
- if t_root is list:
+ if isinstance (root, list):
cnf = root
- elif t_root is dict:
- cnf = root["cnf"]
else:
- raise InvalidCNF(root)
+ cnf = cnf_root (root)
+ if cnf is None:
+ raise InvalidCNF (root)
return walk_cnf(cnf, False, is_valid, {}) is not None
#
return (depth, acc)
-def cnf_root(root):
+CNF_FIELD_MANDATORY = set ([ "varname", "data", "instance" ])
+CNF_FIELD_OPTIONAL = set ([ "parent", "children", "comment", "number" ])
+CNF_FIELD_KNOWN = CNF_FIELD_MANDATORY | CNF_FIELD_OPTIONAL
+
+
+def is_cnf_var (obj):
+ """
+ Applies if all mandatory fields of a CNF_VAR and no unknown fields are
+ present.
+
+ .. XXX: validate field types.
+ """
+ assert isinstance (obj, dict)
+
+ for f in CNF_FIELD_MANDATORY:
+ if obj.get (f, None) is None:
+ return False
+
+ for f in obj:
+ if f not in CNF_FIELD_KNOWN:
+ return False
+
+ return True
+
+
+def cnf_root (root):
+ """
+ Of a given object, return the cnf root. This may be either a list
+ containing the object itself, if it satisfies the criteria for a CNF_VAR,
+ or the object contained in its toplevel field *cnf*.
+ """
if not isinstance(root, dict):
raise TypeError(
"Expected dictionary of CNF_VARs, got %s." % type(root))
+ if is_cnf_var (root):
+ return [ root ]
cnf = root.get("cnf", None)
if not isinstance(cnf, list):
raise TypeError("Expected list of CNF_VARs, got %s." % type(cnf))