eyeling 1.34.3 → 1.34.5
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.
- package/README.md +7 -9
- package/docs/eyelang-guide.md +6 -11
- package/docs/eyelang-language-reference.md +47 -36
- package/examples/eyelang/bayes-therapy.pl +4 -4
- package/examples/eyelang/output/reusable-builtins.pl +5 -0
- package/examples/eyelang/output/term-tools.pl +6 -0
- package/examples/eyelang/reusable-builtins.pl +32 -0
- package/examples/eyelang/term-tools.pl +23 -0
- package/lib/eyelang/builtins/arithmetic.js +19 -6
- package/lib/eyelang/builtins/control.js +12 -0
- package/lib/eyelang/builtins/lists.js +146 -7
- package/lib/eyelang/builtins/registry.js +2 -3
- package/lib/eyelang/builtins/strings.js +165 -1
- package/lib/eyelang/builtins/terms.js +66 -0
- package/package.json +1 -1
- package/test/eyelang/conformance/README.md +9 -11
- package/test/eyelang/conformance/cases/001_fact_output.pl +4 -0
- package/test/eyelang/conformance/cases/002_rule_recursion.pl +7 -0
- package/test/eyelang/conformance/cases/002_rule_recursion.query +1 -0
- package/test/eyelang/conformance/cases/003_terms_and_readback.pl +16 -0
- package/test/eyelang/conformance/cases/003_terms_and_readback.query +1 -0
- package/test/eyelang/conformance/cases/004_conjunction_and_parentheses.pl +5 -0
- package/test/eyelang/conformance/cases/004_conjunction_and_parentheses.query +1 -0
- package/test/eyelang/conformance/cases/005_list_deconstruction.pl +6 -0
- package/test/eyelang/conformance/cases/005_list_deconstruction.query +1 -0
- package/test/eyelang/conformance/cases/006_comma_formula_data.pl +4 -0
- package/test/eyelang/conformance/cases/006_comma_formula_data.query +1 -0
- package/test/eyelang/conformance/cases/007_anonymous_variables.pl +5 -0
- package/test/eyelang/conformance/cases/007_anonymous_variables.query +1 -0
- package/test/eyelang/conformance/cases/008_graphic_atoms.pl +6 -0
- package/test/eyelang/conformance/cases/008_graphic_atoms.query +1 -0
- package/test/eyelang/conformance/cases/009_comments_and_whitespace.pl +5 -0
- package/test/eyelang/conformance/cases/009_comments_and_whitespace.query +1 -0
- package/test/eyelang/conformance/cases/010_variable_scope_and_reuse.pl +8 -0
- package/test/eyelang/conformance/cases/010_variable_scope_and_reuse.query +1 -0
- package/test/eyelang/conformance/cases/011_predicate_arity.pl +6 -0
- package/test/eyelang/conformance/cases/011_predicate_arity.query +1 -0
- package/test/eyelang/conformance/cases/012_nested_compound_unification.pl +5 -0
- package/test/eyelang/conformance/cases/012_nested_compound_unification.query +1 -0
- package/test/eyelang/conformance/cases/013_multiple_clauses_order.pl +6 -0
- package/test/eyelang/conformance/cases/013_multiple_clauses_order.query +1 -0
- package/test/eyelang/conformance/cases/014_failure_filters_answers.pl +7 -0
- package/test/eyelang/conformance/cases/014_failure_filters_answers.query +1 -0
- package/test/eyelang/conformance/cases/015_improper_list_unification.pl +6 -0
- package/test/eyelang/conformance/cases/015_improper_list_unification.query +1 -0
- package/test/eyelang/conformance/cases/016_zero_arity_compound.pl +4 -0
- package/test/eyelang/conformance/cases/016_zero_arity_compound.query +1 -0
- package/test/eyelang/conformance/cases/017_three_step_recursion.pl +8 -0
- package/test/eyelang/conformance/cases/017_three_step_recursion.query +1 -0
- package/test/eyelang/conformance/cases/018_quoted_atom_readback.pl +6 -0
- package/test/eyelang/conformance/cases/018_quoted_atom_readback.query +1 -0
- package/test/eyelang/conformance/cases/019_parenthesized_three_conjuncts.pl +7 -0
- package/test/eyelang/conformance/cases/019_parenthesized_three_conjuncts.query +1 -0
- package/test/eyelang/conformance/cases/020_nested_list_terms.pl +5 -0
- package/test/eyelang/conformance/cases/020_nested_list_terms.query +1 -0
- package/test/eyelang/conformance/cases/021_repeated_variable_head.pl +7 -0
- package/test/eyelang/conformance/cases/022_rule_head_structure.pl +5 -0
- package/test/eyelang/conformance/cases/023_quoted_escapes_readback.pl +5 -0
- package/test/eyelang/conformance/cases/024_numeric_literal_readback.pl +6 -0
- package/test/eyelang/conformance/cases/025_body_parentheses_with_formula_data.pl +5 -0
- package/test/eyelang/conformance/cases/026_underscore_named_variable_reuse.pl +5 -0
- package/test/eyelang/conformance/cases/027_default_derived_output.pl +5 -0
- package/test/eyelang/conformance/cases/028_materialize_focus.pl +5 -0
- package/test/eyelang/conformance/cases/029_arithmetic_and_comparison.pl +11 -0
- package/test/eyelang/conformance/cases/029_arithmetic_and_comparison.query +1 -0
- package/test/eyelang/conformance/cases/030_strings_and_atoms.pl +4 -0
- package/test/eyelang/conformance/cases/030_strings_and_atoms.query +1 -0
- package/test/eyelang/conformance/cases/031_lists_aggregation_ordering.pl +10 -0
- package/test/eyelang/conformance/cases/031_lists_aggregation_ordering.query +1 -0
- package/test/eyelang/conformance/cases/032_holds_parts.pl +4 -0
- package/test/eyelang/conformance/cases/033_negation_once_generators.pl +7 -0
- package/test/eyelang/conformance/cases/033_negation_once_generators.query +1 -0
- package/test/eyelang/conformance/cases/034_equality_and_inequality.pl +6 -0
- package/test/eyelang/conformance/cases/034_equality_and_inequality.query +1 -0
- package/test/eyelang/conformance/cases/035_list_relations.pl +5 -0
- package/test/eyelang/conformance/cases/035_list_relations.query +1 -0
- package/test/eyelang/conformance/cases/036_append_splits.pl +3 -0
- package/test/eyelang/conformance/cases/036_append_splits.query +1 -0
- package/test/eyelang/conformance/cases/037_matching_and_comparison.pl +7 -0
- package/test/eyelang/conformance/cases/037_matching_and_comparison.query +1 -0
- package/test/eyelang/conformance/cases/038_memoize_declaration.pl +8 -0
- package/test/eyelang/conformance/cases/038_memoize_declaration.query +1 -0
- package/test/eyelang/conformance/cases/039_numeric_functions.pl +9 -0
- package/test/eyelang/conformance/cases/039_numeric_functions.query +1 -0
- package/test/eyelang/conformance/cases/040_between_enumeration.pl +3 -0
- package/test/eyelang/conformance/cases/040_between_enumeration.query +1 -0
- package/test/eyelang/conformance/cases/041_smallest_divisor.pl +3 -0
- package/test/eyelang/conformance/cases/041_smallest_divisor.query +1 -0
- package/test/eyelang/conformance/cases/042_negation_filter.pl +7 -0
- package/test/eyelang/conformance/cases/042_negation_filter.query +1 -0
- package/test/eyelang/conformance/cases/043_once_user_predicate.pl +5 -0
- package/test/eyelang/conformance/cases/043_once_user_predicate.query +1 -0
- package/test/eyelang/conformance/cases/044_findall_user_goal.pl +6 -0
- package/test/eyelang/conformance/cases/044_findall_user_goal.query +1 -0
- package/test/eyelang/conformance/cases/045_sort_deduplicates_atoms.pl +3 -0
- package/test/eyelang/conformance/cases/045_sort_deduplicates_atoms.query +1 -0
- package/test/eyelang/conformance/cases/046_append_bound_prefix_suffix.pl +4 -0
- package/test/eyelang/conformance/cases/046_append_bound_prefix_suffix.query +1 -0
- package/test/eyelang/conformance/cases/047_nth0_index_generation.pl +3 -0
- package/test/eyelang/conformance/cases/047_nth0_index_generation.query +1 -0
- package/test/eyelang/conformance/cases/048_set_nth0_edges.pl +4 -0
- package/test/eyelang/conformance/cases/048_set_nth0_edges.query +1 -0
- package/test/eyelang/conformance/cases/049_select_duplicate_occurrences.pl +3 -0
- package/test/eyelang/conformance/cases/049_select_duplicate_occurrences.query +1 -0
- package/test/eyelang/conformance/cases/050_not_member_filter.pl +6 -0
- package/test/eyelang/conformance/cases/050_not_member_filter.query +1 -0
- package/test/eyelang/conformance/cases/051_nested_holds_parts.pl +4 -0
- package/test/eyelang/conformance/cases/052_holds_member.pl +3 -0
- package/test/eyelang/conformance/cases/053_materialize_excludes_source_fact.pl +6 -0
- package/test/eyelang/conformance/cases/054_numeric_and_lexical_comparison.pl +5 -0
- package/test/eyelang/conformance/cases/054_numeric_and_lexical_comparison.query +1 -0
- package/test/eyelang/conformance/cases/055_string_matching_filters.pl +6 -0
- package/test/eyelang/conformance/cases/055_string_matching_filters.query +1 -0
- package/test/eyelang/conformance/cases/056_string_and_atom_concat.pl +3 -0
- package/test/eyelang/conformance/cases/056_string_and_atom_concat.query +1 -0
- package/test/eyelang/conformance/cases/057_countall_empty_and_nonempty.pl +4 -0
- package/test/eyelang/conformance/cases/057_countall_empty_and_nonempty.query +1 -0
- package/test/eyelang/conformance/cases/058_sumall_numeric_template.pl +5 -0
- package/test/eyelang/conformance/cases/058_sumall_numeric_template.query +1 -0
- package/test/eyelang/conformance/cases/059_aggregate_min_template.pl +5 -0
- package/test/eyelang/conformance/cases/059_aggregate_min_template.query +1 -0
- package/test/eyelang/conformance/cases/060_aggregate_max_compound_key.pl +5 -0
- package/test/eyelang/conformance/cases/060_aggregate_max_compound_key.query +1 -0
- package/test/eyelang/conformance/cases/061_date_difference.pl +4 -0
- package/test/eyelang/conformance/cases/062_reusable_numeric_builtins.pl +10 -0
- package/test/eyelang/conformance/cases/063_reusable_list_builtins.pl +11 -0
- package/test/eyelang/conformance/cases/064_reusable_string_builtins.pl +12 -0
- package/test/eyelang/conformance/cases/065_reusable_term_control_builtins.pl +11 -0
- package/test/eyelang/conformance/cases/066_numeric_edges.pl +14 -0
- package/test/eyelang/conformance/cases/067_list_edges.pl +10 -0
- package/test/eyelang/conformance/cases/068_list_generation_order.pl +7 -0
- package/test/eyelang/conformance/cases/069_list_summaries_and_sets.pl +9 -0
- package/test/eyelang/conformance/cases/070_matches_named_captures.pl +13 -0
- package/test/eyelang/conformance/cases/071_string_edges.pl +10 -0
- package/test/eyelang/conformance/cases/072_string_conversions.pl +10 -0
- package/test/eyelang/conformance/cases/073_term_introspection_edges.pl +10 -0
- package/test/eyelang/conformance/cases/074_forall_edges.pl +10 -0
- package/test/eyelang/conformance/cases/075_aggregation_edges.pl +12 -0
- package/test/eyelang/conformance/cases/076_composed_reusable_builtins.pl +8 -0
- package/test/eyelang/conformance/cases/077_recursive_path_with_lists.pl +10 -0
- package/test/eyelang/conformance/cases/078_mutual_recursion_with_arithmetic.pl +7 -0
- package/test/eyelang/conformance/cases/079_big_integer_arithmetic.pl +8 -0
- package/test/eyelang/conformance/cases/080_rounding_modes.pl +10 -0
- package/test/eyelang/conformance/cases/081_zero_safe_numeric_functions.pl +9 -0
- package/test/eyelang/conformance/cases/082_comparison_semantics.pl +10 -0
- package/test/eyelang/conformance/cases/083_between_modes_and_empty_ranges.pl +8 -0
- package/test/eyelang/conformance/cases/084_append_and_select_composition.pl +7 -0
- package/test/eyelang/conformance/cases/085_nth_and_update_edges.pl +8 -0
- package/test/eyelang/conformance/cases/086_slicing_pipeline.pl +10 -0
- package/test/eyelang/conformance/cases/087_sort_reverse_length.pl +8 -0
- package/test/eyelang/conformance/cases/088_list_summaries_failures.pl +8 -0
- package/test/eyelang/conformance/cases/089_string_split_join_pipeline.pl +7 -0
- package/test/eyelang/conformance/cases/090_string_substring_replace_edges.pl +9 -0
- package/test/eyelang/conformance/cases/091_string_case_and_trim.pl +7 -0
- package/test/eyelang/conformance/cases/092_scalar_string_conversions.pl +9 -0
- package/test/eyelang/conformance/cases/093_regex_named_captures_context.pl +8 -0
- package/test/eyelang/conformance/cases/094_context_holds_enumeration.pl +7 -0
- package/test/eyelang/conformance/cases/095_term_introspection_roundtrip.pl +8 -0
- package/test/eyelang/conformance/cases/096_functor_scalar_edges.pl +8 -0
- package/test/eyelang/conformance/cases/097_control_negation_once_forall.pl +13 -0
- package/test/eyelang/conformance/cases/098_aggregation_nested_templates.pl +11 -0
- package/test/eyelang/conformance/cases/099_materialize_multiple_arities.pl +8 -0
- package/test/eyelang/conformance/cases/100_reusable_builtin_workflow.pl +10 -0
- package/test/eyelang/conformance/cases/extension/036_reusable_numeric_builtins.pl +10 -0
- package/test/eyelang/conformance/cases/extension/037_reusable_list_builtins.pl +11 -0
- package/test/eyelang/conformance/cases/extension/038_reusable_string_builtins.pl +12 -0
- package/test/eyelang/conformance/cases/extension/039_reusable_term_control_builtins.pl +11 -0
- package/test/eyelang/conformance/expected/001_fact_output.pl +1 -0
- package/test/eyelang/conformance/expected/002_rule_recursion.pl +2 -0
- package/test/eyelang/conformance/expected/003_terms_and_readback.pl +13 -0
- package/test/eyelang/conformance/expected/004_conjunction_and_parentheses.pl +1 -0
- package/test/eyelang/conformance/expected/005_list_deconstruction.pl +2 -0
- package/test/eyelang/conformance/expected/006_comma_formula_data.pl +1 -0
- package/test/eyelang/conformance/expected/007_anonymous_variables.pl +1 -0
- package/test/eyelang/conformance/expected/008_graphic_atoms.pl +3 -0
- package/test/eyelang/conformance/expected/009_comments_and_whitespace.pl +2 -0
- package/test/eyelang/conformance/expected/010_variable_scope_and_reuse.pl +2 -0
- package/test/eyelang/conformance/expected/011_predicate_arity.pl +2 -0
- package/test/eyelang/conformance/expected/012_nested_compound_unification.pl +2 -0
- package/test/eyelang/conformance/expected/013_multiple_clauses_order.pl +2 -0
- package/test/eyelang/conformance/expected/014_failure_filters_answers.pl +1 -0
- package/test/eyelang/conformance/expected/015_improper_list_unification.pl +3 -0
- package/test/eyelang/conformance/expected/016_zero_arity_compound.pl +1 -0
- package/test/eyelang/conformance/expected/017_three_step_recursion.pl +3 -0
- package/test/eyelang/conformance/expected/018_quoted_atom_readback.pl +3 -0
- package/test/eyelang/conformance/expected/019_parenthesized_three_conjuncts.pl +1 -0
- package/test/eyelang/conformance/expected/020_nested_list_terms.pl +2 -0
- package/test/eyelang/conformance/expected/021_repeated_variable_head.pl +2 -0
- package/test/eyelang/conformance/expected/022_rule_head_structure.pl +2 -0
- package/test/eyelang/conformance/expected/023_quoted_escapes_readback.pl +2 -0
- package/test/eyelang/conformance/expected/024_numeric_literal_readback.pl +3 -0
- package/test/eyelang/conformance/expected/025_body_parentheses_with_formula_data.pl +1 -0
- package/test/eyelang/conformance/expected/026_underscore_named_variable_reuse.pl +1 -0
- package/test/eyelang/conformance/expected/027_default_derived_output.pl +3 -0
- package/test/eyelang/conformance/expected/028_materialize_focus.pl +1 -0
- package/test/eyelang/conformance/expected/029_arithmetic_and_comparison.pl +9 -0
- package/test/eyelang/conformance/expected/030_strings_and_atoms.pl +2 -0
- package/test/eyelang/conformance/expected/031_lists_aggregation_ordering.pl +9 -0
- package/test/eyelang/conformance/expected/032_holds_parts.pl +3 -0
- package/test/eyelang/conformance/expected/033_negation_once_generators.pl +2 -0
- package/test/eyelang/conformance/expected/034_equality_and_inequality.pl +4 -0
- package/test/eyelang/conformance/expected/035_list_relations.pl +4 -0
- package/test/eyelang/conformance/expected/036_append_splits.pl +3 -0
- package/test/eyelang/conformance/expected/037_matching_and_comparison.pl +5 -0
- package/test/eyelang/conformance/expected/038_memoize_declaration.pl +2 -0
- package/test/eyelang/conformance/expected/039_numeric_functions.pl +7 -0
- package/test/eyelang/conformance/expected/040_between_enumeration.pl +3 -0
- package/test/eyelang/conformance/expected/041_smallest_divisor.pl +1 -0
- package/test/eyelang/conformance/expected/042_negation_filter.pl +2 -0
- package/test/eyelang/conformance/expected/043_once_user_predicate.pl +1 -0
- package/test/eyelang/conformance/expected/044_findall_user_goal.pl +1 -0
- package/test/eyelang/conformance/expected/045_sort_deduplicates_atoms.pl +1 -0
- package/test/eyelang/conformance/expected/046_append_bound_prefix_suffix.pl +2 -0
- package/test/eyelang/conformance/expected/047_nth0_index_generation.pl +1 -0
- package/test/eyelang/conformance/expected/048_set_nth0_edges.pl +2 -0
- package/test/eyelang/conformance/expected/049_select_duplicate_occurrences.pl +2 -0
- package/test/eyelang/conformance/expected/050_not_member_filter.pl +1 -0
- package/test/eyelang/conformance/expected/051_nested_holds_parts.pl +3 -0
- package/test/eyelang/conformance/expected/052_holds_member.pl +2 -0
- package/test/eyelang/conformance/expected/053_materialize_excludes_source_fact.pl +1 -0
- package/test/eyelang/conformance/expected/054_numeric_and_lexical_comparison.pl +3 -0
- package/test/eyelang/conformance/expected/055_string_matching_filters.pl +2 -0
- package/test/eyelang/conformance/expected/056_string_and_atom_concat.pl +1 -0
- package/test/eyelang/conformance/expected/057_countall_empty_and_nonempty.pl +1 -0
- package/test/eyelang/conformance/expected/058_sumall_numeric_template.pl +1 -0
- package/test/eyelang/conformance/expected/059_aggregate_min_template.pl +1 -0
- package/test/eyelang/conformance/expected/060_aggregate_max_compound_key.pl +1 -0
- package/test/eyelang/conformance/expected/061_date_difference.pl +2 -0
- package/test/eyelang/conformance/expected/062_reusable_numeric_builtins.pl +8 -0
- package/test/eyelang/conformance/expected/063_reusable_list_builtins.pl +9 -0
- package/test/eyelang/conformance/expected/064_reusable_string_builtins.pl +10 -0
- package/test/eyelang/conformance/expected/065_reusable_term_control_builtins.pl +6 -0
- package/test/eyelang/conformance/expected/066_numeric_edges.pl +12 -0
- package/test/eyelang/conformance/expected/067_list_edges.pl +8 -0
- package/test/eyelang/conformance/expected/068_list_generation_order.pl +10 -0
- package/test/eyelang/conformance/expected/069_list_summaries_and_sets.pl +7 -0
- package/test/eyelang/conformance/expected/070_matches_named_captures.pl +1 -0
- package/test/eyelang/conformance/expected/071_string_edges.pl +8 -0
- package/test/eyelang/conformance/expected/072_string_conversions.pl +8 -0
- package/test/eyelang/conformance/expected/073_term_introspection_edges.pl +8 -0
- package/test/eyelang/conformance/expected/074_forall_edges.pl +5 -0
- package/test/eyelang/conformance/expected/075_aggregation_edges.pl +7 -0
- package/test/eyelang/conformance/expected/076_composed_reusable_builtins.pl +5 -0
- package/test/eyelang/conformance/expected/077_recursive_path_with_lists.pl +3 -0
- package/test/eyelang/conformance/expected/078_mutual_recursion_with_arithmetic.pl +7 -0
- package/test/eyelang/conformance/expected/079_big_integer_arithmetic.pl +6 -0
- package/test/eyelang/conformance/expected/080_rounding_modes.pl +8 -0
- package/test/eyelang/conformance/expected/081_zero_safe_numeric_functions.pl +7 -0
- package/test/eyelang/conformance/expected/082_comparison_semantics.pl +8 -0
- package/test/eyelang/conformance/expected/083_between_modes_and_empty_ranges.pl +8 -0
- package/test/eyelang/conformance/expected/084_append_and_select_composition.pl +10 -0
- package/test/eyelang/conformance/expected/085_nth_and_update_edges.pl +8 -0
- package/test/eyelang/conformance/expected/086_slicing_pipeline.pl +7 -0
- package/test/eyelang/conformance/expected/087_sort_reverse_length.pl +6 -0
- package/test/eyelang/conformance/expected/088_list_summaries_failures.pl +6 -0
- package/test/eyelang/conformance/expected/089_string_split_join_pipeline.pl +4 -0
- package/test/eyelang/conformance/expected/090_string_substring_replace_edges.pl +7 -0
- package/test/eyelang/conformance/expected/091_string_case_and_trim.pl +5 -0
- package/test/eyelang/conformance/expected/092_scalar_string_conversions.pl +7 -0
- package/test/eyelang/conformance/expected/093_regex_named_captures_context.pl +5 -0
- package/test/eyelang/conformance/expected/094_context_holds_enumeration.pl +8 -0
- package/test/eyelang/conformance/expected/095_term_introspection_roundtrip.pl +6 -0
- package/test/eyelang/conformance/expected/096_functor_scalar_edges.pl +6 -0
- package/test/eyelang/conformance/expected/097_control_negation_once_forall.pl +5 -0
- package/test/eyelang/conformance/expected/098_aggregation_nested_templates.pl +5 -0
- package/test/eyelang/conformance/expected/099_materialize_multiple_arities.pl +4 -0
- package/test/eyelang/conformance/expected/100_reusable_builtin_workflow.pl +6 -0
- package/test/eyelang/conformance/expected/extension/036_reusable_numeric_builtins.out +8 -0
- package/test/eyelang/conformance/expected/extension/037_reusable_list_builtins.out +9 -0
- package/test/eyelang/conformance/expected/extension/038_reusable_string_builtins.out +10 -0
- package/test/eyelang/conformance/expected/extension/039_reusable_term_control_builtins.out +6 -0
- package/test/eyelang/run-conformance.mjs +20 -22
- package/examples/eyelang/collatz-1000.pl +0 -14
- package/examples/eyelang/complex-matrix-stability.pl +0 -45
- package/examples/eyelang/gcd-bezout-identity.pl +0 -48
- package/examples/eyelang/goldbach-1000.pl +0 -185
- package/examples/eyelang/kaprekar.pl +0 -32
- package/examples/eyelang/matrix.pl +0 -296
- package/examples/eyelang/output/collatz-1000.pl +0 -1000
- package/examples/eyelang/output/complex-matrix-stability.pl +0 -5
- package/examples/eyelang/output/gcd-bezout-identity.pl +0 -36
- package/examples/eyelang/output/goldbach-1000.pl +0 -667
- package/examples/eyelang/output/kaprekar.pl +0 -8
- package/examples/eyelang/output/matrix.pl +0 -10
- package/lib/eyelang/builtins/matrix.js +0 -226
- package/lib/eyelang/builtins/number-theory.js +0 -114
- package/test/eyelang/conformance/cases/extension/036_extended_gcd.pl +0 -3
- package/test/eyelang/conformance/cases/extension/037_collatz_trajectory.pl +0 -3
- package/test/eyelang/conformance/cases/extension/038_kaprekar_steps.pl +0 -3
- package/test/eyelang/conformance/cases/extension/039_goldbach_pair.pl +0 -3
- package/test/eyelang/conformance/cases/extension/040_matrix_operations.pl +0 -5
- package/test/eyelang/conformance/expected/extension/036_extended_gcd.out +0 -1
- package/test/eyelang/conformance/expected/extension/037_collatz_trajectory.out +0 -1
- package/test/eyelang/conformance/expected/extension/038_kaprekar_steps.out +0 -1
- package/test/eyelang/conformance/expected/extension/039_goldbach_pair.out +0 -2
- package/test/eyelang/conformance/expected/extension/040_matrix_operations.out +0 -3
package/README.md
CHANGED
|
@@ -819,20 +819,18 @@ Formula-aware built-ins make Eyeling useful for meta-reasoning. `log:includes`,
|
|
|
819
819
|
|
|
820
820
|
### eyelang built-ins
|
|
821
821
|
|
|
822
|
-
The eyelang engine has its own built-in registry under `lib/eyelang/builtins/`. These are separate from the N3 namespaces above and are called as ordinary eyelang predicates. See the [eyelang language reference](docs/eyelang-language-reference.md#9-standard-built-in-predicates) for the portable profile. The bundled implementation currently registers
|
|
822
|
+
The eyelang engine has its own built-in registry under `lib/eyelang/builtins/`. These are separate from the N3 namespaces above and are called as ordinary eyelang predicates. See the [eyelang language reference](docs/eyelang-language-reference.md#9-standard-built-in-predicates) for the portable profile. The bundled implementation currently registers 80 name/arity entries across 78 predicate names:
|
|
823
823
|
|
|
824
824
|
| Family | Count | Built-ins |
|
|
825
825
|
|---|---:|---|
|
|
826
826
|
| Core and host | 4 | `eq/2`, `neq/2`, `local_time/1`, `difference/3` |
|
|
827
|
-
| Arithmetic and
|
|
828
|
-
| Strings |
|
|
829
|
-
| Lists |
|
|
827
|
+
| Arithmetic, comparison, and generators | 29 | `neg/2`, `abs/2`, `sin/2`, `cos/2`, `tan/2`, `asin/2`, `acos/2`, `sqrt/2`, `floor/2`, `ceiling/2`, `trunc/2`, `rounded/2`, `exp/2`, `log/2`, `add/3`, `sub/3`, `mul/3`, `div/3`, `mod/3`, `min/3`, `max/3`, `pow/3`, `atan2/3`, `lt/2`, `gt/2`, `le/2`, `ge/2`, `between/3`, `smallest_divisor_from/3` |
|
|
828
|
+
| Strings and conversions | 15 | `str_concat/3`, `contains/2`, `matches/2`, `matches/3`, `not_matches/2`, `split/3`, `join/3`, `substring/4`, `replace/4`, `lowercase/2`, `uppercase/2`, `trim/2`, `number_string/2`, `atom_string/2`, `term_string/2` |
|
|
829
|
+
| Lists | 19 | `append/3`, `nth0/3`, `set_nth0/4`, `head/2`, `rest/2`, `last/2`, `take/3`, `drop/3`, `slice/4`, `member/2`, `select/3`, `not_member/2`, `reverse/2`, `length/2`, `sum_list/2`, `min_list/2`, `max_list/2`, `list_to_set/2`, `sort/2` |
|
|
830
830
|
| Aggregation | 5 | `findall/3`, `countall/2`, `sumall/3`, `aggregate_min/5`, `aggregate_max/5` |
|
|
831
|
-
| Control |
|
|
832
|
-
| Context terms |
|
|
833
|
-
|
|
|
834
|
-
| Matrix helpers | 6 | `matrix_sum/2`, `matrix_multiply/2`, `cholesky_decomposition/2`, `determinant/2`, `matrix_inv_triang/2`, `matrix_inversion/2` |
|
|
835
|
-
| **Total** | **59** | |
|
|
831
|
+
| Control | 3 | `not/1`, `once/1`, `forall/2` |
|
|
832
|
+
| Context and terms | 5 | `holds/2`, `holds/3`, `functor/3`, `arg/3`, `compound_name_arguments/3` |
|
|
833
|
+
| **Total** | **80** | |
|
|
836
834
|
|
|
837
835
|
## Custom built-ins
|
|
838
836
|
|
package/docs/eyelang-guide.md
CHANGED
|
@@ -250,7 +250,7 @@ The playground has matching `--stats` and `--proof` checkboxes, so browser runs
|
|
|
250
250
|
|
|
251
251
|
eyelang builtins are registered by name and arity in small modules under [`lib/eyelang/builtins`](../lib/eyelang/builtins). This keeps the runtime portable to Node.js and the browser while giving each builtin family a clear boundary. Builtins are enabled by normal predicate calls.
|
|
252
252
|
|
|
253
|
-
The builtin families cover unification, arithmetic, comparison, dates, strings, lists, aggregation, context terms, search control
|
|
253
|
+
The builtin families cover unification, arithmetic, comparison, dates, strings, lists, aggregation, context terms, term inspection, and search control. Domain-specific number-theory and matrix helper modules were removed from the default registry because those predicates were examples/accelerators rather than a reusable portable surface. New reusable helpers cover common numeric functions, list slicing and summaries, string normalization/conversion, term inspection/construction, and `forall/2`. The complete bundled implementation list is kept in the top-level [README built-ins section](../README.md#built-ins-1), and the regression suite checks that table against the actual runtime registry.
|
|
254
254
|
|
|
255
255
|
To add a builtin, create or extend a module with `register(registry)` and call `registry.add(name, arity, handler, options)`. The default registry is assembled in [`lib/eyelang/builtins/registry.js`](../lib/eyelang/builtins/registry.js). Builtins that are only safe for specific argument modes should provide a `ready` predicate and `fallbackWhenNotReady: true`, so user-defined clauses remain visible until the builtin is applicable.
|
|
256
256
|
|
|
@@ -321,10 +321,8 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
321
321
|
| [`canary-release.pl`](../examples/eyelang/canary-release.pl) | Decides canary rollout or rollback. | [`output/canary-release.pl`](../examples/eyelang/output/canary-release.pl) |
|
|
322
322
|
| [`cat-koko.pl`](../examples/eyelang/cat-koko.pl) | Demonstrates named existential witnesses from a Cat Koko rule pattern. | [`output/cat-koko.pl`](../examples/eyelang/output/cat-koko.pl) |
|
|
323
323
|
| [`clinical-trial-screening.pl`](../examples/eyelang/clinical-trial-screening.pl) | Screens candidates for a trial. | [`output/clinical-trial-screening.pl`](../examples/eyelang/output/clinical-trial-screening.pl) |
|
|
324
|
-
| [`collatz-1000.pl`](../examples/eyelang/collatz-1000.pl) | Computes shared Collatz trajectories. | [`output/collatz-1000.pl`](../examples/eyelang/output/collatz-1000.pl) |
|
|
325
324
|
| [`combinatorics-findall-sort.pl`](../examples/eyelang/combinatorics-findall-sort.pl) | Collects and sorts finite combinations. | [`output/combinatorics-findall-sort.pl`](../examples/eyelang/output/combinatorics-findall-sort.pl) |
|
|
326
325
|
| [`competitive-enzyme-kinetics.pl`](../examples/eyelang/competitive-enzyme-kinetics.pl) | Computes inhibited enzyme reaction rates. | [`output/competitive-enzyme-kinetics.pl`](../examples/eyelang/output/competitive-enzyme-kinetics.pl) |
|
|
327
|
-
| [`complex-matrix-stability.pl`](../examples/eyelang/complex-matrix-stability.pl) | Checks stability of a 2x2 system. | [`output/complex-matrix-stability.pl`](../examples/eyelang/output/complex-matrix-stability.pl) |
|
|
328
326
|
| [`complex.pl`](../examples/eyelang/complex.pl) | Performs arithmetic on complex pairs. | [`output/complex.pl`](../examples/eyelang/output/complex.pl) |
|
|
329
327
|
| [`composition-of-injective-functions-is-injective.pl`](../examples/eyelang/composition-of-injective-functions-is-injective.pl) | Encodes composition and injectivity of finite functions. | [`output/composition-of-injective-functions-is-injective.pl`](../examples/eyelang/output/composition-of-injective-functions-is-injective.pl) |
|
|
330
328
|
| [`context-association.pl`](../examples/eyelang/context-association.pl) | Associates named contexts with their contents. | [`output/context-association.pl`](../examples/eyelang/output/context-association.pl) |
|
|
@@ -344,9 +342,9 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
344
342
|
| [`derived-backward-rule.pl`](../examples/eyelang/derived-backward-rule.pl) | Derives an inverse-property backward rule from rule data. | [`output/derived-backward-rule.pl`](../examples/eyelang/output/derived-backward-rule.pl) |
|
|
345
343
|
| [`derived-rule.pl`](../examples/eyelang/derived-rule.pl) | Derives conclusions from rule data. | [`output/derived-rule.pl`](../examples/eyelang/output/derived-rule.pl) |
|
|
346
344
|
| [`diamond-property.pl`](../examples/eyelang/diamond-property.pl) | Checks the diamond property of a relation. | [`output/diamond-property.pl`](../examples/eyelang/output/diamond-property.pl) |
|
|
345
|
+
| [`dijkstra.pl`](../examples/eyelang/dijkstra.pl) | Enumerates weighted simple paths. | [`output/dijkstra.pl`](../examples/eyelang/output/dijkstra.pl) |
|
|
347
346
|
| [`dijkstra-findall-sort.pl`](../examples/eyelang/dijkstra-findall-sort.pl) | Finds shortest paths using collected candidates. | [`output/dijkstra-findall-sort.pl`](../examples/eyelang/output/dijkstra-findall-sort.pl) |
|
|
348
347
|
| [`dijkstra-risk-path.pl`](../examples/eyelang/dijkstra-risk-path.pl) | Ranks routes by cost and trust. | [`output/dijkstra-risk-path.pl`](../examples/eyelang/output/dijkstra-risk-path.pl) |
|
|
349
|
-
| [`dijkstra.pl`](../examples/eyelang/dijkstra.pl) | Enumerates weighted simple paths. | [`output/dijkstra.pl`](../examples/eyelang/output/dijkstra.pl) |
|
|
350
348
|
| [`dining-philosophers.pl`](../examples/eyelang/dining-philosophers.pl) | Simulates Chandy-Misra fork exchanges. | [`output/dining-philosophers.pl`](../examples/eyelang/output/dining-philosophers.pl) |
|
|
351
349
|
| [`dog.pl`](../examples/eyelang/dog.pl) | Counts dogs and derives when a license is required. | [`output/dog.pl`](../examples/eyelang/output/dog.pl) |
|
|
352
350
|
| [`dpv-odrl-purpose-mapping.pl`](../examples/eyelang/dpv-odrl-purpose-mapping.pl) | Maps a DPV process into an ODRL permission view. | [`output/dpv-odrl-purpose-mapping.pl`](../examples/eyelang/output/dpv-odrl-purpose-mapping.pl) |
|
|
@@ -365,14 +363,12 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
365
363
|
| [`fft8-numeric.pl`](../examples/eyelang/fft8-numeric.pl) | Runs an 8-point FFT over complex pairs. | [`output/fft8-numeric.pl`](../examples/eyelang/output/fft8-numeric.pl) |
|
|
366
364
|
| [`fibonacci.pl`](../examples/eyelang/fibonacci.pl) | Computes large Fibonacci numbers by fast doubling. | [`output/fibonacci.pl`](../examples/eyelang/output/fibonacci.pl) |
|
|
367
365
|
| [`field-nitrogen-balance.pl`](../examples/eyelang/field-nitrogen-balance.pl) | Classifies field nitrogen balance. | [`output/field-nitrogen-balance.pl`](../examples/eyelang/output/field-nitrogen-balance.pl) |
|
|
368
|
-
| [`floating-point.pl`](../examples/eyelang/floating-point.pl) | Exercises floating-point arithmetic and comparisons. | [`output/floating-point.pl`](../examples/eyelang/output/floating-point.pl) |
|
|
369
366
|
| [`flandor.pl`](../examples/eyelang/flandor.pl) | Derives a Flanders macro-insight authorization and retooling package. | [`output/flandor.pl`](../examples/eyelang/output/flandor.pl) |
|
|
367
|
+
| [`floating-point.pl`](../examples/eyelang/floating-point.pl) | Exercises floating-point arithmetic and comparisons. | [`output/floating-point.pl`](../examples/eyelang/output/floating-point.pl) |
|
|
370
368
|
| [`four-color-map.pl`](../examples/eyelang/four-color-map.pl) | Checks a four-colour map assignment. | [`output/four-color-map.pl`](../examples/eyelang/output/four-color-map.pl) |
|
|
371
369
|
| [`fundamental-theorem-arithmetic.pl`](../examples/eyelang/fundamental-theorem-arithmetic.pl) | Factors integers and reconstructs products. | [`output/fundamental-theorem-arithmetic.pl`](../examples/eyelang/output/fundamental-theorem-arithmetic.pl) |
|
|
372
|
-
| [`gcd-bezout-identity.pl`](../examples/eyelang/gcd-bezout-identity.pl) | Computes gcd and Bézout coefficients. | [`output/gcd-bezout-identity.pl`](../examples/eyelang/output/gcd-bezout-identity.pl) |
|
|
373
370
|
| [`gd-step-certified.pl`](../examples/eyelang/gd-step-certified.pl) | Certifies a gradient-descent step. | [`output/gd-step-certified.pl`](../examples/eyelang/output/gd-step-certified.pl) |
|
|
374
371
|
| [`gdpr-compliance.pl`](../examples/eyelang/gdpr-compliance.pl) | Checks GDPR-style processing compliance. | [`output/gdpr-compliance.pl`](../examples/eyelang/output/gdpr-compliance.pl) |
|
|
375
|
-
| [`goldbach-1000.pl`](../examples/eyelang/goldbach-1000.pl) | Finds Goldbach prime pairs up to 1000. | [`output/goldbach-1000.pl`](../examples/eyelang/output/goldbach-1000.pl) |
|
|
376
372
|
| [`good-cobbler.pl`](../examples/eyelang/good-cobbler.pl) | Demonstrates term-level structure with a good-cobbler statement. | [`output/good-cobbler.pl`](../examples/eyelang/output/good-cobbler.pl) |
|
|
377
373
|
| [`gps.pl`](../examples/eyelang/gps.pl) | Finds and verifies route paths. | [`output/gps.pl`](../examples/eyelang/output/gps.pl) |
|
|
378
374
|
| [`graph-reachability.pl`](../examples/eyelang/graph-reachability.pl) | Derives reachable nodes in a graph. | [`output/graph-reachability.pl`](../examples/eyelang/output/graph-reachability.pl) |
|
|
@@ -386,14 +382,12 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
386
382
|
| [`heron-theorem.pl`](../examples/eyelang/heron-theorem.pl) | Computes triangle area by Heron's theorem. | [`output/heron-theorem.pl`](../examples/eyelang/output/heron-theorem.pl) |
|
|
387
383
|
| [`ideal-gas-law.pl`](../examples/eyelang/ideal-gas-law.pl) | Applies the ideal gas law. | [`output/ideal-gas-law.pl`](../examples/eyelang/output/ideal-gas-law.pl) |
|
|
388
384
|
| [`illegitimate-reasoning.pl`](../examples/eyelang/illegitimate-reasoning.pl) | Detects suspect reasoning patterns. | [`output/illegitimate-reasoning.pl`](../examples/eyelang/output/illegitimate-reasoning.pl) |
|
|
389
|
-
| [`kaprekar.pl`](../examples/eyelang/kaprekar.pl) | Iterates toward Kaprekar's constant. | [`output/kaprekar.pl`](../examples/eyelang/output/kaprekar.pl) |
|
|
390
385
|
| [`knowledge-engineering-alignment-flow.pl`](../examples/eyelang/knowledge-engineering-alignment-flow.pl) | Specializes reusable alignment rules into a target-shaped flow view. | [`output/knowledge-engineering-alignment-flow.pl`](../examples/eyelang/output/knowledge-engineering-alignment-flow.pl) |
|
|
391
386
|
| [`law-of-cosines.pl`](../examples/eyelang/law-of-cosines.pl) | Computes a triangle side by cosine law. | [`output/law-of-cosines.pl`](../examples/eyelang/output/law-of-cosines.pl) |
|
|
392
387
|
| [`least-squares-regression.pl`](../examples/eyelang/least-squares-regression.pl) | Fits a least-squares regression line. | [`output/least-squares-regression.pl`](../examples/eyelang/output/least-squares-regression.pl) |
|
|
393
388
|
| [`list-collection.pl`](../examples/eyelang/list-collection.pl) | Demonstrates list and collection built-ins. | [`output/list-collection.pl`](../examples/eyelang/output/list-collection.pl) |
|
|
394
389
|
| [`lldm.pl`](../examples/eyelang/lldm.pl) | Calculates leg-length discrepancy measurements. | [`output/lldm.pl`](../examples/eyelang/output/lldm.pl) |
|
|
395
390
|
| [`manufacturing-quality-control.pl`](../examples/eyelang/manufacturing-quality-control.pl) | Evaluates process capability and quality. | [`output/manufacturing-quality-control.pl`](../examples/eyelang/output/manufacturing-quality-control.pl) |
|
|
396
|
-
| [`matrix.pl`](../examples/eyelang/matrix.pl) | Runs matrix operations over sample inputs. | [`output/matrix.pl`](../examples/eyelang/output/matrix.pl) |
|
|
397
391
|
| [`microgrid-dispatch.pl`](../examples/eyelang/microgrid-dispatch.pl) | Plans microgrid dispatch and reserve. | [`output/microgrid-dispatch.pl`](../examples/eyelang/output/microgrid-dispatch.pl) |
|
|
398
392
|
| [`monkey-bananas.pl`](../examples/eyelang/monkey-bananas.pl) | Solves the monkey-and-bananas puzzle. | [`output/monkey-bananas.pl`](../examples/eyelang/output/monkey-bananas.pl) |
|
|
399
393
|
| [`network-sla.pl`](../examples/eyelang/network-sla.pl) | Checks network path SLA compliance. | [`output/network-sla.pl`](../examples/eyelang/output/network-sla.pl) |
|
|
@@ -412,6 +406,7 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
412
406
|
| [`proof-contrapositive.pl`](../examples/eyelang/proof-contrapositive.pl) | Models proof by contrapositive. | [`output/proof-contrapositive.pl`](../examples/eyelang/output/proof-contrapositive.pl) |
|
|
413
407
|
| [`quadratic-formula.pl`](../examples/eyelang/quadratic-formula.pl) | Solves sample quadratic equations. | [`output/quadratic-formula.pl`](../examples/eyelang/output/quadratic-formula.pl) |
|
|
414
408
|
| [`radioactive-decay.pl`](../examples/eyelang/radioactive-decay.pl) | Computes radioactive decay over time. | [`output/radioactive-decay.pl`](../examples/eyelang/output/radioactive-decay.pl) |
|
|
409
|
+
| [`reusable-builtins.pl`](../examples/eyelang/reusable-builtins.pl) | Tours reusable numeric, list, and string builtins. | [`output/reusable-builtins.pl`](../examples/eyelang/output/reusable-builtins.pl) |
|
|
415
410
|
| [`riemann-hypothesis.pl`](../examples/eyelang/riemann-hypothesis.pl) | Checks a finite catalogue of non-trivial zeta zeros against the Riemann-hypothesis condition. | [`output/riemann-hypothesis.pl`](../examples/eyelang/output/riemann-hypothesis.pl) |
|
|
416
411
|
| [`security-incident-correlation.pl`](../examples/eyelang/security-incident-correlation.pl) | Correlates security incidents across signals. | [`output/security-incident-correlation.pl`](../examples/eyelang/output/security-incident-correlation.pl) |
|
|
417
412
|
| [`service-impact.pl`](../examples/eyelang/service-impact.pl) | Analyzes service impact over cyclic dependencies. | [`output/service-impact.pl`](../examples/eyelang/output/service-impact.pl) |
|
|
@@ -422,6 +417,7 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
422
417
|
| [`socrates.pl`](../examples/eyelang/socrates.pl) | Derives that Socrates is mortal. | [`output/socrates.pl`](../examples/eyelang/output/socrates.pl) |
|
|
423
418
|
| [`statistics-summary.pl`](../examples/eyelang/statistics-summary.pl) | Computes population statistics for a sample. | [`output/statistics-summary.pl`](../examples/eyelang/output/statistics-summary.pl) |
|
|
424
419
|
| [`superdense-coding.pl`](../examples/eyelang/superdense-coding.pl) | Models superdense-coding bit transmission. | [`output/superdense-coding.pl`](../examples/eyelang/output/superdense-coding.pl) |
|
|
420
|
+
| [`term-tools.pl`](../examples/eyelang/term-tools.pl) | Inspects, builds, renders, and validates terms with reusable term/control builtins. | [`output/term-tools.pl`](../examples/eyelang/output/term-tools.pl) |
|
|
425
421
|
| [`trust-flow-provenance-threshold.pl`](../examples/eyelang/trust-flow-provenance-threshold.pl) | Classifies message trust from provenance confidence scores. | [`output/trust-flow-provenance-threshold.pl`](../examples/eyelang/output/trust-flow-provenance-threshold.pl) |
|
|
426
422
|
| [`turing.pl`](../examples/eyelang/turing.pl) | Simulates a binary-increment Turing machine. | [`output/turing.pl`](../examples/eyelang/output/turing.pl) |
|
|
427
423
|
| [`vector-similarity.pl`](../examples/eyelang/vector-similarity.pl) | Computes dot product, norm, and cosine similarity. | [`output/vector-similarity.pl`](../examples/eyelang/output/vector-similarity.pl) |
|
|
@@ -431,7 +427,6 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
431
427
|
| [`zebra.pl`](../examples/eyelang/zebra.pl) | Solves the zebra logic puzzle. | [`output/zebra.pl`](../examples/eyelang/output/zebra.pl) |
|
|
432
428
|
|
|
433
429
|
|
|
434
|
-
|
|
435
430
|
## Golden outputs, tests, and conformance
|
|
436
431
|
|
|
437
432
|
Golden answer outputs live in [`examples/eyelang/output`](../examples/eyelang/output). `npm run test:eyelang` covers the eyelang integration check, conformance cases, regression checks, runnable examples, and proof-output examples. A curated proof-output suite for `.pl` examples lives in [`examples/eyelang/proof`](../examples/eyelang/proof). Example tests pin `local_time/1` to `2026-05-30` so date-dependent examples stay deterministic. Regenerate them after an intentional output or explanation change:
|
|
@@ -465,7 +460,7 @@ node test/eyelang/run-regression.mjs
|
|
|
465
460
|
node test/eyelang/run-examples.mjs
|
|
466
461
|
```
|
|
467
462
|
|
|
468
|
-
The conformance suite lives in [`test/eyelang/conformance/`](../test/eyelang/conformance/)
|
|
463
|
+
The conformance suite lives in [`test/eyelang/conformance/`](../test/eyelang/conformance/) as one flat eyelang corpus. Each case is a small `.pl` program with an exact expected stdout `.pl` file, and some cases also include a goal file for testing the embeddable solver, so other implementations can reuse the same cases. The suite covers the standard language surface from the language reference, including reusable built-ins. The regression suite lives in [`test/eyelang/run-regression.mjs`](../test/eyelang/run-regression.mjs) and covers CLI regressions, the public JavaScript API, and white-box invariants for parser, unification, and indexing behavior.
|
|
469
464
|
|
|
470
465
|
## Development and release
|
|
471
466
|
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
- [9.8 Aggregation and ordering](#98-aggregation-and-ordering)
|
|
42
42
|
- [9.9 Context terms](#99-context-terms)
|
|
43
43
|
- [9.10 Search control](#910-search-control)
|
|
44
|
-
- [10.
|
|
44
|
+
- [10. Implementation-specific built-ins](#10-implementation-specific-built-ins)
|
|
45
45
|
- [11. Declarations](#11-declarations)
|
|
46
46
|
- [11.1 Memoization](#111-memoization)
|
|
47
47
|
- [11.2 Default-output materialization](#112-default-output-materialization)
|
|
@@ -51,10 +51,7 @@
|
|
|
51
51
|
- [12.3 Sockets and AI agents](#123-sockets-and-ai-agents)
|
|
52
52
|
- [13. Output and read-back profile](#13-output-and-read-back-profile)
|
|
53
53
|
- [13.1 Explanation output](#131-explanation-output)
|
|
54
|
-
- [14. Conformance
|
|
55
|
-
- [14.1 Core language profile](#141-core-language-profile)
|
|
56
|
-
- [14.2 Standard built-in profile](#142-standard-built-in-profile)
|
|
57
|
-
- [14.3 Standard host profile](#143-standard-host-profile)
|
|
54
|
+
- [14. Conformance](#14-conformance)
|
|
58
55
|
- [15. Relationship to ISO Prolog](#15-relationship-to-iso-prolog)
|
|
59
56
|
- [16. Examples](#16-examples)
|
|
60
57
|
- [16.1 Transitive closure](#161-transitive-closure)
|
|
@@ -345,7 +342,7 @@ This section specifies the **standard built-ins** of the eyelang language. An im
|
|
|
345
342
|
|
|
346
343
|
A built-in call is still written as an atomic formula, but the relation is provided by the host implementation rather than by source clauses. Several built-ins are mode-sensitive: they are intended to run when their input arguments are sufficiently ground, and implementations may leave user-defined clauses visible when that mode is not yet satisfied.
|
|
347
344
|
|
|
348
|
-
Implementations MAY provide additional built-ins, but such built-ins are
|
|
345
|
+
Implementations MAY provide additional built-ins, but such built-ins are implementation-specific and are not part of this normative catalog. Implementation-specific built-ins are discussed separately in section 10.
|
|
349
346
|
|
|
350
347
|
### 9.1 Equality and unification
|
|
351
348
|
|
|
@@ -360,15 +357,18 @@ Implementations MAY provide additional built-ins, but such built-ins are extensi
|
|
|
360
357
|
|---|---|
|
|
361
358
|
| `neg(A, B)` | `B` is the numeric negation of `A`. |
|
|
362
359
|
| `abs(A, B)` | `B` is the absolute value of `A`. |
|
|
363
|
-
| `sin(A, B)`, `cos(A, B)`, `
|
|
364
|
-
| `
|
|
360
|
+
| `sin(A, B)`, `cos(A, B)`, `tan(A, B)` | Trigonometric floating functions. |
|
|
361
|
+
| `asin(A, B)`, `acos(A, B)`, `atan2(Y, X, Angle)` | Inverse trigonometric floating functions. |
|
|
362
|
+
| `sqrt(A, B)` | Square root. Fails for negative inputs. |
|
|
363
|
+
| `floor(A, B)`, `ceiling(A, B)`, `trunc(A, B)`, `rounded(A, B)` | Integer-valued numeric rounding functions. |
|
|
364
|
+
| `exp(A, B)`, `log(A, B)` | Natural exponent and logarithm. `log/2` fails for non-positive inputs. |
|
|
365
365
|
| `add(A, B, C)` | `C = A + B`. |
|
|
366
366
|
| `sub(A, B, C)` | `C = A - B`. |
|
|
367
367
|
| `mul(A, B, C)` | `C = A * B`. |
|
|
368
368
|
| `div(A, B, C)` | `C = A / B`; integer inputs use integer division. |
|
|
369
369
|
| `mod(A, B, C)` | Integer remainder. |
|
|
370
370
|
| `pow(A, B, C)` | `C = A^B`. |
|
|
371
|
-
| `min(A, B, C)` | Numeric minimum. |
|
|
371
|
+
| `min(A, B, C)`, `max(A, B, C)` | Numeric minimum and maximum. |
|
|
372
372
|
|
|
373
373
|
### 9.3 Comparison
|
|
374
374
|
|
|
@@ -404,6 +404,14 @@ Comparisons interpret numeric-looking terms numerically. Other scalar terms are
|
|
|
404
404
|
| `matches(Text, Pattern)` | Text matches a simple implementation regex/search pattern. |
|
|
405
405
|
| `matches(Text, Pattern, Context)` | Text matches a JavaScript regular expression with named capture groups; `Context` is a comma context containing one unary term per matched capture group. |
|
|
406
406
|
| `not_matches(Text, Pattern)` | Negation of `matches/2`. |
|
|
407
|
+
| `split(Text, Separator, Parts)` | Splits text into a proper list of strings. |
|
|
408
|
+
| `join(Parts, Separator, Text)` | Joins a proper list of scalar terms into a string. |
|
|
409
|
+
| `substring(Text, Start, Length, Out)` | Extracts a zero-based substring. |
|
|
410
|
+
| `replace(Text, Search, Replacement, Out)` | Replaces all non-empty literal occurrences of `Search`. |
|
|
411
|
+
| `lowercase(Text, Out)`, `uppercase(Text, Out)`, `trim(Text, Out)` | Text normalization helpers. |
|
|
412
|
+
| `number_string(Number, String)` | Converts a number to a string or parses a numeric string into a number. |
|
|
413
|
+
| `atom_string(Atom, String)` | Converts between atom constants and strings. |
|
|
414
|
+
| `term_string(Term, String)` | Renders a ground term as its eyelang source string. |
|
|
407
415
|
|
|
408
416
|
### 9.7 Lists
|
|
409
417
|
|
|
@@ -412,12 +420,21 @@ Comparisons interpret numeric-looking terms numerically. Other scalar terms are
|
|
|
412
420
|
| `append(A, B, C)` | List append/split relation. |
|
|
413
421
|
| `nth0(Index, List, Value)` | Zero-based list lookup. |
|
|
414
422
|
| `set_nth0(Index, List, Value, Out)` | Functional list update. |
|
|
423
|
+
| `head(List, Head)` | Head of a non-empty list. |
|
|
415
424
|
| `rest(List, Tail)` | Tail of a non-empty list. |
|
|
425
|
+
| `last(List, Last)` | Last element of a non-empty proper list. |
|
|
426
|
+
| `take(N, List, Prefix)` | First `N` items of a proper list. |
|
|
427
|
+
| `drop(N, List, Suffix)` | Proper-list suffix after dropping `N` items. |
|
|
428
|
+
| `slice(Start, Length, List, Slice)` | Zero-based proper-list slice. |
|
|
416
429
|
| `member(X, List)` | Member generator. |
|
|
417
430
|
| `select(X, List, Rest)` | Selects one occurrence. |
|
|
418
431
|
| `not_member(X, List)` | Succeeds when `X` is not a member. |
|
|
419
432
|
| `reverse(A, B)` | Reverses a proper list. |
|
|
420
433
|
| `length(List, N)` | Proper-list length. |
|
|
434
|
+
| `sum_list(List, Sum)` | Numeric sum of a proper list; empty lists produce `0`. |
|
|
435
|
+
| `min_list(List, Min)`, `max_list(List, Max)` | Minimum and maximum under standard term ordering. |
|
|
436
|
+
| `list_to_set(List, Set)` | Removes duplicates while preserving the first occurrence order. |
|
|
437
|
+
| `sort(Input, Output)` | Sorts and deduplicates a proper list. |
|
|
421
438
|
|
|
422
439
|
### 9.8 Aggregation and ordering
|
|
423
440
|
|
|
@@ -428,9 +445,8 @@ Comparisons interpret numeric-looking terms numerically. Other scalar terms are
|
|
|
428
445
|
| `sumall(Template, Goal, Sum)` | Sums numeric `Template` values over solutions of `Goal`; empty solution sets produce `0`. |
|
|
429
446
|
| `aggregate_min(Key, Template, Goal, BestKey, BestTemplate)` | Selects the solution of `Goal` with the smallest resolved `Key`, returning that key and the corresponding resolved `Template`. Fails when `Goal` has no solutions. |
|
|
430
447
|
| `aggregate_max(Key, Template, Goal, BestKey, BestTemplate)` | Selects the solution of `Goal` with the largest resolved `Key`, returning that key and the corresponding resolved `Template`. Fails when `Goal` has no solutions. |
|
|
431
|
-
| `sort(Input, Output)` | Sorts and deduplicates a proper list. |
|
|
432
448
|
|
|
433
|
-
### 9.9 Context
|
|
449
|
+
### 9.9 Context and term inspection
|
|
434
450
|
|
|
435
451
|
Context terms are data representations of atomic formulas and comma conjunctions.
|
|
436
452
|
|
|
@@ -438,12 +454,18 @@ Context terms are data representations of atomic formulas and comma conjunctions
|
|
|
438
454
|
|---|---|
|
|
439
455
|
| `holds(Context, Term)` | Enumerates member terms inside a context term and unifies each member with `Term`. |
|
|
440
456
|
| `holds(Context, Name, Args)` | Enumerates context members of any arity, exposing each member as atom constant `Name` plus a proper argument list `Args`. |
|
|
457
|
+
| `functor(Term, Name, Arity)` | Decomposes a non-variable term into its name and arity. |
|
|
458
|
+
| `arg(Index, Term, Arg)` | Extracts the 1-based argument of a compound term. |
|
|
459
|
+
| `compound_name_arguments(Term, Name, Args)` | Decomposes a compound term or constructs one from an atom name and proper argument list. |
|
|
441
460
|
|
|
442
461
|
Example:
|
|
443
462
|
|
|
444
463
|
```prolog
|
|
445
464
|
holds((name(alice, "Alice"), knows(alice, bob)), name(S, O)).
|
|
446
465
|
holds((ready, name(alice, "Alice"), route(alice, bob, 7)), Name, Args).
|
|
466
|
+
functor(route(alice, bob, 7), route, 3).
|
|
467
|
+
arg(2, route(alice, bob, 7), bob).
|
|
468
|
+
compound_name_arguments(Term, route, [alice, bob, 7]).
|
|
447
469
|
```
|
|
448
470
|
|
|
449
471
|
The first goal can yield `holds((name(alice, "Alice"), knows(alice, bob)), name(alice, "Alice")).` The second can yield `holds((ready, name(alice, "Alice"), route(alice, bob, 7)), ready, []).`, `holds((ready, name(alice, "Alice"), route(alice, bob, 7)), name, [alice, "Alice"]).`, and `holds((ready, name(alice, "Alice"), route(alice, bob, 7)), route, [alice, bob, 7]).`
|
|
@@ -458,14 +480,15 @@ The N3 example [`context-schema-audit.n3`](../examples/context-schema-audit.n3)
|
|
|
458
480
|
|---|---|
|
|
459
481
|
| `not(Goal)` | Negation as failure. Succeeds when `Goal` has no solution. |
|
|
460
482
|
| `once(Goal)` | Succeeds with at most the first solution of `Goal`. |
|
|
483
|
+
| `forall(Generator, Test)` | Succeeds when every solution of `Generator` also satisfies `Test`; succeeds vacuously when `Generator` has no solutions. |
|
|
461
484
|
|
|
462
|
-
## 10.
|
|
485
|
+
## 10. Implementation-specific built-ins
|
|
463
486
|
|
|
464
|
-
Implementations MAY provide additional built-ins beyond the standard predicates listed above. Such built-ins are **
|
|
487
|
+
Implementations MAY provide additional built-ins beyond the standard predicates listed above. Such built-ins are **implementation-specific built-ins**. They are useful for embedding eyelang in particular host environments, exposing efficient finite-domain solvers, or providing domain-specific relations for applications.
|
|
465
488
|
|
|
466
|
-
|
|
489
|
+
Implementation-specific built-ins are not required for conformance to this specification. A portable eyelang program SHOULD NOT depend on one unless the target implementation explicitly documents it.
|
|
467
490
|
|
|
468
|
-
An
|
|
491
|
+
An implementation-specific built-in SHOULD obey the same surface-language discipline as standard built-ins:
|
|
469
492
|
|
|
470
493
|
- it is called using ordinary atomic-formula syntax, for example `some_extension(A, B)`;
|
|
471
494
|
- its arguments and results are eyelang terms from the Herbrand universe;
|
|
@@ -473,9 +496,9 @@ An extension built-in SHOULD obey the same surface-language discipline as standa
|
|
|
473
496
|
- it SHOULD document its intended modes, especially which arguments must be ground before it runs deterministically;
|
|
474
497
|
- it MUST NOT change the meaning of ordinary facts, rules, unification, or standard built-ins.
|
|
475
498
|
|
|
476
|
-
For example, an implementation may include
|
|
499
|
+
For example, an implementation may include host-specific integrations or domain accelerators. Those modules may be valuable and may make applications much faster, but their predicate names, arities, algorithms, and modes are implementation-defined unless they are separately standardized.
|
|
477
500
|
|
|
478
|
-
An implementation that provides explanation output SHOULD make
|
|
501
|
+
An implementation that provides explanation output SHOULD make implementation-specific built-ins explainable at least as opaque successful or failed built-in calls, so that proof traces do not incorrectly report "no clauses" for a host-provided relation.
|
|
479
502
|
|
|
480
503
|
## 11. Declarations
|
|
481
504
|
|
|
@@ -597,37 +620,25 @@ Default host output behavior is:
|
|
|
597
620
|
|
|
598
621
|
When proof output is enabled, each answer SHOULD be followed by a machine-readable `why/2` fact. Explanation output is ordinary eyelang syntax whose second argument is a nested abstract proof term such as `proof(goal(G), by(Method), bindings(Bindings), uses(Proofs))`; implementations SHOULD print `goal(...)` and `by(...)` on separate lines for readability. A proof term preserves the answer goal, derivation method, relevant bindings, and nested uses while omitting proof IDs. User clauses SHOULD be referenced explicitly as `fact(Filename, clause(N))` or `rule(Filename, clause(N))`, where `N` is the 1-based clause number within that source. Built-ins SHOULD be referenced as `builtin(Name, Arity)` because they do not come from source clauses. Explanation output is outside the logical semantics of the input program and MUST NOT change the set of answers.
|
|
599
622
|
|
|
600
|
-
## 14. Conformance
|
|
601
|
-
|
|
602
|
-
### 14.1 Core language profile
|
|
623
|
+
## 14. Conformance
|
|
603
624
|
|
|
604
|
-
A conforming
|
|
625
|
+
A conforming eyelang implementation supports the standard language described above as one conformance surface rather than as separate core and extension profiles. This includes:
|
|
605
626
|
|
|
606
627
|
- lexical syntax described above;
|
|
607
628
|
- facts and definite clauses;
|
|
608
629
|
- first-order unification without occurs check;
|
|
609
630
|
- left-to-right goal-directed proof search;
|
|
610
631
|
- lists and comma conjunctions;
|
|
611
|
-
- answer printing
|
|
612
|
-
|
|
613
|
-
### 14.2 Standard built-in profile
|
|
614
|
-
|
|
615
|
-
A conforming standard built-in implementation supports the built-ins listed in section 9. These are the portable built-ins independent implementations should implement when they claim standard built-in compatibility.
|
|
616
|
-
|
|
617
|
-
### 14.3 Standard host profile
|
|
618
|
-
|
|
619
|
-
A conforming standard host also supports:
|
|
620
|
-
|
|
632
|
+
- answer printing and read-back formatting;
|
|
633
|
+
- the standard built-ins listed in section 9;
|
|
621
634
|
- `memoize/2` declarations;
|
|
622
635
|
- `materialize/2` declarations;
|
|
623
636
|
- default derived output;
|
|
624
|
-
- explanation output
|
|
625
|
-
- stdin, file, and URL inputs in the CLI.
|
|
626
|
-
|
|
627
|
-
Browser execution, package layout, and any extension built-ins described in implementation documentation are outside this specification unless separately standardized.
|
|
637
|
+
- explanation output when the host exposes proof output.
|
|
628
638
|
|
|
639
|
+
Browser execution, package layout, CLI URL loading, and any implementation-specific built-ins described in host documentation are outside this conformance surface unless separately standardized.
|
|
629
640
|
|
|
630
|
-
Conformance cases
|
|
641
|
+
Conformance cases live in the repository under `test/eyelang/conformance/`. They are run by `npm test` before the example suite, and can be run alone with `node test/eyelang/run-conformance.mjs`. Each case has an input program under `conformance/cases/` and an exact expected standard-output file under `conformance/expected/`; both use `.pl` so expected output remains eyelang-readable.
|
|
631
642
|
|
|
632
643
|
## 15. Relationship to ISO Prolog
|
|
633
644
|
|
|
@@ -106,9 +106,9 @@ scores_for([Disease|RestDiseases], [Score|RestScores]) :-
|
|
|
106
106
|
score(Disease, Score),
|
|
107
107
|
scores_for(RestDiseases, RestScores).
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
score_sum([], 0.0).
|
|
110
|
+
score_sum([Value|Rest], Sum) :-
|
|
111
|
+
score_sum(Rest, TailSum),
|
|
112
112
|
add(Value, TailSum, Sum).
|
|
113
113
|
|
|
114
114
|
normalize_scores([], _Total, []).
|
|
@@ -159,7 +159,7 @@ scores(case, Scores) :-
|
|
|
159
159
|
scores_for(Diseases, Scores).
|
|
160
160
|
evidenceTotal(case, Total) :-
|
|
161
161
|
scores(case, Scores),
|
|
162
|
-
|
|
162
|
+
score_sum(Scores, Total).
|
|
163
163
|
posteriors(case, Posteriors) :-
|
|
164
164
|
scores(case, Scores),
|
|
165
165
|
evidenceTotal(case, Total),
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
% Reusable builtin tour: normalize text, summarize lists, and compute numeric values.
|
|
2
|
+
materialize(report, 2).
|
|
3
|
+
|
|
4
|
+
name_raw(" Ada Lovelace ").
|
|
5
|
+
tag_csv("logic,math,logic,programming").
|
|
6
|
+
scores([8, 13, 21]).
|
|
7
|
+
|
|
8
|
+
report(normalized_name, Name) :-
|
|
9
|
+
name_raw(Raw),
|
|
10
|
+
trim(Raw, Trimmed),
|
|
11
|
+
lowercase(Trimmed, Name).
|
|
12
|
+
|
|
13
|
+
report(unique_tags, Tags) :-
|
|
14
|
+
tag_csv(Csv),
|
|
15
|
+
split(Csv, ",", Parts),
|
|
16
|
+
list_to_set(Parts, Tags).
|
|
17
|
+
|
|
18
|
+
report(tag_label, Label) :-
|
|
19
|
+
tag_csv(Csv),
|
|
20
|
+
split(Csv, ",", Parts),
|
|
21
|
+
list_to_set(Parts, Tags),
|
|
22
|
+
join(Tags, " / ", Label).
|
|
23
|
+
|
|
24
|
+
report(score_summary, summary(Total, Peak, RootTotal)) :-
|
|
25
|
+
scores(Scores),
|
|
26
|
+
sum_list(Scores, Total),
|
|
27
|
+
max_list(Scores, Peak),
|
|
28
|
+
sqrt(Total, RootTotal).
|
|
29
|
+
|
|
30
|
+
report(window, Slice) :-
|
|
31
|
+
scores(Scores),
|
|
32
|
+
slice(1, 2, Scores, Slice).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
% Term tools: inspect and build structured terms, then validate all facts with forall/2.
|
|
2
|
+
materialize(report, 2).
|
|
3
|
+
|
|
4
|
+
edge(a, b, 3).
|
|
5
|
+
edge(b, c, 4).
|
|
6
|
+
|
|
7
|
+
report(shape, shape(Name, Arity)) :-
|
|
8
|
+
functor(edge(a, b, 3), Name, Arity).
|
|
9
|
+
|
|
10
|
+
report(second_argument, Node) :-
|
|
11
|
+
arg(2, edge(a, b, 3), Node).
|
|
12
|
+
|
|
13
|
+
report(parts, parts(Name, Args)) :-
|
|
14
|
+
compound_name_arguments(edge(a, b, 3), Name, Args).
|
|
15
|
+
|
|
16
|
+
report(rebuilt, Term) :-
|
|
17
|
+
compound_name_arguments(Term, edge, [c, d, 5]).
|
|
18
|
+
|
|
19
|
+
report(rendered, Text) :-
|
|
20
|
+
term_string(edge(a, [b, c]), Text).
|
|
21
|
+
|
|
22
|
+
report(all_weights_positive, yes) :-
|
|
23
|
+
forall(edge(_From, _To, Weight), gt(Weight, 0)).
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// The code keeps BigInt paths where possible so large eyelang integers remain exact.
|
|
3
3
|
import { compareIntegerText, deref, isDecimalInteger, lexicalValue, numberTerm, numberTextFromDouble, parseFiniteNumber, unify } from '../term.js';
|
|
4
4
|
|
|
5
|
-
const unaryNames = ['neg', 'abs', 'sin', 'cos', 'asin', 'acos', 'rounded', 'log'];
|
|
6
|
-
const binaryNames = ['add', 'sub', 'mul', 'div', 'mod', 'min', 'pow'];
|
|
5
|
+
const unaryNames = ['neg', 'abs', 'sin', 'cos', 'tan', 'asin', 'acos', 'sqrt', 'floor', 'ceiling', 'trunc', 'rounded', 'exp', 'log'];
|
|
6
|
+
const binaryNames = ['add', 'sub', 'mul', 'div', 'mod', 'min', 'max', 'pow', 'atan2'];
|
|
7
7
|
const compareNames = ['lt', 'gt', 'le', 'ge'];
|
|
8
8
|
|
|
9
9
|
export const arithmeticBuiltins = {
|
|
@@ -22,9 +22,11 @@ function unary(name) {
|
|
|
22
22
|
const text = lexicalValue(goal.args[0], env);
|
|
23
23
|
if (text == null) return;
|
|
24
24
|
let out = null;
|
|
25
|
-
if ((name === 'neg' || name === 'abs') && isDecimalInteger(text)) {
|
|
25
|
+
if ((name === 'neg' || name === 'abs' || name === 'floor' || name === 'ceiling' || name === 'trunc' || name === 'rounded') && isDecimalInteger(text)) {
|
|
26
26
|
const value = BigInt(text);
|
|
27
|
-
|
|
27
|
+
if (name === 'neg') out = (-value).toString();
|
|
28
|
+
else if (name === 'abs') out = (value < 0n ? -value : value).toString();
|
|
29
|
+
else out = value.toString();
|
|
28
30
|
} else {
|
|
29
31
|
const input = parseFiniteNumber(text);
|
|
30
32
|
if (input == null) return;
|
|
@@ -33,14 +35,22 @@ function unary(name) {
|
|
|
33
35
|
else if (name === 'abs') value = Math.abs(input);
|
|
34
36
|
else if (name === 'sin') value = Math.sin(input);
|
|
35
37
|
else if (name === 'cos') value = Math.cos(input);
|
|
38
|
+
else if (name === 'tan') value = Math.tan(input);
|
|
36
39
|
else if (name === 'asin') value = Math.asin(input);
|
|
37
40
|
else if (name === 'acos') value = Math.acos(input);
|
|
41
|
+
else if (name === 'sqrt') { if (input < 0) return; value = Math.sqrt(input); }
|
|
42
|
+
else if (name === 'floor') value = Math.floor(input);
|
|
43
|
+
else if (name === 'ceiling') value = Math.ceil(input);
|
|
44
|
+
else if (name === 'trunc') value = Math.trunc(input);
|
|
38
45
|
else if (name === 'rounded') value = Math.round(input);
|
|
46
|
+
else if (name === 'exp') value = Math.exp(input);
|
|
39
47
|
else if (name === 'log') {
|
|
40
48
|
if (input <= 0) return;
|
|
41
49
|
value = logCompat(input);
|
|
42
50
|
}
|
|
43
|
-
out = name === '
|
|
51
|
+
out = (name === 'floor' || name === 'ceiling' || name === 'trunc' || name === 'rounded')
|
|
52
|
+
? String(Math.trunc(value))
|
|
53
|
+
: numberTextFromDouble(value);
|
|
44
54
|
}
|
|
45
55
|
const next = env.clone();
|
|
46
56
|
if (out != null && unify(goal.args[1], numberTerm(out), next)) yield next;
|
|
@@ -53,7 +63,7 @@ function binary(name) {
|
|
|
53
63
|
const rightText = lexicalValue(goal.args[1], env);
|
|
54
64
|
if (leftText == null || rightText == null) return;
|
|
55
65
|
let out = null;
|
|
56
|
-
if (isDecimalInteger(leftText) && isDecimalInteger(rightText) && name !== 'mod') {
|
|
66
|
+
if (isDecimalInteger(leftText) && isDecimalInteger(rightText) && name !== 'mod' && name !== 'atan2') {
|
|
57
67
|
const a = BigInt(leftText);
|
|
58
68
|
const b = BigInt(rightText);
|
|
59
69
|
if (name === 'add') out = (a + b).toString();
|
|
@@ -61,6 +71,7 @@ function binary(name) {
|
|
|
61
71
|
else if (name === 'mul') out = (a * b).toString();
|
|
62
72
|
else if (name === 'div') { if (b === 0n) return; out = (a / b).toString(); }
|
|
63
73
|
else if (name === 'min') out = (a <= b ? a : b).toString();
|
|
74
|
+
else if (name === 'max') out = (a >= b ? a : b).toString();
|
|
64
75
|
else if (name === 'pow') { if (b < 0n) return; out = (a ** b).toString(); }
|
|
65
76
|
} else if (name === 'mod') {
|
|
66
77
|
if (!isDecimalInteger(leftText) || !isDecimalInteger(rightText)) return;
|
|
@@ -77,6 +88,8 @@ function binary(name) {
|
|
|
77
88
|
else if (name === 'div') { if (b === 0) return; value = a / b; }
|
|
78
89
|
else if (name === 'pow') value = Math.pow(a, b);
|
|
79
90
|
else if (name === 'min') value = Math.min(a, b);
|
|
91
|
+
else if (name === 'max') value = Math.max(a, b);
|
|
92
|
+
else if (name === 'atan2') value = Math.atan2(a, b);
|
|
80
93
|
out = numberTextFromDouble(value);
|
|
81
94
|
}
|
|
82
95
|
const next = env.clone();
|
|
@@ -3,6 +3,7 @@ export const controlBuiltins = {
|
|
|
3
3
|
register(registry) {
|
|
4
4
|
registry.add('not', 1, notBuiltin);
|
|
5
5
|
registry.add('once', 1, onceBuiltin);
|
|
6
|
+
registry.add('forall', 2, forallBuiltin);
|
|
6
7
|
}
|
|
7
8
|
};
|
|
8
9
|
|
|
@@ -20,3 +21,14 @@ function* onceBuiltin({ solver, goal, env }) {
|
|
|
20
21
|
break;
|
|
21
22
|
}
|
|
22
23
|
}
|
|
24
|
+
|
|
25
|
+
function* forallBuiltin({ solver, goal, env }) {
|
|
26
|
+
const generator = solver.cloneForInnerGoal(10000000);
|
|
27
|
+
for (const answerEnv of generator.solve([goal.args[0]], env.clone(), 0)) {
|
|
28
|
+
const checker = solver.cloneForInnerGoal(1);
|
|
29
|
+
let ok = false;
|
|
30
|
+
for (const _ of checker.solve([goal.args[1]], answerEnv.clone(), 0)) { ok = true; break; }
|
|
31
|
+
if (!ok) return;
|
|
32
|
+
}
|
|
33
|
+
yield env;
|
|
34
|
+
}
|