Welcome to the experimental folder of this branch of the Lurch LDE project. Here we gather code and content for rapidly testing, benchmarking, and prototyping design ideas for the LDE. For details about the rest of the LDE, and in particular the LogicConcept class and Matching package that this algorithm is built on, see the LDE documentation.
The main experiment currently in progress is an implementation of the $n$-compact polynomial time global validation algorithm. This is accessible via the function validate()
and its supporting tools and options.
A document is any LC environment. It may (and usually will) additionally contain declarations of type Declare
and environments of type Rule
, Proof
, Theorem
, BIH
, Substitution
and Cases
, all of which are specified by the user as part of the document. An inference is a descendant of a document that is either an environment, outermost expression, or declaration all of whose ancestors (including itself) are claims. The validate()
routine can validate any specified inference in any document.
This routine and supporting infrastructure is contained primarily in the following files.
lode.js - All lurch documents, libraries, rules, theorems, and proofs begin essentially as a string (or more generally, text). Each UI provides some way for the users and library authors to enter, save, store, load, and merge such text.
𝕃𝕠𝕕𝕖 is a node.js command line UI intended for developers. Document text is created either directly at the command prompt as short test strings, or in an external editor and saved as a file for larger documents. This file defines the 𝕃𝕠𝕕𝕖 repl and contains utilities for listing, loading, and merging such strings.
parsing.js - If the UI produces a string representing user’s content it must be parsed into an LC before validation. Currently available parsers are for putdown
and an asciimath extension of putdown that supports a small but useful subset of asciimath (http://asciimath.org) and LaTeX, which we will call Lurch Notation
. In some cases it may be easier to obtain the desired LC by first parsing the string to an intermediate LC which is then converted to a different LC by post processing what we refer to as Shorthands
- special LC content that indicate some way in which the LC needs further modification before proceeding.
interpret.js - Any LC environment can be validated by $n$-compact validation, but will usually need to be modified extensively to prepare it for validation by calling the interpret()
routine defined in this file. In particular, it will add global system declarations to the document, process all shorthands, move all global constant declarations to the top of the environment, create a rule associated with each user Theorem, move declaration bodies after the declaration, wrap all Let
declarations in an environment as needed to form Let environments, give all bound variables a canonical alpha-equivalent name, convert all rules into formulas and store information about their domains, assign unique names to symbols declared with a body, and mark all global constants throughout the document. These must all be performed in order before validation.
global-validation.js - this is the main part of the validation routine. It constructs all of the relevant instantiations, both for the $n$-compact global validation algorithm and for other validation tools that are compatible with $n$-compact validation. Currently these tools are for BIHs, Equations, Cases, Arithmetic, Algebra, and Scoping. Each of these validation tools is run and it’s validation results stored in the relevant locations in the document. Additional information, such as which user espressions lead to a particular instantiation, is stored in the instantiations as well for future reporting. Once that information is available, it is easy to validate a particular target or validate things in different ways that are determined by the options stored in the object LurchOptions
.
reporting.js - once a document is fully instanted, we can generate reports about the results. This can be as simple as putting a green checkmark or red ✗ after a conclusion, to giving entire reports about how a particular instantiation is found or what rules had something to say about a particular conclusion. The routines in this file can mine a validated document for various information, and report it in a way that is compatible with 𝕃𝕠𝕕𝕖 (terminal output).
extensions.js - contains numerous miscellaneous extensions to the LC class and subclasses that are either convenient or necessary for this code.
utils.js - contains miscellaneous generic js utilities that are not specific to this application.
CNFProp.js - Defines the CNFProp class that is necessary for converting a document into the conjunctive normal form required for checking the boolean satisfiability of the propositional form of all or part of a document. For more information see the Propositional Form tutorial.
An LC is a $n$-compact Document (or simply a doc) if it is a claim environment that has been processed and transformed as follows.
addSystemDeclaration()
- add system declarations to the documentprocessShorthands()
- process all shortHandsmoveDeclaresToTop()
- move all Declare
’s to the top (i.e., make them be the first children of the document)processTheorems()
- put a copy of every Theorem
after it as a next sibling and mark it as a Rule
and a .userRule
(unless such a copy would have no metavars).processDeclarationBodies()
- put a copy of the body of every declaration which has a body after it as a next sibling and store the declaration in the .bodyOf
attribute of the copy.processLetEnvironments()
- check that every Let (i.e. given) declaration that is not the first child of its parent is wrapped in an environment containing its scope (a Let-environment).processBindings
- assign ProperNames
x₀,x₁,x₂,...
to all bound variables to allow alpha-equivalent expressions to have the same propositional form.processRules()
- convert every Rule
to a formula and mark it .ignore
if it contains metavariables. Also rename any bound variables in it to something that cannot be entered by the user (currently, y₀,y₁,y₂...
).assignProperNames()
- assign ProperNames
to any symbol, c
in the scope of a declaration with body by appending #
followed by the putdown form of the body, e.g., c#body
(then renamed to a sequence number like c#12
for legibility). This applies to both Let
and ForSome
declarations with body.markDeclaredSymbols
- mark every symbol declared by a global Declare
declaration as a .constant
.This processing should be generally useful to any validation tool. Additionally, the following processing of the document is more specific to the $n$-compact validation algorithm.
processDomains()
- for each formula (Rule
or Part
) and each proposition they contain, store the domain (=set of metavariable names), whether or not the formula is a Weeny (contains a non-forbidden proposition containing all of the metavariables), and what its weenies are, if any (propositions containing the maximal number of metavariables, even if the formula isn’t itself a weeny formula). The only part of this that is specified by the $n$-compact validation algorithm is the definition of what is ‘forbidden’. So if we consider that to be a parameter, then this can be moved up with the previous collection of utilities that pre-process the document before validation.This algorithm and related utilties can be tested using the files in the following subfolders:
In addition to the files mentioned above, there are also some useful supporting utilities.
.test
in Lodeinitialize()
command in Lode.Here we describe the n-compact algorithm in detail as currently implemented. This is subject to a lot of change, but we will attempt to keep it up to date.
Document - an LC is considered to be a document if it consists of a single LC environment, whose children are either
Declare
- Declarations of symbols that cannot be metavariables.Rules
- given environments used as formulas.User's content
- the user’s theorems, definitions, and proofs.The Lode command loadStr(filename)
loads the file specified by filename
as a string. The file extension ‘.lurch’ can be omitted. The command loadDoc(filename)
loads the string, parses it with the Lurch Notation parser, interprets it, and validates it. Each such file can contain lines of the form include file-to-include
, which must be on a line by themselves, to recursively include other files. This is useful for specifying, e.g. what libraries to load at the top of a proof document.
To construct and validate a document it does the following.
loadStr(filename)
, or provided by a UI.Rule
, Declare
, Theorem
, Proof
, and so on i.e., that is part of user content, not interpreted from his document.LDE EFA
and ➤
)Declare
declarations to the top of the document.Theorem
and insert it below the theorem.Let
declarations in an environment as needed to form Let environments (so every Let
is a first-child and its scope is the same).x₀, x₁, ...
so that Propositional Forms are canonical for alpha-equivalence.Rules
into formulas and cache all of the information about their domains..ignore
on all Rules containing metavariables so they don’t get a prop form.Rules
with y₀, y₁, ...
which cannot be entered as part of a user’s document. (This is needed because Matching checks for variable capture, but Formula.instantiate()
does not.)Let
declaration.LurchOptions.processBIHs
is true, and if so do the following..rule
attribute to the ‘Rule’ it instantiates.LurchOptions.processEquations
is true, and if so, do the following.(= A B C D)
results in
(= A B C D)
(= A B)
(= B C)
(= C D)
:{ :EquationsRule }
. If not, exit.x=y
in the user’s content (e.g. not inside a Rule), insert the symmetric equivalences after the Equations Rule, :{ :x=y y=x }
:{ :y=x x=y }
.LHS=RHS
compute the difference between the LHS and RHS, i.e., compute diff(LHS,RHS)
.f
, x
, and y
such that LHS=f(x)
and RHS=f(y)
. For each such case, insert the instantiation :{ :x=y f(x)=f(y) }
after the Equations Rule. Additionally insert :x=y
and :y=x
as Consider
’s and the symmetric equivalences :{ :x=y y=x }
:{ :y=x x=y }
.(= A B C D)
it would insert the transitive conclusion :{ :(= A B) :(= B C) :(= C D) (= A D) }
.LurchOptions.processCases
is true, and if so, do the following.Cases
by the library author..by
equal to cases
.Inst
s or Part
s found after the rule.LurchOptions.autoCases
is true, and if so, do the following.Inst
s or Part
s found after the corresponding rule. (Note: this is generally slow except for small documents or documents with no caselike rules.)LurchOptions.processArithmetic
is true, and if so, do the following.ArithmeticRule(ring)
by the library author, where ring
is one of ℕ, ℤ, or ℚ..by
equal to arithmetic
.isArithmetic[ring](e)
command in parsing.js. If it does not, mark its validation result for arithmetic
to inapplicable
and return without doing anything further.arithmetic
to valid
or invalid
accordingly.:{ e }
after the Arithmetic rule found in step 2.LurchOptions.processAlgebra
is true, and if so, do the following.ArithmeticRule(ring)
by the library author, where ring
is one of ℕ, ℤ, or ℚ..by
equal to algebra
.lurchNotation
attribute, and let $s$ be its content (should be a string).LHS=RHS
where LHS
and RHS
do not contain =
, and mark it as return if it doesn’t because we only allow identities for now.simplify(LHS-RHS)
. If it returns $0$, mark the validation result for algebra
on $e$ to valid
. Otherwise set it to invalid
.:{ e }
after the Arithmetic rule found in step 2.E
, in the user’s document.F
, of all unfinished formulas with any max weenies.f
in F
,
p
in f
to each e
in E
.f
.f
in its .rule
attribute.e
to it’s .creators
list.given
and a LDE CI
.Part
with .ignore
true.Inst
with no .ignore
attribute.f
as .finished
. It cannot be instantiated again on future
passes because while the number of available formulas can go up on each
pass, the set of user expressions E
cannot.Let
environments, fetch them and sort them by the number of Let
s in their scope so we can check them from the inside outLet
validate it’s parent as a preemie
valid
by n-compact
Let
is deleted and all occurrences of the symbols it declares in either the scope of the deleted Let
or instantiations that do not themselves have their own copy of Let
use their ordinary symbol name instead of their ProperName (i.e., instantiation proper names are ignored for symbols that have the same .text
name as one of the symbols in the deleted Let
but aren’t in the scope of a declaration of that symbols that is, itself, inside the instantiation)Let
environment is a preemie, check all of it’s conclusions to see if they are a preemie, and mark all of their ancestors as one if one or more is found.This completess the validation algorithm.
Any LC in a document can have two kinds of attributes - LC attributes and ordinary js attributes. This validation algorithm uses many different attributes of both kinds to carry out its work in addition to those already defined for all LCs. Attributes which must be supplied by the user are saved as LC attributes as part of the document content. Attributes which can be computed from the user’s content are stored in js attributes. There are exceptions to this however, because the LC.copy()
function only copies LC attributes, not js attributes, so sometimes we use an LC attribute when having that functionality available makes the code simpler or is necessary.
The following attributes set the type of the LC.
Declare
- an LC used to define global constants. Always appears at the top of the document.Rule
- an LC that defines a rule. It must be a given environment.Theorem
- a claim environment that the user wants to prove, and then use as a new rule after that.Proof
- a claim environment that the user wants to have validate. If a Theorem immediately precedes a Proof, their order is interchanged before validation.Subs
- a special rule marked for use with the Substitution tool.BIH
- a blatant instantiation hint. Allows the user to provide an explicit instantiation of some rule in the document.Cases
- a special rule marked for use with the Cases tool.Consider
- this proposition should be added to the list of user propositions for the purpose of creating instantiations, but it has no propositional form itself, so it is neither claimed or assumed as part of the document’s propositional meaning.In addition, these LC attributes store a value.
ExpectedResult
- Stores the expected result from validating this LC. Intended primarily for testing, where the actual validation result can be compared to the expected one. Typical results are ‘valid’, ‘indeterminate’, and ‘invalid’.ID
- stores an ID number associated with this LC. Can be used by a UI to map LC feedback results to entities in the user’s original content that produced the document.ProperName
- the alternate name of a symbol used when computing propositional form.
ProperName
x₀,x₁,x₂,...
so alpha equivalent expressions have the same propositional form.c
, in the scope of a declaration of c
with a body have ProperName
formed by appending the putdown form of the body to the symbol name separated by a #
character, e.g., c#body
, so symbols with the same name that are defined differently have different propositional forms. These are then replaced by a numerical value, e.g. C#12
, for legibility.Part
- indicates this is a partial instantiation constructed during validation (still contains metavariables). It is ignored for propositional form.Inst
- indicates this is an instantiation and should be used for propositional form.validation results
- a upgraded replacement for validation result
set by the validation engine.The following js attributes store data that is computed from the user’s content, and needed for validation and reporting feedback.
.userRule
- true for the Rule copies of Theorems..bodyOf
- true for the copies of declaration bodies.domain
- stores the domain of a non-forbidden proposition or a formula (Rule
s or Part
s) containing at least one non-forbidden proposition whose domain is nonempty..isWeeny
- true for a formula that contains one or more propositions containing all of the metavariables in the formula.weenies
- the set of all maximally weeny propositions in a formula (i.e., containing the largest number of metavariables), whether or not the formula itself is weeny..domainsProcessed
- true if this document has already had all of its domain information processed and stored. Should only appear on an entire document, not on any target inside the document..rule
- the rule that this Part
or Inst
is an instantiation of..creators
- the list of user expressions that created this Part
or Inst
..pass
- which instantiation pass created the Part
or Inst
..finished
- true if the Rule or Part has been fully instantiated and is no longer available on the next pass..ignore
- true for anything that should be ignored when computing the propositional form (e.g., expressions or rules containing metavariables).numsolns
- the number of solutions found when matching the expression and formula proposition that created this Part
or Inst
.letScopes
- caches the Let scopes in the document (not targets).cat
- caches the docuement catalog in the document (not targets).userPropositions
- caches the user’s propositions (things that have a propositional form, do not contain metavariables, and are not inside a Rule
)..equation
- true if this is a binary equation (A=B) either from the user or created by the splitEquations
command.by
- currently should have the value ‘cases’ to indicate that this conclusion is a conclusion of the proof by cases rule..label
- currently should only have the value ‘cases’ on a rule to indicate that that rule is the proof by cases rule in this document.