unicode-logic-kit 0.31.0__py3-none-any.whl
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.
- unicode_logic_kit/__init__.py +385 -0
- unicode_logic_kit/__main__.py +520 -0
- unicode_logic_kit/_deadline.py +219 -0
- unicode_logic_kit/ace/__init__.py +126 -0
- unicode_logic_kit/ace/_align.py +135 -0
- unicode_logic_kit/ace/chem_lexicon.py +128 -0
- unicode_logic_kit/ace/drs_reader.py +570 -0
- unicode_logic_kit/ace/mapping.py +666 -0
- unicode_logic_kit/ace/reverse_modal.py +138 -0
- unicode_logic_kit/ace/runner.py +551 -0
- unicode_logic_kit/ace/translate.py +452 -0
- unicode_logic_kit/ace/verbalize.py +1070 -0
- unicode_logic_kit/api.py +1284 -0
- unicode_logic_kit/atp/__init__.py +177 -0
- unicode_logic_kit/atp/_ascii_names.py +113 -0
- unicode_logic_kit/atp/_html.py +72 -0
- unicode_logic_kit/atp/_substructural_input.py +228 -0
- unicode_logic_kit/atp/_tff_problem.py +715 -0
- unicode_logic_kit/atp/_tptp_problem.py +1111 -0
- unicode_logic_kit/atp/_writer_support.py +289 -0
- unicode_logic_kit/atp/clingo_backend.py +1180 -0
- unicode_logic_kit/atp/cvc5_backend.py +1385 -0
- unicode_logic_kit/atp/eprover_backend.py +732 -0
- unicode_logic_kit/atp/finite_domain.py +1055 -0
- unicode_logic_kit/atp/fitch.py +1547 -0
- unicode_logic_kit/atp/fitch_search.py +551 -0
- unicode_logic_kit/atp/hets_backend.py +339 -0
- unicode_logic_kit/atp/hybrid_down.py +120 -0
- unicode_logic_kit/atp/incremental.py +250 -0
- unicode_logic_kit/atp/kripke_enum.py +741 -0
- unicode_logic_kit/atp/lambek.py +436 -0
- unicode_logic_kit/atp/leo3_backend.py +332 -0
- unicode_logic_kit/atp/linear.py +738 -0
- unicode_logic_kit/atp/lj.py +705 -0
- unicode_logic_kit/atp/logic_backends.py +566 -0
- unicode_logic_kit/atp/ltl_tableau.py +1084 -0
- unicode_logic_kit/atp/minizinc_backend.py +1402 -0
- unicode_logic_kit/atp/modal_tableau.py +1382 -0
- unicode_logic_kit/atp/nanocop_backend.py +410 -0
- unicode_logic_kit/atp/portfolio.py +489 -0
- unicode_logic_kit/atp/protocol.py +1803 -0
- unicode_logic_kit/atp/prover9_entailment.py +1153 -0
- unicode_logic_kit/atp/resolution.py +1376 -0
- unicode_logic_kit/atp/resolution_check.py +1114 -0
- unicode_logic_kit/atp/sequent.py +1050 -0
- unicode_logic_kit/atp/tableau.py +921 -0
- unicode_logic_kit/atp/tableau_check.py +543 -0
- unicode_logic_kit/atp/tptp_ncl.py +811 -0
- unicode_logic_kit/atp/tptp_tff.py +1546 -0
- unicode_logic_kit/atp/tstp.py +1333 -0
- unicode_logic_kit/atp/tstp_check.py +1096 -0
- unicode_logic_kit/atp/twee_backend.py +236 -0
- unicode_logic_kit/atp/twee_check.py +711 -0
- unicode_logic_kit/atp/twee_entailment.py +953 -0
- unicode_logic_kit/atp/vampire_entailment.py +540 -0
- unicode_logic_kit/atp/z3_arith.py +470 -0
- unicode_logic_kit/atp/z3_equivalence.py +36 -0
- unicode_logic_kit/atp/z3_fuzzy.py +362 -0
- unicode_logic_kit/atp/z3_input.py +500 -0
- unicode_logic_kit/atp/z3_models.py +208 -0
- unicode_logic_kit/chem/__init__.py +88 -0
- unicode_logic_kit/chem/_naming.py +284 -0
- unicode_logic_kit/chem/cache.py +185 -0
- unicode_logic_kit/chem/interop.py +244 -0
- unicode_logic_kit/chem/mol.py +525 -0
- unicode_logic_kit/chem/signature.py +112 -0
- unicode_logic_kit/comorphism.py +497 -0
- unicode_logic_kit/dl/__init__.py +384 -0
- unicode_logic_kit/dl/classification.py +227 -0
- unicode_logic_kit/dl/concepts.py +632 -0
- unicode_logic_kit/dl/datatypes.py +818 -0
- unicode_logic_kit/dl/owl_functional.py +2433 -0
- unicode_logic_kit/dl/owl_manchester.py +1637 -0
- unicode_logic_kit/dl/owl_reasoner.py +790 -0
- unicode_logic_kit/dl/parser.py +391 -0
- unicode_logic_kit/dl/tableau.py +4048 -0
- unicode_logic_kit/dl/translate.py +2704 -0
- unicode_logic_kit/drt/__init__.py +94 -0
- unicode_logic_kit/drt/export.py +179 -0
- unicode_logic_kit/drt/nodes.py +506 -0
- unicode_logic_kit/drt/parser.py +965 -0
- unicode_logic_kit/drt/resolve.py +195 -0
- unicode_logic_kit/drt/reverse.py +175 -0
- unicode_logic_kit/eval/__init__.py +106 -0
- unicode_logic_kit/eval/batch.py +382 -0
- unicode_logic_kit/eval/canonical.py +663 -0
- unicode_logic_kit/eval/chem_batch.py +606 -0
- unicode_logic_kit/eval/converses.py +200 -0
- unicode_logic_kit/eval/datasets/__init__.py +136 -0
- unicode_logic_kit/eval/datasets/_base.py +263 -0
- unicode_logic_kit/eval/datasets/_proofwriter_proof.py +422 -0
- unicode_logic_kit/eval/datasets/c3po.py +678 -0
- unicode_logic_kit/eval/datasets/folio.py +158 -0
- unicode_logic_kit/eval/datasets/fracas.py +418 -0
- unicode_logic_kit/eval/datasets/groves.py +191 -0
- unicode_logic_kit/eval/datasets/logicbench.py +467 -0
- unicode_logic_kit/eval/datasets/logicnli.py +303 -0
- unicode_logic_kit/eval/datasets/malls.py +133 -0
- unicode_logic_kit/eval/datasets/pfolio.py +594 -0
- unicode_logic_kit/eval/datasets/pmb.py +242 -0
- unicode_logic_kit/eval/datasets/prontoqa.py +611 -0
- unicode_logic_kit/eval/datasets/proofwriter.py +1431 -0
- unicode_logic_kit/eval/datasets/proverqa.py +674 -0
- unicode_logic_kit/eval/datasets/willow.py +478 -0
- unicode_logic_kit/eval/equivalence.py +466 -0
- unicode_logic_kit/eval/exercise_gen.py +533 -0
- unicode_logic_kit/eval/explain.py +791 -0
- unicode_logic_kit/eval/generality.py +750 -0
- unicode_logic_kit/eval/metric_hf.py +458 -0
- unicode_logic_kit/eval/predicate_match.py +343 -0
- unicode_logic_kit/eval/theory_check.py +1170 -0
- unicode_logic_kit/eval/validate.py +306 -0
- unicode_logic_kit/fol/__init__.py +177 -0
- unicode_logic_kit/fol/_atom_keys.py +510 -0
- unicode_logic_kit/fol/_fol_nodes.py +3586 -0
- unicode_logic_kit/fol/_free_parameters.py +105 -0
- unicode_logic_kit/fol/_ho_nodes.py +448 -0
- unicode_logic_kit/fol/_hybrid_nodes.py +308 -0
- unicode_logic_kit/fol/_identifiers.py +1091 -0
- unicode_logic_kit/fol/_lambek_nodes.py +112 -0
- unicode_logic_kit/fol/_linear_nodes.py +352 -0
- unicode_logic_kit/fol/_modal_nodes.py +1467 -0
- unicode_logic_kit/fol/_msfl_nodes.py +2196 -0
- unicode_logic_kit/fol/_numeral_symbols.py +231 -0
- unicode_logic_kit/fol/_so_nodes.py +200 -0
- unicode_logic_kit/fol/_symbol_names.py +81 -0
- unicode_logic_kit/fol/_team_nodes.py +181 -0
- unicode_logic_kit/fol/_tptp_symbols.py +551 -0
- unicode_logic_kit/fol/_truth_constants.py +117 -0
- unicode_logic_kit/fol/casl_export.py +1135 -0
- unicode_logic_kit/fol/casl_import.py +929 -0
- unicode_logic_kit/fol/derivation.py +367 -0
- unicode_logic_kit/fol/dialect_detect.py +70 -0
- unicode_logic_kit/fol/dialect_repair.py +537 -0
- unicode_logic_kit/fol/frames.py +637 -0
- unicode_logic_kit/fol/grammars/terminals.lark +31 -0
- unicode_logic_kit/fol/lambda_tools.py +297 -0
- unicode_logic_kit/fol/latex_input.py +429 -0
- unicode_logic_kit/fol/modal_translation.py +944 -0
- unicode_logic_kit/fol/msflparser.py +1033 -0
- unicode_logic_kit/fol/naming.py +422 -0
- unicode_logic_kit/fol/nodes.py +241 -0
- unicode_logic_kit/fol/normalforms.py +492 -0
- unicode_logic_kit/fol/pal.py +287 -0
- unicode_logic_kit/fol/prolog_export.py +566 -0
- unicode_logic_kit/fol/prolog_input.py +505 -0
- unicode_logic_kit/fol/prover9_input.py +1325 -0
- unicode_logic_kit/fol/qml.py +1760 -0
- unicode_logic_kit/fol/qmltp_input.py +525 -0
- unicode_logic_kit/fol/sanitize.py +221 -0
- unicode_logic_kit/fol/serialize.py +79 -0
- unicode_logic_kit/fol/signature.py +1290 -0
- unicode_logic_kit/fol/simplify_check.py +544 -0
- unicode_logic_kit/fol/spans.py +594 -0
- unicode_logic_kit/fol/tptp_input.py +1503 -0
- unicode_logic_kit/fol/tptp_repair.py +941 -0
- unicode_logic_kit/fol/unification.py +157 -0
- unicode_logic_kit/fol/verbalize.py +263 -0
- unicode_logic_kit/hets/__init__.py +163 -0
- unicode_logic_kit/hets/bridge.py +142 -0
- unicode_logic_kit/hets/client.py +748 -0
- unicode_logic_kit/hets/docker.py +420 -0
- unicode_logic_kit/hets/dol.py +712 -0
- unicode_logic_kit/hets/haskell_json.py +355 -0
- unicode_logic_kit/hets/owl_backend.py +794 -0
- unicode_logic_kit/hets/owl_cli.py +598 -0
- unicode_logic_kit/hets/symbols.py +512 -0
- unicode_logic_kit/hol/__init__.py +140 -0
- unicode_logic_kit/hol/_ho_common.py +323 -0
- unicode_logic_kit/hol/_isabelle_binders.py +125 -0
- unicode_logic_kit/hol/classical.py +812 -0
- unicode_logic_kit/hol/deepshallow/__init__.py +45 -0
- unicode_logic_kit/hol/deepshallow/_common.py +177 -0
- unicode_logic_kit/hol/deepshallow/conditional.py +225 -0
- unicode_logic_kit/hol/deepshallow/intuitionistic.py +181 -0
- unicode_logic_kit/hol/deepshallow/modal.py +217 -0
- unicode_logic_kit/hol/deepshallow/qml.py +406 -0
- unicode_logic_kit/hol/deepshallow/relevant.py +206 -0
- unicode_logic_kit/hol/free.py +753 -0
- unicode_logic_kit/hol/goedel.py +336 -0
- unicode_logic_kit/hol/ho_modal.py +1743 -0
- unicode_logic_kit/hol/intuitionistic.py +403 -0
- unicode_logic_kit/hol/isabelle_conditional.py +593 -0
- unicode_logic_kit/hol/isabelle_modal.py +1908 -0
- unicode_logic_kit/hol/isabelle_relevant.py +412 -0
- unicode_logic_kit/hol/isabelle_runner.py +1147 -0
- unicode_logic_kit/hol/isabelle_substructural.py +884 -0
- unicode_logic_kit/hol/lean.py +1018 -0
- unicode_logic_kit/hol/manyvalued.py +921 -0
- unicode_logic_kit/hol/secondorder.py +687 -0
- unicode_logic_kit/hol/thf_modal.py +941 -0
- unicode_logic_kit/hol/thirdorder.py +397 -0
- unicode_logic_kit/ilp/__init__.py +89 -0
- unicode_logic_kit/ilp/readback.py +389 -0
- unicode_logic_kit/ilp/separation.py +153 -0
- unicode_logic_kit/ilp/task.py +730 -0
- unicode_logic_kit/logic.py +163 -0
- unicode_logic_kit/mcp/__init__.py +28 -0
- unicode_logic_kit/mcp/__main__.py +5 -0
- unicode_logic_kit/mcp/chem_tools.py +1031 -0
- unicode_logic_kit/mcp/server.py +2453 -0
- unicode_logic_kit/mcp/syntax_spec.py +681 -0
- unicode_logic_kit/prob/__init__.py +53 -0
- unicode_logic_kit/prob/_bdd.py +225 -0
- unicode_logic_kit/prob/_column_gen.py +668 -0
- unicode_logic_kit/prob/distribution.py +686 -0
- unicode_logic_kit/prob/nilsson.py +470 -0
- unicode_logic_kit/py.typed +0 -0
- unicode_logic_kit/semantics/__init__.py +137 -0
- unicode_logic_kit/semantics/_modal_reject.py +156 -0
- unicode_logic_kit/semantics/action_models.py +466 -0
- unicode_logic_kit/semantics/asp_models.py +1200 -0
- unicode_logic_kit/semantics/conditional.py +580 -0
- unicode_logic_kit/semantics/dynamic_epistemic.py +95 -0
- unicode_logic_kit/semantics/free_logic.py +913 -0
- unicode_logic_kit/semantics/fuzzy.py +384 -0
- unicode_logic_kit/semantics/fuzzy_kripke.py +442 -0
- unicode_logic_kit/semantics/intuitionistic.py +581 -0
- unicode_logic_kit/semantics/kripke.py +1139 -0
- unicode_logic_kit/semantics/manyvalued.py +580 -0
- unicode_logic_kit/semantics/matrix.py +342 -0
- unicode_logic_kit/semantics/model_eval.py +1135 -0
- unicode_logic_kit/semantics/modelfinder.py +1036 -0
- unicode_logic_kit/semantics/nonmonotonic.py +372 -0
- unicode_logic_kit/semantics/relevant.py +331 -0
- unicode_logic_kit/semantics/secondorder.py +657 -0
- unicode_logic_kit/semantics/structures.py +352 -0
- unicode_logic_kit/semantics/tarski.py +975 -0
- unicode_logic_kit/semantics/team.py +315 -0
- unicode_logic_kit/semantics/team_translation.py +416 -0
- unicode_logic_kit/semantics/thirdorder.py +358 -0
- unicode_logic_kit/semantics/tnorm.py +85 -0
- unicode_logic_kit/semantics/truthtable.py +201 -0
- unicode_logic_kit-0.31.0.dist-info/METADATA +333 -0
- unicode_logic_kit-0.31.0.dist-info/RECORD +237 -0
- unicode_logic_kit-0.31.0.dist-info/WHEEL +4 -0
- unicode_logic_kit-0.31.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"""Well-formedness / validity report for (LLM-generated) FOL formulas.
|
|
2
|
+
|
|
3
|
+
This module provides lightweight, purely structural checks that flag the
|
|
4
|
+
defects most commonly seen in machine-produced first-order formulas:
|
|
5
|
+
|
|
6
|
+
* the formula is not a closed sentence (it has free logical variables);
|
|
7
|
+
* a predicate or function symbol is applied with inconsistent arities;
|
|
8
|
+
* leftover lambda machinery (Lambda / Application / LambdaVar) that should
|
|
9
|
+
have been eliminated before the formula was considered final;
|
|
10
|
+
* (via ``validate_text``) the raw model output does not even parse.
|
|
11
|
+
|
|
12
|
+
The entry points are:
|
|
13
|
+
|
|
14
|
+
* ``validate(node)`` — inspect an already-parsed AST.
|
|
15
|
+
* ``is_wellformed(node)`` — the headline boolean.
|
|
16
|
+
* ``validate_text(text)`` — parse raw text first, capturing parse failures.
|
|
17
|
+
|
|
18
|
+
Nothing here mutates its input; every traversal is read-only.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from dataclasses import dataclass, field
|
|
22
|
+
from typing import Dict, Optional, Tuple
|
|
23
|
+
|
|
24
|
+
from unicode_logic_kit.fol.nodes import (
|
|
25
|
+
Node,
|
|
26
|
+
Variable,
|
|
27
|
+
Constant,
|
|
28
|
+
Function,
|
|
29
|
+
Atom,
|
|
30
|
+
Lambda,
|
|
31
|
+
Application,
|
|
32
|
+
LambdaVar,
|
|
33
|
+
SortedConstant,
|
|
34
|
+
free_variables,
|
|
35
|
+
)
|
|
36
|
+
# The node types that carry a sort name (SortedQuantifier, SortedConstant,
|
|
37
|
+
# SortedCount, SortedCardinality): one definition, shared with the reduction to
|
|
38
|
+
# plain FOL, so a sorted node added there is read here too.
|
|
39
|
+
from unicode_logic_kit.fol._msfl_nodes import _SORTED_NODE_TYPES
|
|
40
|
+
# The two truth constants are the logical constants true and false, not predicates
|
|
41
|
+
# of the user's: one definition, shared with every route that reads them.
|
|
42
|
+
from unicode_logic_kit.fol._truth_constants import is_truth_constant
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
# Report dataclass
|
|
47
|
+
# ---------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
@dataclass(frozen=True)
|
|
50
|
+
class ValidationReport:
|
|
51
|
+
"""An immutable summary of the well-formedness checks run on a formula.
|
|
52
|
+
|
|
53
|
+
Namespacing of ``arity_conflicts``: predicate and function symbols live in
|
|
54
|
+
SEPARATE namespaces, so a key is a 2-tuple ``("pred", name)`` or
|
|
55
|
+
``("func", name)``. This keeps a predicate ``P`` used as ``P/1`` from
|
|
56
|
+
falsely conflicting with an unrelated function ``p`` used as ``p/2``.
|
|
57
|
+
|
|
58
|
+
Fields:
|
|
59
|
+
|
|
60
|
+
``is_closed``
|
|
61
|
+
True iff the formula has no free logical variables (it is a
|
|
62
|
+
sentence). Free occurrences of both ``Variable`` and ``LambdaVar``
|
|
63
|
+
count against closedness.
|
|
64
|
+
``free_variable_names``
|
|
65
|
+
sorted, de-duplicated names of the free Variable/LambdaVar
|
|
66
|
+
occurrences.
|
|
67
|
+
``arity_consistent``
|
|
68
|
+
True iff every predicate symbol is used with a single arity and
|
|
69
|
+
likewise every function symbol.
|
|
70
|
+
``arity_conflicts``
|
|
71
|
+
maps a namespaced symbol key ``("pred"|"func", name)`` to the sorted
|
|
72
|
+
tuple of the distinct arities observed; only symbols with more than
|
|
73
|
+
one distinct arity appear.
|
|
74
|
+
``has_lambdas``
|
|
75
|
+
True iff any Lambda / Application / LambdaVar remains.
|
|
76
|
+
``predicates`` / ``functions`` / ``constants``
|
|
77
|
+
sorted ``name/arity`` (predicates, functions) or ``name`` (constants)
|
|
78
|
+
inventories for quick inspection. The comparison atoms, the arithmetic
|
|
79
|
+
functions and the two truth constants (``⊤`` / ``$true``, ``⊥`` /
|
|
80
|
+
``$false``) are built in and are not listed.
|
|
81
|
+
``sorts_used``
|
|
82
|
+
sorted sort names from every node that carries one: SortedQuantifier,
|
|
83
|
+
SortedConstant, SortedCount and SortedCardinality.
|
|
84
|
+
``parseable``
|
|
85
|
+
True for ``validate(node)``; ``validate_text`` sets it False on a
|
|
86
|
+
parse failure.
|
|
87
|
+
``error``
|
|
88
|
+
the parse-error message when ``parseable`` is False, else None.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
is_closed: bool
|
|
92
|
+
free_variable_names: Tuple[str, ...]
|
|
93
|
+
arity_consistent: bool
|
|
94
|
+
arity_conflicts: Dict[Tuple[str, str], Tuple[int, ...]]
|
|
95
|
+
has_lambdas: bool
|
|
96
|
+
predicates: Tuple[str, ...]
|
|
97
|
+
functions: Tuple[str, ...]
|
|
98
|
+
constants: Tuple[str, ...]
|
|
99
|
+
sorts_used: Tuple[str, ...]
|
|
100
|
+
parseable: bool = True
|
|
101
|
+
error: Optional[str] = None
|
|
102
|
+
|
|
103
|
+
def __str__(self) -> str:
|
|
104
|
+
"""Render a compact, human-readable multi-line summary."""
|
|
105
|
+
if not self.parseable:
|
|
106
|
+
return f"ValidationReport(parseable=False, error={self.error!r})"
|
|
107
|
+
lines = [
|
|
108
|
+
"ValidationReport(",
|
|
109
|
+
f" parseable = {self.parseable}",
|
|
110
|
+
f" is_closed = {self.is_closed}",
|
|
111
|
+
f" free_variables = {', '.join(self.free_variable_names) or '-'}",
|
|
112
|
+
f" arity_consistent = {self.arity_consistent}",
|
|
113
|
+
f" arity_conflicts = {dict(self.arity_conflicts) or '-'}",
|
|
114
|
+
f" has_lambdas = {self.has_lambdas}",
|
|
115
|
+
f" predicates = {', '.join(self.predicates) or '-'}",
|
|
116
|
+
f" functions = {', '.join(self.functions) or '-'}",
|
|
117
|
+
f" constants = {', '.join(self.constants) or '-'}",
|
|
118
|
+
f" sorts_used = {', '.join(self.sorts_used) or '-'}",
|
|
119
|
+
")",
|
|
120
|
+
]
|
|
121
|
+
return "\n".join(lines)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# ---------------------------------------------------------------------------
|
|
125
|
+
# Internal inventory collection
|
|
126
|
+
# ---------------------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
@dataclass
|
|
129
|
+
class _Inventory:
|
|
130
|
+
"""Mutable scratch collector populated by a single pre-order walk.
|
|
131
|
+
|
|
132
|
+
Kept private and never returned; ``validate`` freezes the results into the
|
|
133
|
+
immutable ``ValidationReport``. Arities are accumulated per namespaced
|
|
134
|
+
symbol so that conflicts can be detected afterwards.
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
pred_arities: Dict[str, set] = field(default_factory=dict)
|
|
138
|
+
func_arities: Dict[str, set] = field(default_factory=dict)
|
|
139
|
+
constants: set = field(default_factory=set)
|
|
140
|
+
sorts: set = field(default_factory=set)
|
|
141
|
+
has_lambdas: bool = False
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# Comparison atoms (=, ≠, <, >, ≤, ≥) and arithmetic functions (+, -, *, /) are
|
|
145
|
+
# built-in operators, not user predicate/function symbols, so they are excluded
|
|
146
|
+
# from the inventories and from arity-consistency checking. So are the two truth
|
|
147
|
+
# constants (the nullary atoms ``$true`` / ``⊤`` and ``$false`` / ``⊥``): a
|
|
148
|
+
# formula that mentions ``⊥`` uses no predicate named ``$false``, and the
|
|
149
|
+
# nullary constant never conflicts with a user predicate spelled like it that
|
|
150
|
+
# takes arguments.
|
|
151
|
+
_BUILTIN_PREDS = frozenset({"=", "≠", "<", ">", "≤", "≥"})
|
|
152
|
+
_BUILTIN_FUNCS = frozenset({"+", "-", "*", "/"})
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _collect(node: Node, inv: _Inventory) -> None:
|
|
156
|
+
"""Walk ``node`` in pre-order, recording every symbol into ``inv``.
|
|
157
|
+
|
|
158
|
+
Uses ``node.walk()`` (the shared pre-order traversal) so that any future
|
|
159
|
+
structural node type is covered without changes here. Each occurrence is
|
|
160
|
+
classified purely by node type; nothing is mutated on the input.
|
|
161
|
+
"""
|
|
162
|
+
for n in node.walk():
|
|
163
|
+
if isinstance(n, (Lambda, Application, LambdaVar)):
|
|
164
|
+
inv.has_lambdas = True
|
|
165
|
+
|
|
166
|
+
if isinstance(n, Atom):
|
|
167
|
+
if n.predicate not in _BUILTIN_PREDS and not is_truth_constant(n):
|
|
168
|
+
inv.pred_arities.setdefault(n.predicate, set()).add(len(n.args))
|
|
169
|
+
elif isinstance(n, Function):
|
|
170
|
+
if n.name not in _BUILTIN_FUNCS:
|
|
171
|
+
inv.func_arities.setdefault(n.name, set()).add(len(n.args))
|
|
172
|
+
elif isinstance(n, Constant):
|
|
173
|
+
inv.constants.add(n.name)
|
|
174
|
+
elif isinstance(n, SortedConstant):
|
|
175
|
+
inv.constants.add(n.name)
|
|
176
|
+
inv.sorts.add(n.sort)
|
|
177
|
+
elif isinstance(n, _SORTED_NODE_TYPES):
|
|
178
|
+
# SortedQuantifier, and the sorted counting quantifier and cardinality
|
|
179
|
+
# term: a sort that occurs only in one of the last two is a sort used.
|
|
180
|
+
inv.sorts.add(n.sort)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def _arity_conflicts(inv: _Inventory) -> Dict[Tuple[str, str], Tuple[int, ...]]:
|
|
184
|
+
"""Return namespaced symbols seen with more than one arity.
|
|
185
|
+
|
|
186
|
+
Keys are ``("pred", name)`` / ``("func", name)``; values are the sorted
|
|
187
|
+
tuple of distinct arities. Symbols with a single consistent arity are
|
|
188
|
+
omitted, so an empty dict means full arity consistency.
|
|
189
|
+
"""
|
|
190
|
+
conflicts: Dict[Tuple[str, str], Tuple[int, ...]] = {}
|
|
191
|
+
for name, arities in inv.pred_arities.items():
|
|
192
|
+
if len(arities) > 1:
|
|
193
|
+
conflicts[("pred", name)] = tuple(sorted(arities))
|
|
194
|
+
for name, arities in inv.func_arities.items():
|
|
195
|
+
if len(arities) > 1:
|
|
196
|
+
conflicts[("func", name)] = tuple(sorted(arities))
|
|
197
|
+
return conflicts
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _inventory_strings(arities: Dict[str, set]) -> Tuple[str, ...]:
|
|
201
|
+
"""Render a name->arities map as a sorted tuple of ``name/arity`` strings.
|
|
202
|
+
|
|
203
|
+
A symbol with conflicting arities yields one entry per distinct arity (e.g.
|
|
204
|
+
``P/1`` and ``P/2``), so the inventory faithfully shows every form seen.
|
|
205
|
+
"""
|
|
206
|
+
entries = []
|
|
207
|
+
for name, arity_set in arities.items():
|
|
208
|
+
for arity in sorted(arity_set):
|
|
209
|
+
entries.append(f"{name}/{arity}")
|
|
210
|
+
return tuple(sorted(entries))
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# ---------------------------------------------------------------------------
|
|
214
|
+
# Public API
|
|
215
|
+
# ---------------------------------------------------------------------------
|
|
216
|
+
|
|
217
|
+
def validate(node: Node) -> ValidationReport:
|
|
218
|
+
"""Run all well-formedness checks on an already-parsed AST.
|
|
219
|
+
|
|
220
|
+
The returned report always has ``parseable=True`` (the node was, by
|
|
221
|
+
definition, parsed to exist). ``validate_text`` is the entry point that can
|
|
222
|
+
report a parse failure.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
node: any FOL/MSFL ``Node``.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
A frozen ``ValidationReport`` describing closedness, arity consistency,
|
|
229
|
+
residual lambda machinery, and symbol inventories.
|
|
230
|
+
"""
|
|
231
|
+
free = free_variables(node)
|
|
232
|
+
free_names = tuple(sorted({v.name for v in free}))
|
|
233
|
+
|
|
234
|
+
inv = _Inventory()
|
|
235
|
+
_collect(node, inv)
|
|
236
|
+
|
|
237
|
+
conflicts = _arity_conflicts(inv)
|
|
238
|
+
|
|
239
|
+
return ValidationReport(
|
|
240
|
+
is_closed=not free,
|
|
241
|
+
free_variable_names=free_names,
|
|
242
|
+
arity_consistent=not conflicts,
|
|
243
|
+
arity_conflicts=conflicts,
|
|
244
|
+
has_lambdas=inv.has_lambdas,
|
|
245
|
+
predicates=_inventory_strings(inv.pred_arities),
|
|
246
|
+
functions=_inventory_strings(inv.func_arities),
|
|
247
|
+
constants=tuple(sorted(inv.constants)),
|
|
248
|
+
sorts_used=tuple(sorted(inv.sorts)),
|
|
249
|
+
parseable=True,
|
|
250
|
+
error=None,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def is_wellformed(node: Node) -> bool:
|
|
255
|
+
"""Convenience headline check on an already-parsed AST.
|
|
256
|
+
|
|
257
|
+
A node is well-formed iff it is a closed sentence, every symbol is used
|
|
258
|
+
with a single arity, and no lambda machinery remains.
|
|
259
|
+
"""
|
|
260
|
+
report = validate(node)
|
|
261
|
+
return report.is_closed and report.arity_consistent and not report.has_lambdas
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def validate_text(text: str, parser=None) -> ValidationReport:
|
|
265
|
+
"""Parse ``text`` then validate it, capturing syntactic failures.
|
|
266
|
+
|
|
267
|
+
This is the entry point for raw model output: a parse failure
|
|
268
|
+
(``NamingError`` / ``ParsingError``) yields a report with
|
|
269
|
+
``parseable=False`` and the error message in ``error`` rather than raising.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
text: the raw formula string.
|
|
273
|
+
parser: an ``MSFLParser`` instance (or anything with a compatible
|
|
274
|
+
``.parse``). Defaults to a fresh ``MSFLParser()`` (classical FOL
|
|
275
|
+
mode). Pass ``MSFLParser(many_sorted=True)`` etc. for other modes.
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
On success, a report with ``parseable=True`` plus the ``validate(node)``
|
|
279
|
+
fields. On a parse failure, a report with ``parseable=False``, the
|
|
280
|
+
error message in ``error``, and conservative empty/false field values.
|
|
281
|
+
"""
|
|
282
|
+
# Imported lazily so the AST-only checks (validate / is_wellformed) do not
|
|
283
|
+
# pull in the parser stack, and to mirror the package's import boundaries.
|
|
284
|
+
from unicode_logic_kit import MSFLParser, NamingError, ParsingError
|
|
285
|
+
|
|
286
|
+
if parser is None:
|
|
287
|
+
parser = MSFLParser()
|
|
288
|
+
|
|
289
|
+
try:
|
|
290
|
+
node = parser.parse(text)
|
|
291
|
+
except (NamingError, ParsingError) as exc:
|
|
292
|
+
return ValidationReport(
|
|
293
|
+
is_closed=False,
|
|
294
|
+
free_variable_names=(),
|
|
295
|
+
arity_consistent=False,
|
|
296
|
+
arity_conflicts={},
|
|
297
|
+
has_lambdas=False,
|
|
298
|
+
predicates=(),
|
|
299
|
+
functions=(),
|
|
300
|
+
constants=(),
|
|
301
|
+
sorts_used=(),
|
|
302
|
+
parseable=False,
|
|
303
|
+
error=str(exc),
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
return validate(node)
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
from .msflparser import MSFLParser
|
|
2
|
+
from .nodes import (
|
|
3
|
+
Node, Variable, Constant, Number, Function,
|
|
4
|
+
Atom, Not, And, Or, Xor, Implies, Iff, Quantifier,
|
|
5
|
+
Count, Measure, Cardinality, Contrast,
|
|
6
|
+
Z3Env,
|
|
7
|
+
node_at, replace_at,
|
|
8
|
+
SortedQuantifier, SortedConstant,
|
|
9
|
+
SortedCount, SortedCardinality,
|
|
10
|
+
Nominal, At, Down,
|
|
11
|
+
Dependence, SlashedExists,
|
|
12
|
+
Tensor, With, OPlus, LinearImplies, OfCourse, One, Top, Zero,
|
|
13
|
+
Product, Under, Over,
|
|
14
|
+
WeakConjunction, WeakDisjunction,
|
|
15
|
+
StrongConjunction, StrongDisjunction,
|
|
16
|
+
LukNegation, LukImplication, LukEquivalence,
|
|
17
|
+
LambdaVar, Lambda, Application,
|
|
18
|
+
Box, Diamond, Knows, Believes, Says, Wants,
|
|
19
|
+
EverybodyKnows, DistributedKnowledge, CommonKnowledge,
|
|
20
|
+
Always, Eventually, Next, Until,
|
|
21
|
+
Historically, Once, Previous, Since,
|
|
22
|
+
Obligatory, Permitted,
|
|
23
|
+
Would, Might,
|
|
24
|
+
Announce, AnnounceDiamond,
|
|
25
|
+
SecondOrderQuantifier,
|
|
26
|
+
PredicateTerm, Signatures, analyse_signatures, MixedSlotError, NestedPropertySlotError,
|
|
27
|
+
free_variables,
|
|
28
|
+
substitute, beta_reduce, ReductionLimitError,
|
|
29
|
+
eta_reduce, beta_eta_normalize,
|
|
30
|
+
resolve_lambda_scope,
|
|
31
|
+
to_fol,
|
|
32
|
+
nonempty_sort_axioms,
|
|
33
|
+
sort_membership_axioms,
|
|
34
|
+
sort_axioms,
|
|
35
|
+
subsort_axioms,
|
|
36
|
+
signature_axioms,
|
|
37
|
+
)
|
|
38
|
+
from .normalforms import to_nnf, to_pnf, to_cnf, to_dnf, to_tseitin_cnf, skolemize, is_horn
|
|
39
|
+
from .lambda_tools import has_lambdas, eliminate_lambdas, beta_reduce_step, reduce_trace
|
|
40
|
+
from .unification import unify, apply_subst
|
|
41
|
+
from .modal_translation import standard_translation, hybrid_is_valid, down_is_valid
|
|
42
|
+
from .pal import reduce_announcements
|
|
43
|
+
from .latex_input import latex_to_unicode, parse_latex
|
|
44
|
+
from .tptp_input import (
|
|
45
|
+
parse_tptp, parse_tptp_formula, load_tptp, TptpFormula,
|
|
46
|
+
parse_tptp_problem, load_tptp_problem, TptpProblem, TptpHeader,
|
|
47
|
+
parse_tff_problem, load_tff_problem,
|
|
48
|
+
)
|
|
49
|
+
from .qmltp_input import (
|
|
50
|
+
parse_qmltp_formula, parse_qmltp, load_qmltp,
|
|
51
|
+
QmltpFormula, QmltpHeader, QmltpStatus, QmltpProblem,
|
|
52
|
+
)
|
|
53
|
+
from .prover9_input import (
|
|
54
|
+
parse_prover9, parse_prover9_problem, load_prover9, Prover9Formula,
|
|
55
|
+
)
|
|
56
|
+
from .prolog_input import (
|
|
57
|
+
parse_prolog_clause, parse_prolog_program, load_prolog, PrologParsingError,
|
|
58
|
+
)
|
|
59
|
+
from .prolog_export import (
|
|
60
|
+
formula_to_prolog_clause, formula_to_prolog_program, PrologExportError,
|
|
61
|
+
)
|
|
62
|
+
from .sanitize import sanitize_names, sanitize_all, NameMapping
|
|
63
|
+
from .verbalize import to_english
|
|
64
|
+
from .derivation import CCGDerivation, reduction_derivation
|
|
65
|
+
from .frames import (
|
|
66
|
+
AXIOM_ALIASES, FRAMES, FRAME_CONDITIONS, MODAL_AXIOMS,
|
|
67
|
+
UnsupportedFrameCondition, resolve_frame, geach_axiom,
|
|
68
|
+
holds_on_finite_frame, modal_axiom, unguarded_frame_axiom,
|
|
69
|
+
)
|
|
70
|
+
from .qml import (
|
|
71
|
+
qml_translate, qml_axioms, qml_is_valid, qml_equivalent, qml_validity_formula,
|
|
72
|
+
to_thf_modal, to_isabelle_modal, BARCAN, CONVERSE_BARCAN, QML_BRIDGES,
|
|
73
|
+
)
|
|
74
|
+
from .naming import NamingError, ParsingError
|
|
75
|
+
from .spans import (
|
|
76
|
+
Span, UNKNOWN, NodeSpans, Path, SpanMap, SpannedFormula,
|
|
77
|
+
traverse, build_span_map, project_spans,
|
|
78
|
+
)
|
|
79
|
+
from .serialize import SCHEMA_VERSION, serialize, deserialize
|
|
80
|
+
from .casl_export import to_casl_spec, formula_to_casl
|
|
81
|
+
from .casl_import import parse_casl_spec, CaslSpec, CaslImportError
|
|
82
|
+
from .tptp_repair import (
|
|
83
|
+
repair_tptp_formula, repair_tptp_problem, RepairResult, Issue,
|
|
84
|
+
ProblemRepairEntry, ProblemRepairResult, TptpRepairError,
|
|
85
|
+
)
|
|
86
|
+
from .dialect_repair import repair_formula, DialectRepairResult
|
|
87
|
+
from .simplify_check import (
|
|
88
|
+
simplify_for_checking, SimplifyResult,
|
|
89
|
+
count_from_existential_chain, expand_count,
|
|
90
|
+
)
|
|
91
|
+
from .dialect_detect import detect_dialects
|
|
92
|
+
from .signature import (
|
|
93
|
+
Signature, PredicateDecl, FunctionDecl, ConstantDecl, inventory_of,
|
|
94
|
+
)
|
|
95
|
+
from ._identifiers import is_variable_name, is_bare_constant, constant_text
|
|
96
|
+
from ._atom_keys import atom_key
|
|
97
|
+
|
|
98
|
+
__all__ = [
|
|
99
|
+
# The shared modal frame registry — one table for every modal route.
|
|
100
|
+
"FRAMES", "FRAME_CONDITIONS", "MODAL_AXIOMS", "AXIOM_ALIASES",
|
|
101
|
+
"modal_axiom", "resolve_frame", "geach_axiom",
|
|
102
|
+
"holds_on_finite_frame", "unguarded_frame_axiom",
|
|
103
|
+
"UnsupportedFrameCondition",
|
|
104
|
+
"MSFLParser",
|
|
105
|
+
"Node", "Variable", "Constant", "Number", "Function",
|
|
106
|
+
"Atom", "Not", "And", "Or", "Xor", "Implies", "Iff", "Quantifier",
|
|
107
|
+
"Count", "Measure", "Cardinality", "Contrast",
|
|
108
|
+
"Z3Env",
|
|
109
|
+
"node_at", "replace_at",
|
|
110
|
+
"NamingError", "ParsingError",
|
|
111
|
+
"Span", "UNKNOWN", "NodeSpans", "Path", "SpanMap", "SpannedFormula",
|
|
112
|
+
"traverse", "build_span_map", "project_spans",
|
|
113
|
+
"SCHEMA_VERSION", "serialize", "deserialize",
|
|
114
|
+
"to_casl_spec", "formula_to_casl",
|
|
115
|
+
"parse_casl_spec", "CaslSpec", "CaslImportError",
|
|
116
|
+
"repair_tptp_formula", "repair_tptp_problem", "RepairResult", "Issue",
|
|
117
|
+
"ProblemRepairEntry", "ProblemRepairResult", "TptpRepairError",
|
|
118
|
+
"repair_formula", "DialectRepairResult",
|
|
119
|
+
"parse_prolog_clause", "parse_prolog_program", "load_prolog",
|
|
120
|
+
"PrologParsingError",
|
|
121
|
+
"formula_to_prolog_clause", "formula_to_prolog_program",
|
|
122
|
+
"PrologExportError",
|
|
123
|
+
"simplify_for_checking", "SimplifyResult",
|
|
124
|
+
"count_from_existential_chain", "expand_count",
|
|
125
|
+
"detect_dialects",
|
|
126
|
+
"is_variable_name", "is_bare_constant", "constant_text", "atom_key",
|
|
127
|
+
"Signature", "PredicateDecl", "FunctionDecl", "ConstantDecl",
|
|
128
|
+
"inventory_of",
|
|
129
|
+
"SortedQuantifier", "SortedConstant",
|
|
130
|
+
"SortedCount", "SortedCardinality",
|
|
131
|
+
"Nominal", "At", "Down",
|
|
132
|
+
"Dependence", "SlashedExists",
|
|
133
|
+
"Tensor", "With", "OPlus", "LinearImplies", "OfCourse", "One", "Top", "Zero",
|
|
134
|
+
"Product", "Under", "Over",
|
|
135
|
+
"WeakConjunction", "WeakDisjunction",
|
|
136
|
+
"StrongConjunction", "StrongDisjunction",
|
|
137
|
+
"LukNegation", "LukImplication", "LukEquivalence",
|
|
138
|
+
"LambdaVar", "Lambda", "Application",
|
|
139
|
+
"Box", "Diamond", "Knows", "Believes", "Says", "Wants",
|
|
140
|
+
"EverybodyKnows", "DistributedKnowledge", "CommonKnowledge",
|
|
141
|
+
"Always", "Eventually", "Next", "Until",
|
|
142
|
+
"Historically", "Once", "Previous", "Since",
|
|
143
|
+
"Obligatory", "Permitted",
|
|
144
|
+
"Would", "Might",
|
|
145
|
+
"Announce", "AnnounceDiamond",
|
|
146
|
+
"SecondOrderQuantifier",
|
|
147
|
+
"PredicateTerm", "Signatures", "analyse_signatures", "MixedSlotError", "NestedPropertySlotError",
|
|
148
|
+
"free_variables",
|
|
149
|
+
"substitute", "beta_reduce", "ReductionLimitError",
|
|
150
|
+
"eta_reduce", "beta_eta_normalize",
|
|
151
|
+
"resolve_lambda_scope",
|
|
152
|
+
"to_fol",
|
|
153
|
+
"nonempty_sort_axioms",
|
|
154
|
+
"sort_membership_axioms",
|
|
155
|
+
"sort_axioms",
|
|
156
|
+
"subsort_axioms",
|
|
157
|
+
"signature_axioms",
|
|
158
|
+
"to_nnf", "to_pnf", "to_cnf", "to_dnf", "to_tseitin_cnf", "skolemize", "is_horn",
|
|
159
|
+
"has_lambdas", "eliminate_lambdas", "beta_reduce_step", "reduce_trace",
|
|
160
|
+
"unify", "apply_subst",
|
|
161
|
+
"standard_translation", "hybrid_is_valid", "down_is_valid",
|
|
162
|
+
"reduce_announcements",
|
|
163
|
+
"latex_to_unicode", "parse_latex",
|
|
164
|
+
"parse_tptp", "parse_tptp_formula", "load_tptp", "TptpFormula",
|
|
165
|
+
"parse_tptp_problem", "load_tptp_problem", "TptpProblem", "TptpHeader",
|
|
166
|
+
"parse_tff_problem", "load_tff_problem",
|
|
167
|
+
"parse_prover9", "parse_prover9_problem", "load_prover9", "Prover9Formula",
|
|
168
|
+
"sanitize_names", "sanitize_all", "NameMapping",
|
|
169
|
+
"to_english",
|
|
170
|
+
"CCGDerivation", "reduction_derivation",
|
|
171
|
+
"qml_translate", "qml_axioms", "qml_is_valid", "qml_equivalent",
|
|
172
|
+
"qml_validity_formula",
|
|
173
|
+
"to_thf_modal", "to_isabelle_modal", "BARCAN", "CONVERSE_BARCAN",
|
|
174
|
+
"QML_BRIDGES",
|
|
175
|
+
"parse_qmltp_formula", "parse_qmltp", "load_qmltp",
|
|
176
|
+
"QmltpFormula", "QmltpHeader", "QmltpStatus", "QmltpProblem",
|
|
177
|
+
]
|