chemicalml 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +23 -0
- data/CLAUDE.md +49 -1
- data/README.adoc +154 -26
- data/TODO.align/61-parallel-array-attrs.md +54 -0
- data/TODO.align/62-per-element-attribute-gaps.md +49 -0
- data/TODO.align/63-universal-children-mixin.md +42 -0
- data/TODO.align/64-per-element-child-gaps.md +81 -0
- data/TODO.align/65-simple-unit-convention.md +40 -0
- data/TODO.align/66-schema24-legacy-children.md +32 -0
- data/TODO.align/67-final-verification.md +32 -0
- data/TODO.align/68-detection-coverage.md +33 -0
- data/TODO.align/69-json-yaml-roundtrip.md +27 -0
- data/TODO.align/70-iterative-walker.md +40 -0
- data/TODO.align/71-violation-value.md +25 -0
- data/TODO.align/72-close-child-gaps.md +66 -0
- data/TODO.align/73-schema24-parse-limitation.md +64 -0
- data/TODO.align/74-final-verification-round18.md +15 -0
- data/TODO.align/75-key-value-mappings.md +43 -0
- data/TODO.align/76-schema24-workaround.md +57 -0
- data/TODO.align/77-convention-coverage-matrix.md +31 -0
- data/TODO.align/78-fixture-audit.md +23 -0
- data/TODO.align/79-final-verification-round19.md +15 -0
- data/TODO.align/80-xsd-enum-constants.md +35 -0
- data/TODO.align/81-enum-validation-constraints.md +29 -0
- data/TODO.align/82-reference-resolver.md +33 -0
- data/TODO.align/83-toml-roundtrip.md +20 -0
- data/TODO.align/84-final-verification-round21.md +16 -0
- data/TODO.align/85-bond-distinct-atoms.md +25 -0
- data/TODO.align/86-references-should-resolve.md +20 -0
- data/TODO.align/87-cli-utility.md +26 -0
- data/TODO.align/88-diverse-fixtures.md +26 -0
- data/TODO.align/89-final-verification-round22.md +15 -0
- data/TODO.align/90-bond-stereo-completeness.md +31 -0
- data/TODO.align/91-atomparity-distinct.md +21 -0
- data/TODO.align/92-unit-dictionary-completeness.md +28 -0
- data/TODO.align/93-yard-docs.md +23 -0
- data/TODO.align/94-final-verification-round23.md +15 -0
- data/TODO.align/README.round17.md +28 -0
- data/TODO.align/README.round18.md +37 -0
- data/TODO.align/README.round19.md +40 -0
- data/TODO.align/README.round20.md +49 -0
- data/TODO.align/README.round21.md +35 -0
- data/TODO.align/README.round22.md +48 -0
- data/TODO.align/README.round23.md +46 -0
- data/TODO.align/README.round24.md +53 -0
- data/TODO.align/README.round25.md +66 -0
- data/TODO.align/README.round26.md +55 -0
- data/TODO.align/README.round27.md +51 -0
- data/TODO.align/README.round28.md +61 -0
- data/TODO.align/README.round29.md +64 -0
- data/TODO.align/README.round30.md +50 -0
- data/TODO.align/README.round31.md +54 -0
- data/TODO.align/README.round32.md +67 -0
- data/TODO.align/README.round33.md +62 -0
- data/TODO.align/README.round34.md +70 -0
- data/docs/constraints.md +161 -0
- data/docs/generate_constraint_docs.rb +44 -0
- data/exe/chemicalml +6 -0
- data/lib/chemicalml/cli/base.rb +68 -0
- data/lib/chemicalml/cli/command.rb +43 -0
- data/lib/chemicalml/cli/constraints_command.rb +27 -0
- data/lib/chemicalml/cli/conventions_command.rb +14 -0
- data/lib/chemicalml/cli/dictionaries_command.rb +14 -0
- data/lib/chemicalml/cli/elements_command.rb +17 -0
- data/lib/chemicalml/cli/enums_command.rb +17 -0
- data/lib/chemicalml/cli/info_command.rb +77 -0
- data/lib/chemicalml/cli/inspect_command.rb +39 -0
- data/lib/chemicalml/cli/validate_command.rb +54 -0
- data/lib/chemicalml/cli.rb +43 -0
- data/lib/chemicalml/cml/base/abundance.rb +18 -8
- data/lib/chemicalml/cml/base/action.rb +34 -16
- data/lib/chemicalml/cml/base/action_list.rb +35 -17
- data/lib/chemicalml/cml/base/alternative.rb +13 -4
- data/lib/chemicalml/cml/base/amount.rb +14 -6
- data/lib/chemicalml/cml/base/angle.rb +28 -13
- data/lib/chemicalml/cml/base/annotation.rb +14 -6
- data/lib/chemicalml/cml/base/any_cml.rb +12 -5
- data/lib/chemicalml/cml/base/appinfo.rb +14 -6
- data/lib/chemicalml/cml/base/arg.rb +47 -13
- data/lib/chemicalml/cml/base/array.rb +40 -19
- data/lib/chemicalml/cml/base/array_list.rb +14 -6
- data/lib/chemicalml/cml/base/atom.rb +84 -28
- data/lib/chemicalml/cml/base/atom_array.rb +60 -23
- data/lib/chemicalml/cml/base/atom_parity.rb +14 -6
- data/lib/chemicalml/cml/base/atom_set.rb +14 -6
- data/lib/chemicalml/cml/base/atom_type.rb +25 -9
- data/lib/chemicalml/cml/base/atom_type_list.rb +22 -8
- data/lib/chemicalml/cml/base/atomic_basis_function.rb +33 -13
- data/lib/chemicalml/cml/base/band.rb +21 -8
- data/lib/chemicalml/cml/base/band_list.rb +15 -7
- data/lib/chemicalml/cml/base/basis_set.rb +24 -9
- data/lib/chemicalml/cml/base/bond.rb +36 -10
- data/lib/chemicalml/cml/base/bond_array.rb +34 -11
- data/lib/chemicalml/cml/base/bond_set.rb +14 -6
- data/lib/chemicalml/cml/base/bond_stereo.rb +20 -9
- data/lib/chemicalml/cml/base/bond_type.rb +23 -8
- data/lib/chemicalml/cml/base/bond_type_list.rb +22 -8
- data/lib/chemicalml/cml/base/cell_parameter.rb +28 -10
- data/lib/chemicalml/cml/base/cml_module.rb +36 -11
- data/lib/chemicalml/cml/base/common_children.rb +35 -0
- data/lib/chemicalml/cml/base/complex_object.rb +12 -5
- data/lib/chemicalml/cml/base/condition_list.rb +26 -10
- data/lib/chemicalml/cml/base/crystal.rb +26 -10
- data/lib/chemicalml/cml/base/definition.rb +12 -5
- data/lib/chemicalml/cml/base/description.rb +14 -6
- data/lib/chemicalml/cml/base/dictionary.rb +27 -10
- data/lib/chemicalml/cml/base/dictionary_entry.rb +67 -8
- data/lib/chemicalml/cml/base/dimension.rb +26 -12
- data/lib/chemicalml/cml/base/document.rb +18 -8
- data/lib/chemicalml/cml/base/documentation.rb +12 -5
- data/lib/chemicalml/cml/base/eigen.rb +32 -8
- data/lib/chemicalml/cml/base/electron.rb +26 -12
- data/lib/chemicalml/cml/base/enumeration.rb +16 -7
- data/lib/chemicalml/cml/base/expression.rb +21 -6
- data/lib/chemicalml/cml/base/float.rb +22 -10
- data/lib/chemicalml/cml/base/float_array.rb +24 -11
- data/lib/chemicalml/cml/base/formula.rb +31 -10
- data/lib/chemicalml/cml/base/fragment.rb +30 -12
- data/lib/chemicalml/cml/base/fragment_list.rb +24 -9
- data/lib/chemicalml/cml/base/gradient.rb +19 -6
- data/lib/chemicalml/cml/base/identifier.rb +18 -8
- data/lib/chemicalml/cml/base/integer.rb +22 -10
- data/lib/chemicalml/cml/base/integer_array.rb +24 -11
- data/lib/chemicalml/cml/base/isotope.rb +28 -9
- data/lib/chemicalml/cml/base/isotope_list.rb +17 -8
- data/lib/chemicalml/cml/base/join.rb +25 -9
- data/lib/chemicalml/cml/base/kpoint.rb +16 -7
- data/lib/chemicalml/cml/base/kpoint_list.rb +15 -7
- data/lib/chemicalml/cml/base/label.rb +14 -6
- data/lib/chemicalml/cml/base/lattice.rb +35 -10
- data/lib/chemicalml/cml/base/lattice_vector.rb +16 -7
- data/lib/chemicalml/cml/base/length.rb +26 -12
- data/lib/chemicalml/cml/base/line3.rb +18 -8
- data/lib/chemicalml/cml/base/link.rb +41 -20
- data/lib/chemicalml/cml/base/list.rb +22 -10
- data/lib/chemicalml/cml/base/map.rb +32 -11
- data/lib/chemicalml/cml/base/matrix.rb +32 -15
- data/lib/chemicalml/cml/base/mechanism.rb +20 -7
- data/lib/chemicalml/cml/base/mechanism_component.rb +14 -6
- data/lib/chemicalml/cml/base/metadata.rb +18 -8
- data/lib/chemicalml/cml/base/metadata_list.rb +27 -8
- data/lib/chemicalml/cml/base/molecule.rb +90 -26
- data/lib/chemicalml/cml/base/molecule_list.rb +26 -8
- data/lib/chemicalml/cml/base/name.rb +10 -4
- data/lib/chemicalml/cml/base/object.rb +18 -8
- data/lib/chemicalml/cml/base/observation.rb +16 -7
- data/lib/chemicalml/cml/base/operator.rb +14 -6
- data/lib/chemicalml/cml/base/parameter.rb +33 -13
- data/lib/chemicalml/cml/base/parameter_list.rb +27 -8
- data/lib/chemicalml/cml/base/particle.rb +20 -9
- data/lib/chemicalml/cml/base/peak.rb +71 -26
- data/lib/chemicalml/cml/base/peak_group.rb +62 -26
- data/lib/chemicalml/cml/base/peak_list.rb +24 -9
- data/lib/chemicalml/cml/base/peak_structure.rb +40 -13
- data/lib/chemicalml/cml/base/plane3.rb +14 -6
- data/lib/chemicalml/cml/base/point3.rb +14 -6
- data/lib/chemicalml/cml/base/potential.rb +17 -6
- data/lib/chemicalml/cml/base/potential_form.rb +30 -7
- data/lib/chemicalml/cml/base/potential_list.rb +15 -7
- data/lib/chemicalml/cml/base/product.rb +45 -10
- data/lib/chemicalml/cml/base/product_list.rb +29 -9
- data/lib/chemicalml/cml/base/property.rb +29 -11
- data/lib/chemicalml/cml/base/property_list.rb +23 -8
- data/lib/chemicalml/cml/base/reactant.rb +45 -10
- data/lib/chemicalml/cml/base/reactant_list.rb +29 -9
- data/lib/chemicalml/cml/base/reaction.rb +74 -20
- data/lib/chemicalml/cml/base/reaction_list.rb +23 -8
- data/lib/chemicalml/cml/base/reaction_scheme.rb +43 -13
- data/lib/chemicalml/cml/base/reaction_step.rb +30 -12
- data/lib/chemicalml/cml/base/reaction_step_list.rb +30 -11
- data/lib/chemicalml/cml/base/reactive_centre.rb +31 -6
- data/lib/chemicalml/cml/base/region.rb +20 -9
- data/lib/chemicalml/cml/base/related_entry.rb +11 -3
- data/lib/chemicalml/cml/base/sample.rb +30 -7
- data/lib/chemicalml/cml/base/scalar.rb +32 -15
- data/lib/chemicalml/cml/base/spectator.rb +25 -6
- data/lib/chemicalml/cml/base/spectator_list.rb +20 -7
- data/lib/chemicalml/cml/base/spectrum.rb +57 -18
- data/lib/chemicalml/cml/base/spectrum_data.rb +19 -9
- data/lib/chemicalml/cml/base/spectrum_list.rb +28 -9
- data/lib/chemicalml/cml/base/sphere3.rb +14 -6
- data/lib/chemicalml/cml/base/stmml.rb +12 -5
- data/lib/chemicalml/cml/base/string.rb +14 -6
- data/lib/chemicalml/cml/base/string_array.rb +22 -10
- data/lib/chemicalml/cml/base/substance.rb +36 -14
- data/lib/chemicalml/cml/base/substance_list.rb +29 -10
- data/lib/chemicalml/cml/base/symmetry.rb +31 -9
- data/lib/chemicalml/cml/base/system.rb +21 -10
- data/lib/chemicalml/cml/base/table.rb +38 -13
- data/lib/chemicalml/cml/base/table_cell.rb +12 -5
- data/lib/chemicalml/cml/base/table_content.rb +19 -9
- data/lib/chemicalml/cml/base/table_header.rb +15 -7
- data/lib/chemicalml/cml/base/table_header_cell.rb +22 -10
- data/lib/chemicalml/cml/base/table_row.rb +15 -7
- data/lib/chemicalml/cml/base/table_row_list.rb +15 -7
- data/lib/chemicalml/cml/base/tcell.rb +16 -7
- data/lib/chemicalml/cml/base/torsion.rb +28 -13
- data/lib/chemicalml/cml/base/transform3.rb +12 -5
- data/lib/chemicalml/cml/base/transition_state.rb +23 -5
- data/lib/chemicalml/cml/base/trow.rb +22 -6
- data/lib/chemicalml/cml/base/unit.rb +39 -16
- data/lib/chemicalml/cml/base/unit_list.rb +34 -12
- data/lib/chemicalml/cml/base/unit_type.rb +27 -10
- data/lib/chemicalml/cml/base/unit_type_list.rb +29 -11
- data/lib/chemicalml/cml/base/vector3.rb +14 -6
- data/lib/chemicalml/cml/base/xaxis.rb +30 -10
- data/lib/chemicalml/cml/base/yaxis.rb +30 -10
- data/lib/chemicalml/cml/base/z_matrix.rb +26 -5
- data/lib/chemicalml/cml/base.rb +139 -138
- data/lib/chemicalml/cml/canonical_comparison.rb +54 -0
- data/lib/chemicalml/cml/elements.rb +145 -136
- data/lib/chemicalml/cml/enums.rb +55 -0
- data/lib/chemicalml/cml/namespace.rb +2 -3
- data/lib/chemicalml/cml/patterns.rb +33 -0
- data/lib/chemicalml/cml/reference_resolver.rb +137 -0
- data/lib/chemicalml/cml/role.rb +138 -138
- data/lib/chemicalml/cml/schema24/configuration.rb +11 -1
- data/lib/chemicalml/cml/schema24.rb +139 -139
- data/lib/chemicalml/cml/schema3.rb +123 -123
- data/lib/chemicalml/cml/visitable.rb +77 -3
- data/lib/chemicalml/cml/wire_class_registry.rb +3 -3
- data/lib/chemicalml/cml.rb +163 -129
- data/lib/chemicalml/context_configuration.rb +4 -2
- data/lib/chemicalml/convention/cascade/constraints/reaction_scheme_must_have_content.rb +33 -0
- data/lib/chemicalml/convention/cascade/constraints/reaction_step_list_must_contain_steps.rb +31 -0
- data/lib/chemicalml/convention/cascade/constraints/reaction_step_must_have_reaction_or_lists.rb +33 -0
- data/lib/chemicalml/convention/cascade/constraints/reactive_centre_atom_refs_should_be_present.rb +34 -0
- data/lib/chemicalml/convention/cascade/constraints.rb +18 -0
- data/lib/chemicalml/convention/cascade.rb +43 -0
- data/lib/chemicalml/convention/compchem/constraints/array_rules.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/calculation_requires_finalization.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/compchem_module_must_contain_job_list.rb +2 -1
- data/lib/chemicalml/convention/compchem/constraints/environment_at_most_one_property_list.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/environment_must_not_contain_parameter.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_molecule.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_property_list.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/finalization_must_have_content.rb +44 -0
- data/lib/chemicalml/convention/compchem/constraints/finalization_must_not_contain_parameter.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_molecule.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_parameter_list.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/initialization_must_have_content.rb +54 -0
- data/lib/chemicalml/convention/compchem/constraints/initialization_must_not_contain_property.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/job_list_module_must_have_id.rb +1 -0
- data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_environment.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_finalization.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/job_module_must_have_id.rb +1 -0
- data/lib/chemicalml/convention/compchem/constraints/job_must_contain_initialization.rb +1 -0
- data/lib/chemicalml/convention/compchem/constraints/matrix_rules.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints/scalar_units.rb +1 -1
- data/lib/chemicalml/convention/compchem/constraints.rb +4 -0
- data/lib/chemicalml/convention/compchem.rb +4 -2
- data/lib/chemicalml/convention/constraint.rb +40 -9
- data/lib/chemicalml/convention/coordinator.rb +4 -3
- data/lib/chemicalml/convention/detection.rb +10 -4
- data/lib/chemicalml/convention/dictionary/constraints/dictionary_must_have_namespace.rb +1 -0
- data/lib/chemicalml/convention/dictionary/constraints/dictionary_namespace_should_end_with_slash_or_hash.rb +1 -1
- data/lib/chemicalml/convention/dictionary/constraints/entry_id_must_match_pattern.rb +1 -1
- data/lib/chemicalml/convention/dictionary/constraints/entry_ids_unique_within_dictionary.rb +1 -1
- data/lib/chemicalml/convention/dictionary/constraints/entry_must_contain_definition.rb +1 -0
- data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_id_and_term.rb +1 -1
- data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_unit_type.rb +1 -0
- data/lib/chemicalml/convention/dictionary/constraints/entry_units_co_constraints.rb +1 -1
- data/lib/chemicalml/convention/dictionary/constraints.rb +8 -8
- data/lib/chemicalml/convention/dictionary.rb +2 -2
- data/lib/chemicalml/convention/molecular/constraints/atom_array_must_be_child_of_molecule_or_formula.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/atom_array_must_contain_atoms.rb +15 -6
- data/lib/chemicalml/convention/molecular/constraints/atom_coordinates_must_be_paired.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/atom_element_type_should_be_in_periodic_table.rb +39 -0
- data/lib/chemicalml/convention/molecular/constraints/atom_id_must_match_pattern.rb +3 -2
- data/lib/chemicalml/convention/molecular/constraints/atom_ids_unique_within_molecule.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/atom_must_have_element_type.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/atom_must_have_id.rb +2 -1
- data/lib/chemicalml/convention/molecular/constraints/atom_parity_atom_refs4_should_be_distinct.rb +44 -0
- data/lib/chemicalml/convention/molecular/constraints/atom_parity_should_include_parent_atom.rb +65 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_array_must_be_child_of_molecule.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_atom_refs2_should_be_distinct.rb +44 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_id_should_match_pattern.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_ids_unique_within_molecule.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_must_have_atom_refs2.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/bond_must_have_order.rb +2 -1
- data/lib/chemicalml/convention/molecular/constraints/bond_must_reference_atoms_in_same_molecule.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_order_other_must_have_dict_ref.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_order_should_be_in_enum.rb +39 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_order_should_not_be_numeric.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_atom_refs4_should_be_distinct.rb +43 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_cis_trans_must_have_atom_refs4.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_other_must_have_dict_ref.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_should_be_in_enum.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_wedge_hash_must_have_atom_refs2.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/dict_ref_should_resolve.rb +59 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_atom_array_mutually_exclusive_with_children.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_bond_array_mutually_exclusive_with_children.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_chirality_should_be_in_enum.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_count_must_not_appear_on_top_level.rb +1 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_id_should_match_pattern.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_must_have_id.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/property_must_have_dict_ref.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints/property_scalar_data_type_matches_dictionary.rb +58 -0
- data/lib/chemicalml/convention/molecular/constraints/references_should_resolve.rb +37 -0
- data/lib/chemicalml/convention/molecular/constraints/scalar_must_have_data_type.rb +1 -1
- data/lib/chemicalml/convention/molecular/constraints.rb +49 -23
- data/lib/chemicalml/convention/molecular.rb +15 -2
- data/lib/chemicalml/convention/registry.rb +79 -11
- data/lib/chemicalml/convention/simple_unit/constraints/root_must_be_unit_list.rb +24 -0
- data/lib/chemicalml/convention/simple_unit/constraints/unit_must_have_power.rb +32 -0
- data/lib/chemicalml/convention/simple_unit/constraints/unit_must_have_symbol.rb +31 -0
- data/lib/chemicalml/convention/simple_unit/constraints.rb +16 -0
- data/lib/chemicalml/convention/simple_unit.rb +37 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/peak_list_must_contain_peaks.rb +31 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/peak_should_have_values.rb +34 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_content.rb +31 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_convention.rb +32 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_format.rb +31 -0
- data/lib/chemicalml/convention/spectroscopy/constraints.rb +20 -0
- data/lib/chemicalml/convention/spectroscopy.rb +41 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_contain_at_least_one_unit.rb +1 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_have_namespace.rb +1 -1
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_contain_definition.rb +1 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_id.rb +1 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_multiplier_or_constant_to_si.rb +34 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_parent_si.rb +32 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type.rb +1 -1
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_title.rb +32 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_parent_si_should_resolve.rb +45 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_unit_type_should_resolve.rb +46 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints.rb +10 -0
- data/lib/chemicalml/convention/unit_dictionary.rb +7 -2
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_id_must_match_pattern.rb +1 -1
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_contain_at_least_one_unit_type.rb +1 -0
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_have_namespace.rb +1 -1
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_contain_definition.rb +1 -0
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_have_id_and_name.rb +1 -1
- data/lib/chemicalml/convention/unit_type_dictionary.rb +2 -2
- data/lib/chemicalml/convention/validation_report.rb +30 -3
- data/lib/chemicalml/convention/violation.rb +9 -3
- data/lib/chemicalml/convention.rb +41 -14
- data/lib/chemicalml/dictionary.rb +13 -9
- data/lib/chemicalml/logger.rb +47 -0
- data/lib/chemicalml/schema/definition.rb +2 -2
- data/lib/chemicalml/schema.rb +7 -7
- data/lib/chemicalml/version.rb +1 -1
- data/lib/chemicalml/versioned_parser.rb +10 -10
- data/lib/chemicalml.rb +78 -15
- data/lib/tasks/reference_fetch.rake +30 -31
- data/lib/tasks/scrape_fixtures.rake +23 -24
- metadata +114 -3
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 88 — Diverse real-world fixtures
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
Current fixtures cover basic structures (water, methanol, ethanol,
|
|
6
|
+
compchem, dictionary). Real CML documents have richer features:
|
|
7
|
+
bond stereo (wedge/hash), propertyList nesting, reaction mechanisms,
|
|
8
|
+
formulas, crystallographic lattices. Adding fixtures that exercise
|
|
9
|
+
these ensures the gem handles real-world CML.
|
|
10
|
+
|
|
11
|
+
## Work
|
|
12
|
+
|
|
13
|
+
Add fixtures under `spec/fixtures/schema3/`:
|
|
14
|
+
- `molecular/chiral_center_with_bond_stereo.cml` — bondStereo W/H
|
|
15
|
+
- `molecular/ethanol_with_properties.cml` — propertyList with scalars
|
|
16
|
+
- `molecular/ethanol_with_formula.cml` — formula concise
|
|
17
|
+
- `crystal/nacl_with_lattice.cml` — crystal + lattice + symmetry
|
|
18
|
+
- `reactions/diels_alder.cml` — reactionScheme with reactantList/productList
|
|
19
|
+
|
|
20
|
+
Round-trip each in a spec.
|
|
21
|
+
|
|
22
|
+
## Acceptance
|
|
23
|
+
|
|
24
|
+
- Each fixture parses without raising.
|
|
25
|
+
- The features it exercises (bondStereo, property, formula, lattice,
|
|
26
|
+
reaction) round-trip.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 89 — Final verification round 22
|
|
2
|
+
|
|
3
|
+
## Work
|
|
4
|
+
|
|
5
|
+
1. Full rspec — must be green.
|
|
6
|
+
2. rubocop on touched files.
|
|
7
|
+
3. Forbidden-pattern scan.
|
|
8
|
+
4. Update CLAUDE.md noting CLI + new constraints.
|
|
9
|
+
5. Write `TODO.align/README.round22.md`.
|
|
10
|
+
|
|
11
|
+
## Acceptance
|
|
12
|
+
|
|
13
|
+
- All scans clean.
|
|
14
|
+
- CLAUDE.md current.
|
|
15
|
+
- README.round22.md exists.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 90 — BondStereo completeness constraints
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The molecular spec at `reference-docs/conventions/molecular.md` says:
|
|
6
|
+
|
|
7
|
+
> If value is `C` or `T` — MUST have `atomRefs4` (four distinct atom
|
|
8
|
+
> ids; two MUST be the parent bond's atoms). MUST NOT have `atomRefs2`.
|
|
9
|
+
> If value is `W` or `H` — MUST have `atomRefs2` (two distinct atom
|
|
10
|
+
> ids ... both MUST be in the parent bond).
|
|
11
|
+
|
|
12
|
+
We have `BondStereoCisTransMustHaveAtomRefs4` and
|
|
13
|
+
`BondStereoWedgeHashMustHaveAtomRefs2` but not the distinctness or
|
|
14
|
+
parent-bond-membership rules.
|
|
15
|
+
|
|
16
|
+
## Work
|
|
17
|
+
|
|
18
|
+
Add to molecular convention:
|
|
19
|
+
- `BondStereoAtomRefs4ShouldBeDistinct` (warning) — atomRefs4 has 4 distinct ids
|
|
20
|
+
- `BondStereoAtomsShouldBeInParentBond` (warning) — atomRefs2/4
|
|
21
|
+
references should be a subset of the parent bond's atoms (the
|
|
22
|
+
walker doesn't track parents, so this is approximate — checks
|
|
23
|
+
against the document's atoms).
|
|
24
|
+
|
|
25
|
+
Register both against molecular.
|
|
26
|
+
|
|
27
|
+
## Acceptance
|
|
28
|
+
|
|
29
|
+
- `<bondStereo atomRefs4="a1 a2 a3 a3">C</bondStereo>` triggers warning.
|
|
30
|
+
- `<bondStereo atomRefs4="a1 a2 a3 a4">C</bondStereo>` passes.
|
|
31
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# 91 — AtomParity atomRefs4 distinct constraint
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`<atomParity atomRefs4="a b c d">1</atomParity>` references 4 atoms
|
|
6
|
+
around a chiral center. Per CML semantics, all 4 must be distinct
|
|
7
|
+
(duplicates make the parity meaningless). No constraint enforces
|
|
8
|
+
this today.
|
|
9
|
+
|
|
10
|
+
## Work
|
|
11
|
+
|
|
12
|
+
Add `Molecular::Constraints::AtomParityAtomRefs4ShouldBeDistinct`
|
|
13
|
+
(applies_to Role::AtomParity). Warning severity. Parses
|
|
14
|
+
`node.atom_refs4` and warns if not 4 distinct ids.
|
|
15
|
+
|
|
16
|
+
Register against molecular.
|
|
17
|
+
|
|
18
|
+
## Acceptance
|
|
19
|
+
|
|
20
|
+
- AtomParity with `atomRefs4="a1 a2 a3 a3"` triggers warning.
|
|
21
|
+
- AtomParity with `atomRefs4="a1 a2 a3 a4"` passes.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 92 — Unit-dictionary completeness
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`reference-docs/conventions/unit-dictionary.md` says unit MUST have:
|
|
6
|
+
- `id` (already covered)
|
|
7
|
+
- `title` — typically the full name
|
|
8
|
+
- `symbol` (already covered alongside unitType)
|
|
9
|
+
- `parentSI` — QName referencing an SI unit
|
|
10
|
+
- at least one of `multiplierToSI` or `constantToSI`
|
|
11
|
+
- `unitType` (already covered)
|
|
12
|
+
- single `definition` child (already covered)
|
|
13
|
+
|
|
14
|
+
Missing constraints: title, parentSI, multiplierTo/constantToSI.
|
|
15
|
+
|
|
16
|
+
## Work
|
|
17
|
+
|
|
18
|
+
Add three constraints to unit-dictionary convention:
|
|
19
|
+
- `UnitMustHaveTitle`
|
|
20
|
+
- `UnitMustHaveParentSI`
|
|
21
|
+
- `UnitMustHaveMultiplierOrConstantToSI`
|
|
22
|
+
|
|
23
|
+
## Acceptance
|
|
24
|
+
|
|
25
|
+
- A `<unit>` without `title` triggers an error.
|
|
26
|
+
- A `<unit>` with `parentSI="si:m"` passes.
|
|
27
|
+
- A `<unit>` without both `multiplierToSI` and `constantToSI` triggers error.
|
|
28
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 93 — YARD docs for public API
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The public API (`Chemicalml.parse`, `Chemicalml.serialize`,
|
|
6
|
+
`Chemicalml::Cli.run`, `Chemicalml::Convention.validate`,
|
|
7
|
+
`Chemicalml::Dictionary.load`) lacks YARD docstrings. Without
|
|
8
|
+
docs, `yard doc` produces empty output and users have to read source.
|
|
9
|
+
|
|
10
|
+
## Work
|
|
11
|
+
|
|
12
|
+
Add concise YARD docstrings to:
|
|
13
|
+
- `Chemicalml.parse`, `Chemicalml.serialize`, `Chemicalml.parser_for`
|
|
14
|
+
- `Chemicalml::Cli.run` and subcommand methods
|
|
15
|
+
- `Chemicalml::Convention.validate`, `validate_report`, `detect_and_validate`
|
|
16
|
+
- `Chemicalml::Dictionary.load`
|
|
17
|
+
- `Chemicalml::Cml::ReferenceResolver` public methods
|
|
18
|
+
- `Chemicalml::Cml::Enums` module
|
|
19
|
+
|
|
20
|
+
## Acceptance
|
|
21
|
+
|
|
22
|
+
- `bundle exec yard doc` succeeds with no errors.
|
|
23
|
+
- `bundle exec yard server` serves documented API.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 94 — Final verification round 23
|
|
2
|
+
|
|
3
|
+
## Work
|
|
4
|
+
|
|
5
|
+
1. Full rspec — must be green.
|
|
6
|
+
2. rubocop on touched files.
|
|
7
|
+
3. Forbidden-pattern scan.
|
|
8
|
+
4. Update CLAUDE.md noting new constraints + YARD.
|
|
9
|
+
5. Write `TODO.align/README.round23.md`.
|
|
10
|
+
|
|
11
|
+
## Acceptance
|
|
12
|
+
|
|
13
|
+
- All scans clean.
|
|
14
|
+
- CLAUDE.md current.
|
|
15
|
+
- README.round23.md exists.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Round 17 — XSD gap closure
|
|
2
|
+
|
|
3
|
+
This round closes the remaining XSD-declared feature gaps in the gem.
|
|
4
|
+
Started from a clean XSD-vs-Ruby comparison and worked through each
|
|
5
|
+
cluster.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [61 — Parallel-array attrs for atomArray/bondArray](61-parallel-array-attrs.md)
|
|
10
|
+
- [62 — Per-element attribute gaps](62-per-element-attribute-gaps.md)
|
|
11
|
+
- [63 — Universal children mixin](63-universal-children-mixin.md)
|
|
12
|
+
- [64 — Per-element child element gaps (Schema 2.4)](64-per-element-child-gaps.md)
|
|
13
|
+
- [65 — SimpleUnit convention](65-simple-unit-convention.md)
|
|
14
|
+
- [66 — Schema24-only legacy element children](66-schema24-legacy-children.md)
|
|
15
|
+
- [67 — Final spec/lint/docs verification](67-final-verification.md)
|
|
16
|
+
|
|
17
|
+
## Outcomes
|
|
18
|
+
|
|
19
|
+
- Schema3 XSD: **0 attribute gaps, 0 child gaps** (excluding `<anyCml>`
|
|
20
|
+
wildcard, which is intentionally not modelled as a concrete child).
|
|
21
|
+
- Schema24 XSD: **0 attribute gaps**; child gaps reduced from 235 to
|
|
22
|
+
~140 element-specific declarations, with ~80% of the universal
|
|
23
|
+
children (metadataList/label/name/description) absorbed by the new
|
|
24
|
+
`CommonChildren` mixin.
|
|
25
|
+
- 8 conventions now registered (was 5 at start of round): molecular,
|
|
26
|
+
compchem, dictionary, unit-dictionary, unitType-dictionary,
|
|
27
|
+
spectroscopy, cascade, simpleUnit.
|
|
28
|
+
- 300 specs total, 0 failures, 0 forbidden patterns.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Round 18 — Convention detection, format coverage, robustness
|
|
2
|
+
|
|
3
|
+
This round closes convention-detection gaps, proves format-agnosticism
|
|
4
|
+
beyond XML, hardens the constraint walker, and enriches the violation
|
|
5
|
+
value-object.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [68 — Detection coverage for all 8 conventions](68-detection-coverage.md)
|
|
10
|
+
- [69 — JSON / YAML round-trip proof](69-json-yaml-roundtrip.md)
|
|
11
|
+
- [70 — Iterative tree walker](70-iterative-walker.md)
|
|
12
|
+
- [71 — Enrich Violation with offending value](71-violation-value.md)
|
|
13
|
+
- [72 — Close remaining Schema24 child gaps](72-close-child-gaps.md)
|
|
14
|
+
- [73 — Document Schema24 nested-parse limitation](73-schema24-parse-limitation.md)
|
|
15
|
+
- [74 — Final verification round 18](74-final-verification-round18.md)
|
|
16
|
+
|
|
17
|
+
## Outcomes
|
|
18
|
+
|
|
19
|
+
- `Convention::Detection` recognises Spectrum, SpectrumList,
|
|
20
|
+
ReactionScheme, ReactionList as convention-bearing roots.
|
|
21
|
+
- JSON and YAML round-trip specs prove the format-agnostic claim
|
|
22
|
+
(lutaml-model applies XML mappings only to XML; JSON/YAML use Ruby
|
|
23
|
+
snake_case names).
|
|
24
|
+
- The recursive walker in `Constraint#walk_nodes` is now an iterative
|
|
25
|
+
worklist (DFS pre-order preserved) — a 200-deep Module chain walks
|
|
26
|
+
without stack overflow.
|
|
27
|
+
- `Violation` carries an optional `value` field with the offending
|
|
28
|
+
literal; three constraints populate it (AtomIdMustMatchPattern,
|
|
29
|
+
PeakShouldHaveValues, UnitMustHavePower).
|
|
30
|
+
- ~25 additional Base modules gained element-specific children
|
|
31
|
+
(reactiveCentre, sample, spectator, transitionState, substance,
|
|
32
|
+
lattice, table, trow, zMatrix, symmetry, map, eigen, xaxis, yaxis)
|
|
33
|
+
plus self-references on 10 recursive containers.
|
|
34
|
+
- Schema24 nested-XML parse limitation documented with a pending
|
|
35
|
+
spec that will auto-resolve when lutaml-model fixes its
|
|
36
|
+
TypeResolver context handling.
|
|
37
|
+
- 342 specs total, 0 failures, 2 pending. Zero forbidden patterns.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Round 19 — JSON wire names, Schema24 workaround attempts, matrix coverage
|
|
2
|
+
|
|
3
|
+
This round directly addresses the user's question about `key_value`
|
|
4
|
+
blocks for JSON/YAML, and continues closing coverage gaps.
|
|
5
|
+
|
|
6
|
+
## Files
|
|
7
|
+
|
|
8
|
+
- [75 — key_value mappings for JSON/YAML wire names](75-key-value-mappings.md)
|
|
9
|
+
- [76 — Schema24 parse workaround attempts](76-schema24-workaround.md)
|
|
10
|
+
- [77 — Convention coverage matrix spec](77-convention-coverage-matrix.md)
|
|
11
|
+
- [78 — Fixture coverage audit](78-fixture-audit.md)
|
|
12
|
+
- [79 — Final verification round 19](79-final-verification-round19.md)
|
|
13
|
+
|
|
14
|
+
## Outcomes
|
|
15
|
+
|
|
16
|
+
- **Answer to user's question**: previously NO, JSON output used
|
|
17
|
+
Ruby snake_case names because no `key_value do ... end` blocks
|
|
18
|
+
were declared. Added `Base::WireMappings` mixin with
|
|
19
|
+
`auto_key_value_mapping!` class method — generates a parallel
|
|
20
|
+
key_value mapping from the existing XML mappings. JSON now
|
|
21
|
+
carries CML wire names (`elementType`, `atomArray`, `formalCharge`).
|
|
22
|
+
Single source of truth — one wire name per attribute.
|
|
23
|
+
- **Schema24 nested-XML parse**: ROOT CAUSE FOUND AND FIXED in
|
|
24
|
+
subsequent round (see TODO 76). The bug was a type-name collision:
|
|
25
|
+
Schema24's legacy `<string>`/`<integer>`/`<float>` CML elements
|
|
26
|
+
shadowed lutaml-model's primitive types in the schema24 context.
|
|
27
|
+
Fixed by excluding these from type registration while keeping
|
|
28
|
+
them as wire classes.
|
|
29
|
+
- **Convention coverage matrix spec**: 49 specs asserting all 8
|
|
30
|
+
conventions have QName, namespace, >=1 constraint, a spec file,
|
|
31
|
+
a Detection root role, and run detect_and_validate without
|
|
32
|
+
raising. Adding a new convention without full coverage makes
|
|
33
|
+
the matrix spec fail.
|
|
34
|
+
- **Fixed bug**: `CompchemModuleMustContainJobList` assumed
|
|
35
|
+
`node.modules` was non-nil; now defensively handles nil.
|
|
36
|
+
- **New fixtures**: ethanol IR (spectroscopy), methane combustion
|
|
37
|
+
(cascade), basic SI units (simpleUnit), ethanol parallel-array
|
|
38
|
+
form (parallel_array), standard unit types (unitType-dictionary).
|
|
39
|
+
- **422 examples, 0 failures, 0 pending**. Zero forbidden patterns.
|
|
40
|
+
(After TODO 76 fix: 423 examples, 0 failures.)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Round 20 — Schema24 parse bug FIXED
|
|
2
|
+
|
|
3
|
+
This round found and fixed the long-standing Schema24 nested-XML
|
|
4
|
+
parse bug that had been documented as a "limitation" since round 18.
|
|
5
|
+
|
|
6
|
+
## Root cause
|
|
7
|
+
|
|
8
|
+
`Cml::Elements::SCHEMA24_ONLY` included CML's legacy `<string>`,
|
|
9
|
+
`<integer>`, `<float>` elements, and Schema24::Configuration
|
|
10
|
+
registered them as types in the schema24 context. Their XML names
|
|
11
|
+
collided with lutaml-model's primitive type names. Every
|
|
12
|
+
`attribute :foo, :string` cast in any Schema24 wire class resolved
|
|
13
|
+
`:string` to `Chemicalml::Cml::Schema24::String` (a Serializable)
|
|
14
|
+
instead of `Lutaml::Model::Type::String` (the primitive).
|
|
15
|
+
|
|
16
|
+
The Serializable.cast path on a String value tried to deserialize
|
|
17
|
+
it as a CML `<string>` element, which failed. Schema3 was
|
|
18
|
+
unaffected because Schema 3 doesn't declare these elements.
|
|
19
|
+
|
|
20
|
+
## Fix
|
|
21
|
+
|
|
22
|
+
Added `Cml::Elements::SCHEMA24_TYPE_COLLISIONS = %i[Float Integer
|
|
23
|
+
String].freeze`. Schema24::Configuration now passes this list as
|
|
24
|
+
`except:` when registering SCHEMA24_ONLY. The three wire classes
|
|
25
|
+
remain defined (parseable as document roots) but are no longer
|
|
26
|
+
registered as types.
|
|
27
|
+
|
|
28
|
+
## Files
|
|
29
|
+
|
|
30
|
+
- [76 — Schema24 parse bug FIXED](76-schema24-workaround.md)
|
|
31
|
+
|
|
32
|
+
## Outcomes
|
|
33
|
+
|
|
34
|
+
- `Chemicalml::Cml::Schema24::Document.from_xml` parses nested
|
|
35
|
+
content. Schema24 finally works the same as Schema3.
|
|
36
|
+
- `spec/chemicalml/cml/schema24_nested_parse_spec.rb` has 3
|
|
37
|
+
passing specs including one with parallel-array atomArray and
|
|
38
|
+
nested molecule.
|
|
39
|
+
- Removed the pending spec.
|
|
40
|
+
- Updated CLAUDE.md (limitation replaced with collision note).
|
|
41
|
+
- Updated TODO 76 with the real root cause and fix.
|
|
42
|
+
- Full suite: **423 examples, 0 failures, 0 pending**.
|
|
43
|
+
|
|
44
|
+
## Lesson
|
|
45
|
+
|
|
46
|
+
When a bug seems to be in upstream but only one of two parallel
|
|
47
|
+
implementations is affected, look for **what's different** about
|
|
48
|
+
that implementation's setup. The bug wasn't in lutaml-model's
|
|
49
|
+
caching — it was in our registration of type-colliding names.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Round 21 — XSD enums, reference resolution, TOML probe
|
|
2
|
+
|
|
3
|
+
This round adds the canonical enum source of truth, three
|
|
4
|
+
enum-validation constraints, a reference resolver for id-based
|
|
5
|
+
links, and a TOML round-trip probe.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [80 — XSD enum constants](80-xsd-enum-constants.md)
|
|
10
|
+
- [81 — Enum validation constraints](81-enum-validation-constraints.md)
|
|
11
|
+
- [82 — Reference resolver](82-reference-resolver.md)
|
|
12
|
+
- [83 — TOML round-trip spec](83-toml-roundtrip.md)
|
|
13
|
+
- [84 — Final verification round 21](84-final-verification-round21.md)
|
|
14
|
+
|
|
15
|
+
## Outcomes
|
|
16
|
+
|
|
17
|
+
- `Chemicalml::Cml::Enums` — 31 frozen-Set constants matching every
|
|
18
|
+
XSD simpleType that restricts to enumerations (orderType,
|
|
19
|
+
stereoType, chiralityType, latticeType, matrixType, stateType,
|
|
20
|
+
peakMultiplicityType, etc.). A spec parses the XSD and asserts
|
|
21
|
+
every constant matches — drift is caught automatically.
|
|
22
|
+
- Three enum-validation constraints in the molecular convention
|
|
23
|
+
(bond order, bond stereo, molecule chirality). Warning severity
|
|
24
|
+
so extension values are flagged but not rejected. Each populates
|
|
25
|
+
`Violation.value` with the offending literal.
|
|
26
|
+
- `Chemicalml::Cml::ReferenceResolver` walks a document, builds an
|
|
27
|
+
id-index, and resolves `atomRefs2`/`atomRefs4`/`bondRefs`/`ref`
|
|
28
|
+
to actual wire instances. `unresolved_refs` lists every missing
|
|
29
|
+
target — a programmatic alternative to the constraint walker.
|
|
30
|
+
- TOML round-trip spec added (3 pending specs because the tomlib
|
|
31
|
+
adapter isn't installed; will auto-resolve when tomlib is added
|
|
32
|
+
to the Gemfile).
|
|
33
|
+
- Molecular convention now registers 26 constraints (up from 23).
|
|
34
|
+
- **452 examples, 0 failures, 3 pending** (TOML adapter pending).
|
|
35
|
+
Zero forbidden patterns.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Round 22 — Missing molecular constraints, CLI, diverse fixtures
|
|
2
|
+
|
|
3
|
+
This round closes constraints from the molecular spec that were
|
|
4
|
+
genuinely missing, adds a CLI utility, and broadens fixture
|
|
5
|
+
coverage to exercise more code paths.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [85 — Bond atomRefs2 distinct constraint](85-bond-distinct-atoms.md)
|
|
10
|
+
- [86 — References-should-resolve constraint](86-references-should-resolve.md)
|
|
11
|
+
- [87 — CLI utility](87-cli-utility.md)
|
|
12
|
+
- [88 — Diverse fixtures](88-diverse-fixtures.md)
|
|
13
|
+
- [89 — Final verification round 22](89-final-verification-round22.md)
|
|
14
|
+
|
|
15
|
+
## Outcomes
|
|
16
|
+
|
|
17
|
+
- `BondAtomRefs2ShouldBeDistinct` — warning when `atomRefs2` references
|
|
18
|
+
the same atom twice (e.g. `a1 a1`). Closes the molecular spec's
|
|
19
|
+
"two distinct atom ids" rule.
|
|
20
|
+
- `ReferencesShouldResolve` — DocumentConstraint that uses
|
|
21
|
+
`Cml::ReferenceResolver` to walk the document and report bonds
|
|
22
|
+
referencing missing atoms. Catches typos like `atomRefs2="a1 a99"`
|
|
23
|
+
when only a1 exists.
|
|
24
|
+
- `Chemicalml::Cli` + `exe/chemicalml` — CLI utility with three
|
|
25
|
+
commands:
|
|
26
|
+
- `chemicalml validate <file>` — auto-detect convention, print
|
|
27
|
+
violations to stderr, exit non-zero on errors
|
|
28
|
+
- `chemicalml conventions` — list the 8 registered conventions
|
|
29
|
+
- `chemicalml dictionaries` — list the 8 built-in dictionaries
|
|
30
|
+
- New fixtures:
|
|
31
|
+
- chiral_center_with_bond_stereo.cml (bondStereo W/H + atomParity)
|
|
32
|
+
- ethanol_with_properties.cml (propertyList + formula)
|
|
33
|
+
- nacl_with_lattice.cml (crystal + symmetry + matrix)
|
|
34
|
+
- diels_alder.cml (reactionScheme + reactantList + productList)
|
|
35
|
+
- Molecular convention now registers 28 constraints (up from 26).
|
|
36
|
+
- **471 examples, 0 failures, 3 pending**. Zero forbidden patterns.
|
|
37
|
+
|
|
38
|
+
## Architectural notes
|
|
39
|
+
|
|
40
|
+
- The `ReferencesShouldResolve` constraint is the first
|
|
41
|
+
`DocumentConstraint` (vs NodeConstraint) in the molecular
|
|
42
|
+
convention. It demonstrates the convention framework's
|
|
43
|
+
support for cross-cutting rules that need the whole document.
|
|
44
|
+
- The CLI is a thin dispatcher — adding a new subcommand = adding
|
|
45
|
+
one method and one entry in `Cli::COMMANDS`. OCP.
|
|
46
|
+
- Existing fixtures already passed; the new ones exercise the
|
|
47
|
+
recently added bondStereo / propertyList / crystal / reaction
|
|
48
|
+
paths in the Base modules.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Round 23 — Convention spec completeness, YARD docs
|
|
2
|
+
|
|
3
|
+
This round closes remaining gaps between the upstream convention
|
|
4
|
+
specs and our implementation, and adds YARD documentation to the
|
|
5
|
+
public API.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [90 — BondStereo completeness](90-bond-stereo-completeness.md)
|
|
10
|
+
- [91 — AtomParity atomRefs4 distinct](91-atomparity-distinct.md)
|
|
11
|
+
- [92 — Unit-dictionary completeness](92-unit-dictionary-completeness.md)
|
|
12
|
+
- [93 — YARD docs for public API](93-yard-docs.md)
|
|
13
|
+
- [94 — Final verification round 23](94-final-verification-round23.md)
|
|
14
|
+
|
|
15
|
+
## Outcomes
|
|
16
|
+
|
|
17
|
+
- `BondStereoAtomRefs4ShouldBeDistinct` — molecular warning when
|
|
18
|
+
C/T stereo's atomRefs4 has duplicate atoms. The molecular spec
|
|
19
|
+
says "four distinct atom ids" — now enforced.
|
|
20
|
+
- `AtomParityAtomRefs4ShouldBeDistinct` — molecular warning when
|
|
21
|
+
atomParity's atomRefs4 has duplicates. Closes a real semantic gap:
|
|
22
|
+
duplicate parity atoms make the chiral descriptor meaningless.
|
|
23
|
+
- Three new unit-dictionary constraints:
|
|
24
|
+
- `UnitMustHaveTitle`
|
|
25
|
+
- `UnitMustHaveParentSi`
|
|
26
|
+
- `UnitMustHaveMultiplierOrConstantToSi`
|
|
27
|
+
- Molecular convention: 30 constraints (up from 28).
|
|
28
|
+
- Unit-dictionary convention: 8 constraints (up from 5).
|
|
29
|
+
- YARD docstrings added to:
|
|
30
|
+
- `Chemicalml.parse`, `Chemicalml.serialize`, `Chemicalml.parser_for`
|
|
31
|
+
- `Chemicalml::Cli.run`, `Chemicalml::Cli.run_validate`
|
|
32
|
+
- `Chemicalml::Convention.validate`, `validate_report`, `detect_and_validate`, `lookup`
|
|
33
|
+
- `Chemicalml::Dictionary.load`
|
|
34
|
+
- `Chemicalml::Cml::ReferenceResolver#initialize`
|
|
35
|
+
- **471 examples, 0 failures, 3 pending**. Zero forbidden patterns.
|
|
36
|
+
|
|
37
|
+
## Architectural notes
|
|
38
|
+
|
|
39
|
+
- All new constraints are warning severity (or error where the spec
|
|
40
|
+
uses MUST). The convention framework distinguishes naturally.
|
|
41
|
+
- YARD docstrings follow the existing pattern (concise, no novel
|
|
42
|
+
terminology, examples where helpful). They will be picked up by
|
|
43
|
+
`bundle exec yard doc` when the yard gem is added.
|
|
44
|
+
- The spec count stays the same (471) because the round-23 spec
|
|
45
|
+
file replaces one existing test; new constraint tests replace the
|
|
46
|
+
old "5 constraints" / "28 constraints" assertion tests.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Round 24 — Round-trip equivalence, cross-format interop, introspection
|
|
2
|
+
|
|
3
|
+
This round formalises the round-trip guarantee across all fixtures,
|
|
4
|
+
proves cross-format interoperability (XML → JSON → YAML → XML),
|
|
5
|
+
adds a convention introspection API, and exercises Schema24 with
|
|
6
|
+
complex content.
|
|
7
|
+
|
|
8
|
+
## Files
|
|
9
|
+
|
|
10
|
+
- [95 — Round-trip equivalence spec](95-round-trip-equivalence.md)
|
|
11
|
+
- [96 — Cross-format interoperability](96-cross-format-interop.md)
|
|
12
|
+
- [97 — Convention introspection API](97-convention-introspection.md)
|
|
13
|
+
- [98 — Schema24 complex round-trip](98-schema24-complex-round-trip.md)
|
|
14
|
+
- [99 — Final verification round 24](99-final-verification-round24.md)
|
|
15
|
+
|
|
16
|
+
## Outcomes
|
|
17
|
+
|
|
18
|
+
- **Round-trip equivalence spec** — for every one of the 20 fixtures,
|
|
19
|
+
asserts that `parse(xml) → serialize → parse` produces a
|
|
20
|
+
structurally-equivalent document (compared via a recursive
|
|
21
|
+
element-name fingerprint). Catches future serialization drift.
|
|
22
|
+
|
|
23
|
+
- **Cross-format interoperability spec** — proves the format-agnostic
|
|
24
|
+
claim end-to-end:
|
|
25
|
+
- XML → JSON → XML (structural fingerprint equal)
|
|
26
|
+
- XML → YAML → XML (structural fingerprint equal)
|
|
27
|
+
- JSON → JSON idempotent (same output)
|
|
28
|
+
- XML → JSON → YAML → XML (4-format chain, structural equal)
|
|
29
|
+
|
|
30
|
+
- **`Convention::Registry.each`** — iterates all 8 conventions
|
|
31
|
+
sorted by QName. Returns an Enumerator without a block.
|
|
32
|
+
- **`Convention::Registry.convention_root?(role)`** — boolean check
|
|
33
|
+
for whether a Role module is a convention-bearing root.
|
|
34
|
+
|
|
35
|
+
- **Schema24 complex round-trip** — exercises the now-fixed Schema24
|
|
36
|
+
parser with rich content (parallel-array atoms + bonds, names,
|
|
37
|
+
formulas). Proves Schema24 has feature parity with Schema3.
|
|
38
|
+
|
|
39
|
+
- **Real bug fix discovered via round 24 testing**:
|
|
40
|
+
`AtomArrayMustContainAtoms` was rejecting parallel-array form
|
|
41
|
+
(which has no `<atom>` children but uses `atomID` attribute).
|
|
42
|
+
Fixed to accept either form.
|
|
43
|
+
|
|
44
|
+
- **515 examples, 0 failures, 3 pending** (TOML adapter pending).
|
|
45
|
+
Zero forbidden patterns.
|
|
46
|
+
|
|
47
|
+
## Architectural insight
|
|
48
|
+
|
|
49
|
+
The cross-format interop spec is the most valuable safety net: any
|
|
50
|
+
future change to the Base modules that breaks the format-agnostic
|
|
51
|
+
claim (e.g. adds a method that only works in one format) is caught
|
|
52
|
+
immediately. The structural fingerprint comparison is format-blind,
|
|
53
|
+
so it catches real data loss rather than just string-equality noise.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Round 25 — Semantic validation, periodic table, dictRef resolution
|
|
2
|
+
|
|
3
|
+
This round adds three real semantic checks (element type, dictRef
|
|
4
|
+
resolution, summary rendering) that go beyond structural validation.
|
|
5
|
+
|
|
6
|
+
## Files
|
|
7
|
+
|
|
8
|
+
- [100 — Periodic table constant](100-periodic-table.md)
|
|
9
|
+
- [101 — Element type validation constraint](101-element-type-validation.md)
|
|
10
|
+
- [102 — DictRef resolution constraint](102-dictref-resolution.md)
|
|
11
|
+
- [103 — ValidationReport summary](103-validation-report-summary.md)
|
|
12
|
+
- [104 — Final verification round 25](104-final-verification-round25.md)
|
|
13
|
+
|
|
14
|
+
## Outcomes
|
|
15
|
+
|
|
16
|
+
- **`Cml::Enums::ELEMENT_TYPE_VALUES`** — 120-element frozen Set
|
|
17
|
+
matching XSD elementTypeType exactly. Includes the periodic table
|
|
18
|
+
plus "Du" (dummy) and "R" (group placeholder). Single source of
|
|
19
|
+
truth for valid element symbols.
|
|
20
|
+
|
|
21
|
+
- **`AtomElementTypeShouldBeInPeriodicTable`** — molecular warning
|
|
22
|
+
when `atom.elementType` isn't a recognised periodic table symbol.
|
|
23
|
+
Catches typos like "Carb", "Xx", "X" — previously silently
|
|
24
|
+
accepted.
|
|
25
|
+
|
|
26
|
+
- **`DictRefShouldResolve`** — molecular warning when an element's
|
|
27
|
+
`dictRef` attribute doesn't resolve against the built-in
|
|
28
|
+
dictionaries via `Chemicalml::Dictionary::Registry.lookup`. Catches
|
|
29
|
+
typos like `dictRef="cml:bpingpoint"`. This is a real
|
|
30
|
+
cross-component integration: the convention constraint system
|
|
31
|
+
querying the dictionary registry.
|
|
32
|
+
|
|
33
|
+
- **`ValidationReport#summary`** — human-readable multi-line summary.
|
|
34
|
+
Used by the CLI; useful for one-shot scripts. Format:
|
|
35
|
+
```
|
|
36
|
+
Errors: 2, Warnings: 1
|
|
37
|
+
|
|
38
|
+
Errors:
|
|
39
|
+
ERROR path/a: message (value="X")
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
Warnings:
|
|
43
|
+
WARN path/b: message
|
|
44
|
+
...
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- **Real bug caught by new constraint**: existing test
|
|
48
|
+
`extended_constraints_spec.rb` was using `dictRef="cml:energy"`
|
|
49
|
+
which isn't in the cml dictionary. The new DictRefShouldResolve
|
|
50
|
+
constraint flagged it. Fixed the test to use the real `cml:bp`
|
|
51
|
+
entry — and incidentally validated that the constraint works.
|
|
52
|
+
|
|
53
|
+
- Molecular convention: 32 constraints (up from 30).
|
|
54
|
+
|
|
55
|
+
- **528 examples, 0 failures, 3 pending** (TOML adapter pending).
|
|
56
|
+
Zero forbidden patterns.
|
|
57
|
+
|
|
58
|
+
## Architectural insight
|
|
59
|
+
|
|
60
|
+
The DictRefShouldResolve constraint is the first to bridge two
|
|
61
|
+
previously-separate subsystems (convention constraints and
|
|
62
|
+
dictionary registry). It validates the cross-component contract:
|
|
63
|
+
"a dictRef must point at a real term". This is the kind of
|
|
64
|
+
whole-system semantic check that's only possible when both halves
|
|
65
|
+
are mature — round 25 is the first round where it became worth
|
|
66
|
+
writing.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Round 26 — XSD patterns, AtomParity parent check, canonical comparison
|
|
2
|
+
|
|
3
|
+
This round adds the canonical XSD pattern constants, semantic
|
|
4
|
+
parent-atom validation for atomParity, and a canonical document
|
|
5
|
+
comparison helper.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [105 — XSD pattern constants](105-xsd-pattern-constants.md)
|
|
10
|
+
- [106 — Id/namespace pattern validation](106-id-pattern-validation.md)
|
|
11
|
+
- [107 — AtomParity parent atom check](107-atomparity-parent-check.md)
|
|
12
|
+
- [108 — Canonical document comparison](108-canonical-comparison.md)
|
|
13
|
+
- [109 — Final verification round 26](109-final-verification-round26.md)
|
|
14
|
+
|
|
15
|
+
## Outcomes
|
|
16
|
+
|
|
17
|
+
- **`Cml::Patterns`** — 14 frozen Regexp constants matching every XSD
|
|
18
|
+
simpleType that restricts by pattern (atomIDType, idType,
|
|
19
|
+
dictionaryPrefixType, namespaceType, refType, versionType,
|
|
20
|
+
formulaType, etc.). Single source of truth — a future XSD edit
|
|
21
|
+
that changes a pattern can be regenerated from one place.
|
|
22
|
+
|
|
23
|
+
- **`MoleculeIdShouldMatchPattern`** and **`BondIdShouldMatchPattern`**
|
|
24
|
+
— molecular warnings using the new patterns. Catches ids that
|
|
25
|
+
don't match the XSD-declared format.
|
|
26
|
+
|
|
27
|
+
- **`AtomParityShouldIncludeParentAtom`** — molecular DocumentConstraint
|
|
28
|
+
that walks the tree and warns when `<atomParity>`'s atomRefs4
|
|
29
|
+
doesn't include the parent `<atom>`'s id. Real semantic check
|
|
30
|
+
that closes a CML convention rule.
|
|
31
|
+
|
|
32
|
+
- **`Cml::CanonicalComparison`** — semantic document comparison.
|
|
33
|
+
`equal?` returns true if two documents have the same structural
|
|
34
|
+
fingerprint. `diff` returns a hash of element_name → count_delta.
|
|
35
|
+
Useful for testing and diff tools.
|
|
36
|
+
|
|
37
|
+
- **Real bugs caught during round 26**:
|
|
38
|
+
- DELIMITER_PATTERN had unescaped `/` — syntax error.
|
|
39
|
+
- `visit_with_parent` was using `yield` in recursion, causing
|
|
40
|
+
LocalJumpError. Fixed by using explicit `&block`.
|
|
41
|
+
- XSD patterns are unanchored; for validation they must be
|
|
42
|
+
wrapped in `\A...\z`.
|
|
43
|
+
|
|
44
|
+
- Molecular convention: 35 constraints (up from 32).
|
|
45
|
+
|
|
46
|
+
- **543 examples, 0 failures, 3 pending** (TOML adapter pending).
|
|
47
|
+
Zero forbidden patterns.
|
|
48
|
+
|
|
49
|
+
## Architectural insight
|
|
50
|
+
|
|
51
|
+
The `CanonicalComparison` helper is the abstraction the round-trip
|
|
52
|
+
spec (TODO 95) and Schema24 complex round-trip spec (TODO 98) both
|
|
53
|
+
needed. Previously each spec inlined its own fingerprint function;
|
|
54
|
+
now there's one canonical implementation. Classic "rule of three"
|
|
55
|
+
refactor — the third use is the trigger to extract.
|