Atoms, Facts, Rules and the like #
In this file, we define the next layers of building blocks above terms.
This includes first and foremost Atom and Fact but also
Rule, RuleSet, Database and KnowledgeBase to name a few.
The atom-like datastructures are all expressed in terms of a GeneralizedAtom. This will turn out convenient when defining substitutions and homomorphisms next since these can (for the most part) just be defines as generic mapping over GeneralizedAtom.
A GeneralizedAtom consists of a predicate symbol and a list of terms of an arbitrary type such that the number of terms matches the predicate's arity.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Atom #
An Atom is a GeneralizedAtom with SkolemTerms.
Equations
- Atom sig = GeneralizedAtom sig (SkolemTerm sig)
Instances For
FunctionFreeAtom #
A FunctionFreeAtom is a GeneralizedAtom with VarOrConsts.
Equations
- FunctionFreeAtom sig = GeneralizedAtom sig (VarOrConst sig)
Instances For
Using VarOrConst.filterVars, we can obtain all variables from the terms of the FunctionFreeAtom.
Equations
Instances For
Using VarOrConst.filterConsts, we can obtain all constants from the terms of the FunctionFreeAtom.
Equations
Instances For
We can skolemize a FunctionFreeAtom by skolemizing all its VarOrConsts. This yields an Atom.
Equations
- FunctionFreeAtom.skolemize ruleId disjunctIndex frontier a = { predicate := a.predicate, terms := List.map (VarOrConst.skolemize ruleId disjunctIndex frontier) a.terms, arity_ok := ⋯ }
Instances For
A variable occurs in variables iff it is a term of the `FunctionFreeAtom.
A constant occurs in constants iff it is a term of the `FunctionFreeAtom.
The number of terms remains unchanged when Skolemizing.
If a a VarOrConst occurs in the terms of the FunctionFreeAtom, then the Skolemized VarOrConst occurs in the Skolemized Atom.
FunctionFreeConjunction #
A conjunction of FunctionFreeAtoms $p(x, y) \land q(y)$ can simply be represented as a list of FunctionFreeAtoms.
Equations
- FunctionFreeConjunction sig = List (FunctionFreeAtom sig)
Instances For
The terms of a FunctionFreeConjunction are the terms of all its atoms.
Equations
- conj.terms = List.flatMap GeneralizedAtom.terms conj
Instances For
The vars of a FunctionFreeConjunction are the variables of all its atoms.
Equations
- conj.vars = List.flatMap FunctionFreeAtom.variables conj
Instances For
The consts of a FunctionFreeConjunction are the constants of all its atoms.
Equations
- conj.consts = List.flatMap FunctionFreeAtom.constants conj
Instances For
The predicates of a FunctionFreeConjunction are the predicates of all its atoms.
Equations
- conj.predicates = List.map GeneralizedAtom.predicate conj
Instances For
Different from the definition, we can also say that a variable is in variables iff there is a FunctionFreeAtom in the conjunction that features the variable as a term.
Different from the definition, we can also say that a constant is in constants iff there is a FunctionFreeAtom in the conjunction that features the constant as a term.
(Disjunctive) (Existential) Rule #
A disjunctive existential rule, or simply Rule, formally is an expression of the form
$$∀ \vec{x}, \vec{y}. B(x, y) \to \bigvee_{i = 1}^{k} \exists \vec{z}_i. H_i(y_i, z_i)$$
where $B,H_1,\dots,H_k$ are conjunctions of function free atoms, $y$ is exactly the union of all $y_i$
and $x$, $y$, and all $z_i$ are disjoint lists of variables. $y$ is called frontier. $B$ is called body and the $H_i$ are called heads.
We call a rule determinstic if $k = 1$ so if the head is merely a conjunction.
To represent this formal definition in Lean, we use a structure with a FunctionFreeConjunction for the body and a list of FunctionFreeConjunctions for the disjunction in the head. For bookkeeping each rule also gets an id. That's it!
The frontier variables can simply be defined as the variables occurring both in body and head and the existential variables can be indentified as the variables that occur only in the head, without the need for explicit quantification.
The definition of a Rule as discussed above.
- id : Nat
- body : FunctionFreeConjunction sig
- head : List (FunctionFreeConjunction sig)
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
This function returns the frontier variables that occur in a given head disjunct. This is a sublist of all the frontier variables.
Equations
Instances For
This returns all the frontier variables of the rule, i.e. the variables that occur in both body and some head.
Equations
Instances For
The pure_body_vars are the variables from the body that are not in the frontier.
Equations
- r.pure_body_vars = List.filter (fun (x : sig.V) => decide ¬x ∈ r.frontier) r.body.vars
Instances For
We call a rule isDatalog if it does not contain existential variables, i.e. if all head variables occur in the body.
Equations
Instances For
We call a rule isDeterministic if it has exactly one head disjunct.
Instances For
The predicate symbols of a rule are just the predicate symbols from the body and all heads.
Equations
Instances For
The constants of a rule are just the constants from the body and all heads.
Equations
- r.constants = r.body.consts ++ List.flatMap (fun (conj : FunctionFreeConjunction sig) => conj.consts) r.head
Instances For
Sometimes we require only the constants from the heads and therefore we define them here.
Equations
- r.head_constants = List.flatMap (fun (conj : FunctionFreeConjunction sig) => conj.consts) r.head
Instances For
The existential variables for a given head are simply the variables from the head that are not in the frontier.
Equations
Instances For
The Skolem function symbols of a rule are all SkolemFS with the rule id, all possible head indices and the respective existential variables.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A variable is a frontier variable if and only if it is a frontier variable in some head disjunct.
A variable is in the frontier of a head if it is in the frontier of the rule and occurs as a term in the given head.
All frontier variables occur in the body.
The frontier variables in a given head occur in the list of variables for the same head.
The head constants of the rule are also constants of the whole rule.
RuleSet and RuleList #
A RuleSet is a Set (Rule sig) where rules are uniquely identified by their id.
Instances For
A RuleList is a List (Rule sig) where rules are uniquely identified by their id.
Instances For
RuleSet #
A RuleSet is is deterministic if each rule is.
Equations
- rs.isDeterministic = ∀ (r : Rule sig), r ∈ rs.rules → r.isDeterministic = true
Instances For
The predicate symbols of a RuleSet are the predicate symbols from all rules.
Instances For
The head constants of a RuleSet are the head constants from all rules.
Instances For
The Skolem function symbols of a RuleSet are the Skolem function symbols from all rules.
Instances For
If the RuleSet is finite, so are the predicates.
If the RuleSet is finite, so are the head_constants.
If the RuleSet is finite, so are the skolem_functions.
The head_constants of a RuleSet are a subset of the constants.
RuleList #
A rule that we get by id is indeed the rule that the id belongs to.
Facts and FunctionFreeFacts #
A Fact is a GeneralizedAtom with GroundTerms.
Equations
- Fact sig = GeneralizedAtom sig (GroundTerm sig)
Instances For
A FunctionFreeFact is a GeneralizedAtom with constants.
Equations
- FunctionFreeFact sig = GeneralizedAtom sig sig.C
Instances For
The constants of a Fact are the constants of all terms.
Equations
Instances For
The function_symbols of a Fact are the function symbols of all terms.
Equations
Instances For
A Fact is function free, if each term is a constant.
Equations
- f.isFunctionFree = ∀ (t : GroundTerm sig), t ∈ f.terms → ∃ (c : sig.C), t = GroundTerm.const c
Instances For
If a Fact isFunctionFree, then we can convert it to a FunctionFreeFact.
Equations
Instances For
A FunctionFreeFact can always be converted to a Fact.
Equations
Instances For
A Fact obtained from a FunctionFreeFact isFunctionFree.
Converting a FunctionFreeFact to a Fact and back yields the initial FunctionFreeFact.
Converting a Fact to a FunctionFreeFact and back yields the initial Fact.
FactSet #
The predicate symbols of a FactSet are the predicate symbols from all facts.
Instances For
The terms of a FactSet are the terms from all facts.
Instances For
The function symbols of a FactSet are the function symbols from all facts.
Instances For
A FactSet is function free if all of its facts are.
Equations
- fs.isFunctionFree = ∀ (f : Fact sig), f ∈ fs → f.isFunctionFree
Instances For
When converting a list to a FactSet, the terms remain the same.
The a FactSet is a subset of another, then their terms share this subset relation.
The terms of the union of two FactSets are the union of the terms of both sets.
If a FactSet is finite, so are its terms.
When converting a list to a FactSet, the constants remain the same.
The constants of the union of two FactSets are the union of the constants of both sets.
If a FactSet is finite, so are its constants.
A FactSet is finite if both its predicates and terms are. This holds since the fact set must be a subset of all facts that can possibly be constructed using the prediactes and terms available. This overapproximation is easily shown to be finite.
For a list of terms in a given FactSet, we can find a list of facts in the fact set such that all the terms from the list occur in the list of facts.
Database #
A Database is a finite set of FunctionFreeFacts.
Instances For
Any Database can trivially be converted to a finite and function free FactSet.
Equations
Instances For
Each Database has a finite set of constants.
Equations
Instances For
When converting a Database to a FactSet, the constants remain the same.
KnowledgeBase #
A KnowledgeBase is a pair of a Database and a RuleSet. Note that usually the RuleSet is enforced to be finite but we only restrict this in places where we really need this.
Instances For
A KnowledgeBase is determinstic if the underlying RuleSet is.
Equations
- kb.isDeterministic = kb.rules.isDeterministic