octalgo.datalogcert.syntax
The DatalogCert Library CNRS & Université Paris-Sud, Université Paris-Saclay Copyright 2016-2019 : FormalData Original authors: Véronique Benzaken Évelyne Contejean Stefania Dumbrava
This is the first part of the original file "pengine.v" with some modifications
Added
Standard Datalog in Coq
program signature: constants and symbols as finite types and arities as finitely-supported functions
Decidable equality on pred kind
Definition pred_type_eq (x y : pred_type) := match x,y with
| Edb,Edb | Idb,Idb ⇒ true
| _,_ ⇒ false end.
| Edb,Edb | Idb,Idb ⇒ true
| _,_ ⇒ false end.
pred_type_eq is an equality
From which we derive an Equality mixin
Definition pred_type_eqMixin := EqMixin pred_type_eq_axiom.
Canonical pred_type_eqType := Eval hnf in EqType pred_type pred_type_eqMixin.
Canonical pred_type_eqType := Eval hnf in EqType pred_type pred_type_eqMixin.
Predicate symbols have a kind
Extract the value of a constant
instances for the type of constants
Canonical cons_subType := Eval hnf in [newType for of_constant].
Canonical cons_eqType := Eval hnf in EqType _ [eqMixin of constant by <: ].
Canonical cons_choiceType := Eval hnf in ChoiceType _ [choiceMixin of constant by <:].
Canonical cons_countType := Eval hnf in CountType _ [countMixin of constant by <:].
Canonical cons_subCountType := Eval hnf in [subCountType of constant].
Canonical cons_finType := Eval hnf in FinType _ [finMixin of constant by <:].
Canonical cons_subFinType := Eval hnf in [subFinType of constant].
Canonical cons_optionFinType := option_finType cons_finType.
Coercion opt_constant (c : option constant) : (option_finType cons_finType) := c.
Canonical cons_eqType := Eval hnf in EqType _ [eqMixin of constant by <: ].
Canonical cons_choiceType := Eval hnf in ChoiceType _ [choiceMixin of constant by <:].
Canonical cons_countType := Eval hnf in CountType _ [countMixin of constant by <:].
Canonical cons_subCountType := Eval hnf in [subCountType of constant].
Canonical cons_finType := Eval hnf in FinType _ [finMixin of constant by <:].
Canonical cons_subFinType := Eval hnf in [subFinType of constant].
Canonical cons_optionFinType := option_finType cons_finType.
Coercion opt_constant (c : option constant) : (option_finType cons_finType) := c.
extractors for the corresponding symbols and arguments of a "raw" ground atom
Definition sym_gatom ga := let: RawGAtom s_ga _ := ga in s_ga.
Definition arg_gatom ga := let: RawGAtom _ arg_ga := ga in arg_ga.
Lemma gatom_eta ga : ga = RawGAtom (sym_gatom ga) (arg_gatom ga).
Definition arg_gatom ga := let: RawGAtom _ arg_ga := ga in arg_ga.
Lemma gatom_eta ga : ga = RawGAtom (sym_gatom ga) (arg_gatom ga).
packing and unpacking of a "raw" ground atom; needed for the canonical inference of its instances
Definition raw_gatom_rep l := let: RawGAtom s a := l in (s, a).
Definition raw_gatom_pre l := let: (s, a) := l in RawGAtom s a.
Definition raw_gatom_pre l := let: (s, a) := l in RawGAtom s a.
cancelation lemma for "raw" ground atoms
"raw" ground atom instances
Canonical raw_gatom_eqType :=
Eval hnf in EqType raw_gatom (CanEqMixin raw_gatom_repK).
Canonical raw_gatom_choiceType :=
Eval hnf in ChoiceType raw_gatom (CanChoiceMixin raw_gatom_repK).
Canonical raw_gatom_countType :=
Eval hnf in CountType raw_gatom (CanCountMixin raw_gatom_repK).
End RawGAtomInstances.
Eval hnf in EqType raw_gatom (CanEqMixin raw_gatom_repK).
Canonical raw_gatom_choiceType :=
Eval hnf in ChoiceType raw_gatom (CanChoiceMixin raw_gatom_repK).
Canonical raw_gatom_countType :=
Eval hnf in CountType raw_gatom (CanCountMixin raw_gatom_repK).
End RawGAtomInstances.
Ground Atoms:
A ground atom gatom packs a "raw" ground atom and a boolean well-formedness condition
ground atom record
ground atom instances
Canonical gatom_subType := Eval hnf in [subType for uga].
Canonical gatom_eqType := Eval hnf in EqType _ [eqMixin of gatom by <:].
Canonical gatom_choiceType := Eval hnf in ChoiceType _ [choiceMixin of gatom by <:].
Canonical gatom_countType := Eval hnf in CountType _ [countMixin of gatom by <:].
Canonical gatom_subCountType := Eval hnf in [subCountType of gatom].
Canonical gatom_eqType := Eval hnf in EqType _ [eqMixin of gatom by <:].
Canonical gatom_choiceType := Eval hnf in ChoiceType _ [choiceMixin of gatom by <:].
Canonical gatom_countType := Eval hnf in CountType _ [countMixin of gatom by <:].
Canonical gatom_subCountType := Eval hnf in [subCountType of gatom].
Gives back the arguments of the atom as a tuple of the right length
using the well formedness constraint
Given an i smaller than the arity gives back the ith argument
Definition nth_cons (a : gatom) (i : 'I_(arity (sym_gatom a))) : constant :=
tnth (arg_wf_gatom a) i.
tnth (arg_wf_gatom a) i.
maximal symbol arity
Ground atoms are a finite type (uses the max arity)
corresponding finite type for ground atoms, packing a symbol type and a tuple of constants
of length bounded by the maximal symbol arity
Definition gatom_fenc (ga : gatom) : gatom_enc :=
let: GAtom ga proof := ga in
existT _ (Ordinal (max_ar_bound (sym_gatom ga))) (sym_gatom ga, Tuple proof).
let: GAtom ga proof := ga in
existT _ (Ordinal (max_ar_bound (sym_gatom ga))) (sym_gatom ga, Tuple proof).
partial cancelation lemma for ground atoms
canonical instances for ground atoms
Canonical gatom_finType := Eval hnf in FinType gatom (PcanFinMixin fenc_gatomK).
Canonical gatom_subFinType := [subFinType of gatom].
Canonical gatom_subFinType := [subFinType of gatom].
We can access the ith argument of a gatom with predicate whose
arity is greater than i
Lemma oob_gatom_args (ga : gatom) (ind : 'I_(arity (sym_gatom ga))) :
nth_error (arg_gatom ga) ind ≠ None.
nth_error (arg_gatom ga) ind ≠ None.
Ground Clauses:
A ground clause gclause packs a ground atom head and a body list of ground atoms *Important:* Our definition differs from the original one to keep a bound on the size of bodies
head and body extractors for ground clauses
Definition head_gcl gcl := let: GClause h b := gcl in h.
Definition body_gcl gcl := let: GClause h b := gcl in b.
Definition body_gcl gcl := let: GClause h b := gcl in b.
Definition gclause_eq gcl1 gcl2 := match gcl1,gcl2 with
| GClause h1 l1, GClause h2 l2 ⇒ (h1 == h2) && (l1 == l2) end.
Lemma gclause_eq_refl gcl : gclause_eq gcl gcl.
| GClause h1 l1, GClause h2 l2 ⇒ (h1 == h2) && (l1 == l2) end.
Lemma gclause_eq_refl gcl : gclause_eq gcl gcl.
This is indeed an equality for clauses
Lemma gclause_eq_inv gcl1 gcl2 : gclause_eq gcl1 gcl2 → gcl1 = gcl2.
Lemma gclause_eq_axiom : Equality.axiom gclause_eq.
Definition gclause_eqMixin := EqMixin gclause_eq_axiom.
Lemma gclause_eq_axiom : Equality.axiom gclause_eq.
Definition gclause_eqMixin := EqMixin gclause_eq_axiom.
Definition of the equality type
Projection of the clause to a pair head, body list
Definition gclause_rep cl := let: GClause hd bd := cl in (hd, bd).
Definition gclause_pre cl := let: (hd, bd) := cl in GClause hd bd.
Lemma gclause_repK : cancel gclause_rep gclause_pre.
Canonical gclause_choiceType := Eval hnf in ChoiceType gclause (CanChoiceMixin gclause_repK).
Canonical gclause_countType := Eval hnf in CountType gclause (CanCountMixin gclause_repK).
Canonical gclause_finType := Eval hnf in FinType gclause (CanFinMixin gclause_repK).
Definition gclause_pre cl := let: (hd, bd) := cl in GClause hd bd.
Lemma gclause_repK : cancel gclause_rep gclause_pre.
Canonical gclause_choiceType := Eval hnf in ChoiceType gclause (CanChoiceMixin gclause_repK).
Canonical gclause_countType := Eval hnf in CountType gclause (CanCountMixin gclause_repK).
Canonical gclause_finType := Eval hnf in FinType gclause (CanFinMixin gclause_repK).
set of all symbols of a given interpretation
satisfiability of a ground clause gcl w.r.t a given interpretation i:
if all body atoms belong to i, the head should also belong to i
Injection of constants in terms
corresponding sigma type encoding for terms; needed for canonical instance inference
converting a termRep encoding into the corresponding term type
cancelation lemma for terms
canonical instances for terms
Canonical term_eqType := Eval hnf in EqType term (CanEqMixin term_repK).
Canonical term_choiceType := Eval hnf in ChoiceType term (CanChoiceMixin term_repK).
Canonical term_countType := Eval hnf in CountType term (CanCountMixin term_repK).
Canonical term_finType := Eval hnf in FinType term (CanFinMixin term_repK).
Canonical term_choiceType := Eval hnf in ChoiceType term (CanChoiceMixin term_repK).
Canonical term_countType := Eval hnf in CountType term (CanCountMixin term_repK).
Canonical term_finType := Eval hnf in FinType term (CanFinMixin term_repK).
Inject raw ground atoms in raw atoms
Definition to_raw_atom gra :=
RawAtom (sym_gatom gra) [seq Val x | x <- arg_gatom gra].
Section RawAtomInstances.
RawAtom (sym_gatom gra) [seq Val x | x <- arg_gatom gra].
Section RawAtomInstances.
packing and unpacking of raw atoms
Definition raw_atom_rep l := let: RawAtom s a := l in (s, a).
Definition raw_atom_pre l := let: (s, a) := l in RawAtom s a.
Definition raw_atom_pre l := let: (s, a) := l in RawAtom s a.
cancelation lemma for raw atoms
canonical instances for raw atoms
Canonical raw_atom_eqType := Eval hnf in EqType raw_atom (CanEqMixin raw_atom_repK).
Canonical raw_atom_choiceType := Eval hnf in ChoiceType raw_atom (CanChoiceMixin raw_atom_repK).
Canonical raw_atom_countType :=
Eval hnf in CountType raw_atom (@CanCountMixin (prod_countType symtype (seq_countType term_finType)) _ _ _ raw_atom_repK).
End RawAtomInstances.
Canonical raw_atom_choiceType := Eval hnf in ChoiceType raw_atom (CanChoiceMixin raw_atom_repK).
Canonical raw_atom_countType :=
Eval hnf in CountType raw_atom (@CanCountMixin (prod_countType symtype (seq_countType term_finType)) _ _ _ raw_atom_repK).
End RawAtomInstances.
extractors for the corresponding symbols and arguments of an atom
Definition sym_atom a := let: RawAtom s_a _ := a in s_a.
Definition arg_atom a := let: RawAtom _ arg_a := a in arg_a.
Definition arg_atom a := let: RawAtom _ arg_a := a in arg_a.
A few useful lemmas and auxiliary functions
Preservation of well formedness by the translation to raw atom
Translates ground atom to atom using lemma above
Extract the args as a tuple from an atom
Given an atom and i smaller than the arity, gets the ith arg
Given a predicate and a ground atom having this pred, access one
argument of this ground atom (using dependent type on arity)
Definition nth_cons_rew_dep pred (ga : {x : gatom | sym_gatom x == pred}) (i : 'I_(arity pred)) : constant.
Defined.
Defined.
We can access the ith argument of an atom with predicate whose
arity is greater than i
atom instances
Canonical atom_subType := Eval hnf in [subType for ua].
Canonical atom_eqType := Eval hnf in EqType _ [eqMixin of atom by <: ].
Canonical atom_choiceType := Eval hnf in ChoiceType _ [choiceMixin of atom by <:].
Canonical atom_countType := Eval hnf in CountType _ [countMixin of atom by <:].
Canonical atom_eqType := Eval hnf in EqType _ [eqMixin of atom by <: ].
Canonical atom_choiceType := Eval hnf in ChoiceType _ [choiceMixin of atom by <:].
Canonical atom_countType := Eval hnf in CountType _ [countMixin of atom by <:].
We use as represention the triple with
- number of arguments (smaller than max_r)
- symbol
- |args|-tuples of terms
We can inject atom in this encoding
Definition atom_fenc (a : atom) : atom_enc :=
let: Atom a proof := a in
existT _ (Ordinal (max_ar_bound (sym_atom a))) (sym_atom a, Tuple proof).
let: Atom a proof := a in
existT _ (Ordinal (max_ar_bound (sym_atom a))) (sym_atom a, Tuple proof).
We can invert this encoding as long as we respect arity
This is a true injection
Lemma fenc_atomK : pcancel atom_fenc fenc_atom.
End AtomFinType.
Canonical atom_finType := Eval hnf in FinType atom (PcanFinMixin fenc_atomK).
Canonical atom_subFinType := [subFinType of atom].
End AtomFinType.
Canonical atom_finType := Eval hnf in FinType atom (PcanFinMixin fenc_atomK).
Canonical atom_subFinType := [subFinType of atom].
A clause pack an atom head and a list of at most size n of atoms.
Our definition differs from the original one
packing and unpacking of clauses
Definition clause_rep cl := let: Clause hd bd := cl in (hd, bd).
Definition clause_pre cl := let: (hd, bd) := cl in Clause hd bd.
Definition clause_pre cl := let: (hd, bd) := cl in Clause hd bd.
cancelation lemma for clauses
clause instances
Canonical clause_eqType := Eval hnf in EqType clause (CanEqMixin clause_repK).
Canonical clause_choiceType := Eval hnf in ChoiceType clause (CanChoiceMixin clause_repK).
Canonical clause_choiceType := Eval hnf in ChoiceType clause (CanChoiceMixin clause_repK).
Added instances using the bound on the size of the body
Canonical clause_countType := Eval hnf in CountType clause (CanCountMixin clause_repK).
Canonical clause_finType := Eval hnf in FinType clause (CanFinMixin clause_repK).
End ClauseInstances.
Canonical clause_finType := Eval hnf in FinType clause (CanFinMixin clause_repK).
End ClauseInstances.
extractors for the corresponding head, body and atoms of a clause
Definition head_cl cl := let: Clause h b := cl in h.
Definition body_cl cl := let: Clause h b := cl in b.
Definition atoms_cl cl := [:: head_cl cl & body_cl cl].
Definition body_cl cl := let: Clause h b := cl in b.
Definition atoms_cl cl := [:: head_cl cl & body_cl cl].
clause head symbols
all clause symbols
all head symbols of a program
all program symbols
all program atoms
Ground valuations and their application
Definition gr := finfun_finType (ordinal_finType n) cons_finType.
Implicit Types (g : gr) (t : term) (ra : raw_atom) (a : atom)
(cl : clause) (hd : atom) (tl : seq atom).
Implicit Types (g : gr) (t : term) (ra : raw_atom) (a : atom)
(cl : clause) (hd : atom) (tl : seq atom).
term grounding
raw atom grounding
the grounding of a well-formed ground atom is well-formed
atom grounding
Grounding on a list of atoms
clause grounding
Definition gr_cl g cl :=
GClause (gr_atom g (head_cl cl)) (wmap (gr_atom g) (body_cl cl)).
End Grounding.
Section Theory.
GClause (gr_atom g (head_cl cl)) (wmap (gr_atom g) (body_cl cl)).
End Grounding.
Section Theory.
Extract constant from term (as a list of at most one element)
atom constants
atom list constants
clause constants
term variables
"raw" atom variables
atom variables
atom list variables
Extract variables from a clauses (as a set)
Definition cl_vars (cl : clause) : {set 'I_n} := tail_vars (body_cl cl).
Lemma raw_atom_vars_cons_sub g args h :
raw_atom_vars (RawAtom g args) \subset raw_atom_vars (RawAtom g (h::args)).
Lemma raw_atom_vars_cons_sub g args h :
raw_atom_vars (RawAtom g args) \subset raw_atom_vars (RawAtom g (h::args)).
Lemma tail_vars_cons x a tl : x \in tail_vars tl → x \in tail_vars (a :: tl).
Lemma tail_vars_sub_cons a tl : tail_vars tl \subset tail_vars (a :: tl).
Lemma tail_vars_consUP (tl : seq atom) (a : atom) :
tail_vars (a :: tl) = tail_vars [:: a] :|: tail_vars tl.
Lemma tail_vars_sub_cons a tl : tail_vars tl \subset tail_vars (a :: tl).
Lemma tail_vars_consUP (tl : seq atom) (a : atom) :
tail_vars (a :: tl) = tail_vars [:: a] :|: tail_vars tl.
If v is in the vars of a raw atom, adding a new term to the list of
arguments does not change this fact (note raw atoms are untyped)
Lemma raw_atom_vars_cons v fa args h : v \in raw_atom_vars (RawAtom fa args)
→ v \in raw_atom_vars (RawAtom fa (h::args)).
→ v \in raw_atom_vars (RawAtom fa (h::args)).
If a var is in an atom and the atom in a body (list of atom),
then the var is in the body
The vars of an empty body is the empty set
Lemma tail_vars_nil : tail_vars [::] = set0.
Lemma tail_vars_1 (a:atom) : tail_vars [:: a] = atom_vars a.
Lemma tail_vars_1 (a:atom) : tail_vars [:: a] = atom_vars a.
program safety: all clauses should be safe
Safety of deduced facts (in the IDB) - added
A clause has a safe head if its head predicate is of kind IDB
Definition safe_cl_hd cl :=
predtype (hsym_cl cl) == Idb.
Definition prog_safe_hds p := all safe_cl_hd p.
predtype (hsym_cl cl) == Idb.
Definition prog_safe_hds p := all safe_cl_hd p.
An interpretation is a "safe edb" if all its atoms have symbols
of type edb
Definition clauses_var_intersect (cl1 cl2 : clause) : bool :=
tail_vars (body_cl cl1) :&: tail_vars (body_cl cl2) != set0.
tail_vars (body_cl cl1) :&: tail_vars (body_cl cl2) != set0.
Constraint on P: clauses sharing variables in a program would
mean they are equals
Definition vars_not_shared (p : program) : bool :=
[∀ cl1 in p, ∀ cl2 in p,
(clauses_var_intersect cl1 cl2) ==> (cl1 == cl2)].
[∀ cl1 in p, ∀ cl2 in p,
(clauses_var_intersect cl1 cl2) ==> (cl1 == cl2)].
If the constraint vars_not_shared is fullfilled on P and if we
have a variable v that is in both cl1 and cl2 clauses of P, then
cl1 and cl2 are the same clause.
Lemma vns_cl_eq (p : program) (cl1 cl2 : clause) (v : 'I_n) :
v \in (tail_vars (body_cl cl1)) → v \in (tail_vars (body_cl cl2)) →
cl1 \in p → cl2 \in p → vars_not_shared p → cl1 = cl2.
Definition is_var (t : term) :=
match t with
Val _ ⇒ false
| Var _ ⇒ true end.
Definition only_variables_atom (a : atom) :=
all is_var (arg_atom a).
Definition only_variables_head (cl : clause) :=
only_variables_atom (head_cl cl).
Definition only_variables_in_heads (p : program) :=
all only_variables_head p.
v \in (tail_vars (body_cl cl1)) → v \in (tail_vars (body_cl cl2)) →
cl1 \in p → cl2 \in p → vars_not_shared p → cl1 = cl2.
Definition is_var (t : term) :=
match t with
Val _ ⇒ false
| Var _ ⇒ true end.
Definition only_variables_atom (a : atom) :=
all is_var (arg_atom a).
Definition only_variables_head (cl : clause) :=
only_variables_atom (head_cl cl).
Definition only_variables_in_heads (p : program) :=
all only_variables_head p.
Program Satisfiability
A program is true in i, if all grounding of its clauses are true