octalgo.datalogcert.subs
The DatalogCert Library CNRS & Université Paris-Sud, Université Paris-Saclay Copyright 2016-2019 : FormalData Original authors: Véronique Benzaken Évelyne Contejean Stefania Dumbrava
Second part of the original file "pengine.v" with some modifications
Require Import syntax.
Require Import bigop_aux.
Require Import utils.
Require Import finseqs.
Set Implicit Arguments.
Section Substitutions.
Definition sub := finfun_finType (ordinal_finType n) (option_finType cons_finType).
Coercion opt_sub (s : option sub) : (option_finType sub) := s.
Coercion opt_sub (s : option sub) : (option_finType sub) := s.
empty substitution
For each variable, either there is a constant mapped or None
Added notion of composition of substitutions: not exactly sub union as there
is a priority on s1
empty is neutral element for subU
Lemma subU_0l (s : sub) : subU emptysub s = s.
Lemma subU_0r (s : sub) : s = subU emptysub s.
Implicit Types (s : sub) (t : term) (a : atom) (v : 'I_n)
(b : 'I_n × syntax.constant).
Lemma subU_0r (s : sub) : s = subU emptysub s.
Implicit Types (s : sub) (t : term) (a : atom) (v : 'I_n)
(b : 'I_n × syntax.constant).
Variable is mapped/free by the substitution s
Binding b belongs to s
mem_binding = \in to be used as generic predicate
Definition eqbind_class := sub.
Coercion pred_of_eq_bind (s : eqbind_class) : pred_class := [eta mem_binding s].
Canonical mem_bind_symtype := mkPredType mem_binding.
Lemma mem_bindE s b : b \in s = (s b.1 == Some b.2).
Definition inE_bis := (mem_bindE, inE).
Coercion pred_of_eq_bind (s : eqbind_class) : pred_class := [eta mem_binding s].
Canonical mem_bind_symtype := mkPredType mem_binding.
Lemma mem_bindE s b : b \in s = (s b.1 == Some b.2).
Definition inE_bis := (mem_bindE, inE).
Definition sub_st s1 s2 :=
[∀ v : 'I_n, if s1 v is Some b1 then (v, b1) \in s2 else true].
Notation "A \sub B" := (sub_st A B)
(at level 70, no associativity) : bool_scope.
[∀ v : 'I_n, if s1 v is Some b1 then (v, b1) \in s2 else true].
Notation "A \sub B" := (sub_st A B)
(at level 70, no associativity) : bool_scope.
reflection lemma for substitution ordering
reflexivity of substitution ordering
transitivity of substitution ordering
any substitution extends the empty substitution
Value of substitution on variable added
Adding a binding is idempotent
More lemmas: If s1 and s2 do not bind v, adding a binding on v on the
composition or composing the substitution after adding v gives
the same result
Lemma subU_addl v c (s1 s2 : sub) : s1 v = None → s2 v = None
→ (add (subU s1 s2) v c) = subU (add s1 v c) s2.
→ (add (subU s1 s2) v c) = subU (add s1 v c) s2.
If binding are on different variables we can permute the
additions of those binding to s
Definition sterm s t : term :=
match t with
| Val d ⇒ Val d
| Var v ⇒ if s v is Some d
then Val d
else Var v
end.
match t with
| Val d ⇒ Val d
| Var v ⇒ if s v is Some d
then Val d
else Var v
end.
Empty term substitution application
Substitution extension for terms
Instantiation function that, for a given atom a, takes a substitution s
and returns the corresponding substituted atom
Atom symbols are preserved by substitution instantiation
The ground atom that is the result of applying s to a if any
Atom Substitution Extensions Lemma:
Let s1, s2 be two substitutions. If s2 extends s1 and s1 instantiates an atom a to a ground atom ga, then s2 also instantitates a to ga.
Tail substitution
Lifting of a ground tail to tail
Grounding of atom list
The set of variables also decrease when we use a list of atoms.
Composition of substitutions giving a ground atom
Lemma satomeq_subU a ga s1 s2 :
satom (satom a s1) s2 = to_atom ga
→ satom a (subU s1 s2) = to_atom ga.
satom (satom a s1) s2 = to_atom ga
→ satom a (subU s1 s2) = to_atom ga.
Same as above but generalized to a list of atoms (body of clause)
Lemma staileq_subU tl gtl s1 s2 :
stail [seq satom a s1 | a <- tl] s2 = [seq to_atom ga | ga <- gtl]
→ stail tl (subU s1 s2) = [seq to_atom ga | ga <- gtl].
stail [seq satom a s1 | a <- tl] s2 = [seq to_atom ga | ga <- gtl]
→ stail tl (subU s1 s2) = [seq to_atom ga | ga <- gtl].
Definition scl s (cl : clause) : clause :=
match cl with
| Clause h tl ⇒ Clause (satom h s) (wmap (fun a ⇒ satom a s) tl) end.
End Substitutions.
match cl with
| Clause h tl ⇒ Clause (satom h s) (wmap (fun a ⇒ satom a s) tl) end.
End Substitutions.
Export the notation
Notation "A \sub B" := (sub_st A B)
(at level 70, no associativity) : bool_scope.
Hint Resolve substss subst0s.
(at level 70, no associativity) : bool_scope.
Hint Resolve substss subst0s.
Section NoDepGrounding.
Implicit Types (s : sub) (t : term) (a : atom) (v : 'I_n)
(b : 'I_n × syntax.constant).
Implicit Types (s : sub) (t : term) (a : atom) (v : 'I_n)
(b : 'I_n × syntax.constant).
default element
Definition gr_term_def s t : syntax.constant :=
match t with
| Val c ⇒ c
| Var i ⇒ odflt def (s i)
end.
match t with
| Val c ⇒ c
| Var i ⇒ odflt def (s i)
end.
We can use the above def, or first apply the definition and then
ground using the empty substitution.
If, when instantiating a term t with a substitution s, we obtain a constant c,
then we obtain c also when grounding t with s using the default element def.
If t1 has less variables than t2 (reminder at most one), then
if s applied to t2 gives a constant, so does s applied to t1
Lemma gr_term_sub t1 t2 s d (t_sub : term_vars t1 \subset term_vars t2) :
sterm s t2 = Val d → ∃ e, sterm s t1 = Val e.
sterm s t2 = Val d → ∃ e, sterm s t1 = Val e.
Non dependent grounding on raw atoms
grounding a raw atom ra with a substitution s and the default element def
Definition gr_raw_atom_def s ra : raw_gatom :=
RawGAtom (sym_atom ra) (map (gr_term_def s) (arg_atom ra)).
RawGAtom (sym_atom ra) (map (gr_term_def s) (arg_atom ra)).
Let s1 and s2 be two substitutions. For each variable v,
either s1 or s2 is undefined and the other coincide with s.
Then grounding a raw atom with s2 and then s1 is the same as
grounding with s
Lemma gr_raw_atom_scl_eq (s s1 s2 : sub) ra :
(∀ v, (s1 v = s v ∧ s2 v = None) ∨ (s2 v = s v ∧ s1 v = None))
→ gr_raw_atom_def s ra = gr_raw_atom_def s1 (sraw_atom ra s2).
(∀ v, (s1 v = s v ∧ s2 v = None) ∨ (s2 v = s v ∧ s1 v = None))
→ gr_raw_atom_def s ra = gr_raw_atom_def s1 (sraw_atom ra s2).
Let a be an atom and s a substitution. If, when instantiating a with s, we obtain
the ground atom ga, then, when grounding a with s and the default element def, we also
obtain ga.
Let ga be a ground atom. If we lift it to an atom and ground it with a substitution
s and a default element def, ga is preserved.
Definition gr_cl_def s cl :=
GClause (gr_atom_def s (head_cl cl)) (wmap (gr_atom_def s) (body_cl cl)).
GClause (gr_atom_def s (head_cl cl)) (wmap (gr_atom_def s) (body_cl cl)).
From grounding to substitution
Applied to a term, a grounding gives as the associated subst
If s is defined on t, applying it on t gives as applying its
associated grounding
The domain of the empty subsitution is the empty set
domain of a "singleton sub" is the relevant variable - added
equality of a "singleton sub" - added
Lemma eq_singlesub s v c :
dom s = [set v]
→ s v = Some c
→ s = add emptysub v c.
Lemma sub_dom (s1 s2 : sub) :
s1 \sub s2 → dom s1 \subset dom s2.
dom s = [set v]
→ s v = Some c
→ s = add emptysub v c.
Lemma sub_dom (s1 s2 : sub) :
s1 \sub s2 → dom s1 \subset dom s2.
If the domain of s contains all the variables of ato, then
applying s as a grounding to ato with default value gr gives the
same result as applying s as a regular substitution.
Lemma to_atom_satom_eq (s : sub) ato : atom_vars ato \subset dom s →
to_atom (gr_atom_def s ato) = satom ato s.
to_atom (gr_atom_def s ato) = satom ato s.
Two substitution having the same domain and such that one is smaller than
the other are in fact identical.
For variables in the domain substitution and grounding coincide
If domain of substitution is empty, then s is the empty substitution
The domain of a set of substitution is the union of the domain of its members
The domain of the set of substitution reduced to the empty substitution is empty
The restriction has a smaller domain
Its domain is in fact also included in t (the restriction)
For v in t, if s v is defined, then so is the restriction and it
gives the same result.
Restricting a substitution to a set that contains its domain does
not change the substitution
Restricting the empty sub does not change it.
Let t1 and t2 disjoint, v in t1, the restriction of sp to t2
is the same as the restriction of sp augmented with a binding for v to
t2
Lemma add_typed_untyped v (t1 t2 : {set 'I_n}) c sp :
(v \in t1) → [disjoint t1 & t2] →
sub_filter sp t2 = sub_filter (add sp v c) t2.
(v \in t1) → [disjoint t1 & t2] →
sub_filter sp t2 = sub_filter (add sp v c) t2.
If v in ŧ2, the restriction of sp augmented with a binding for v
to t2 is equal to augmenting the restriction of sp to t2 with this
same binding.
Lemma add_untyped_untyped v (t : {set 'I_n}) c sp :
v \in t
→ add (sub_filter sp t) v c = (sub_filter (add sp v c) t).
Lemma atom_vars_sub_gr (a:atom) (s1 s2:sub) :
atom_vars a \subset dom s1
→ s1 \sub s2
→ gr_atom (to_gr s1) a = gr_atom (to_gr s2) a.
Lemma atom_vars_sub_gr_def (a:atom) (s1 s2:sub) :
atom_vars a \subset dom s1
→ s1 \sub s2
→ gr_atom_def s1 a = gr_atom_def s2 a.
Lemma gr_term_def_eq_in_dom s1 s2 v1 v2 :
gr_term_def s1 (Var v1) = gr_term_def s2 (Var v2)
→ v1 \in dom s1
→ v2 \in dom s2
→ s1 v1 = s2 v2.
End NoDepGrounding.
v \in t
→ add (sub_filter sp t) v c = (sub_filter (add sp v c) t).
Lemma atom_vars_sub_gr (a:atom) (s1 s2:sub) :
atom_vars a \subset dom s1
→ s1 \sub s2
→ gr_atom (to_gr s1) a = gr_atom (to_gr s2) a.
Lemma atom_vars_sub_gr_def (a:atom) (s1 s2:sub) :
atom_vars a \subset dom s1
→ s1 \sub s2
→ gr_atom_def s1 a = gr_atom_def s2 a.
Lemma gr_term_def_eq_in_dom s1 s2 v1 v2 :
gr_term_def s1 (Var v1) = gr_term_def s2 (Var v2)
→ v1 \in dom s1
→ v2 \in dom s2
→ s1 v1 = s2 v2.
End NoDepGrounding.