why3doc index index
module Spec use option.Option use int.Int use Nat.Nat use Functions.Func use OptionFuncs.Funcs use Sum.Sum use Firstorder_symbol_spec.Spec use Firstorder_term_spec.Spec type fo_formula 'b0 'b1 = | Forall (fo_formula 'b0 (option 'b1)) | Exists (fo_formula 'b0 (option 'b1)) | And (fo_formula 'b0 'b1) (fo_formula 'b0 'b1) | Or (fo_formula 'b0 'b1) (fo_formula 'b0 'b1) | Not (fo_formula 'b0 'b1) | FTrue | FFalse | PApp (symbol 'b0) (fo_term_list 'b0 'b1) function nat_size_fo_formula (t:fo_formula 'b0 'b1) : nat = match t with | Forall v0 -> let s = one_nat in let s = add_nat (nat_size_fo_formula v0) s in s | Exists v0 -> let s = one_nat in let s = add_nat (nat_size_fo_formula v0) s in s | And v0 v1 -> let s = one_nat in let s = add_nat (nat_size_fo_formula v1) s in let s = add_nat (nat_size_fo_formula v0) s in s | Or v0 v1 -> let s = one_nat in let s = add_nat (nat_size_fo_formula v1) s in let s = add_nat (nat_size_fo_formula v0) s in s | Not v0 -> let s = one_nat in let s = add_nat (nat_size_fo_formula v0) s in s | FTrue -> let s = one_nat in s | FFalse -> let s = one_nat in s | PApp v0 v1 -> let s = one_nat in let s = add_nat (nat_size_fo_term_list v1) s in let s = add_nat (nat_size_symbol v0) s in s end with size_fo_formula (t:fo_formula 'b0 'b1) : int = match t with | Forall v0 -> let s = 1 in let s = size_fo_formula v0 + s in s | Exists v0 -> let s = 1 in let s = size_fo_formula v0 + s in s | And v0 v1 -> let s = 1 in let s = size_fo_formula v1 + s in let s = size_fo_formula v0 + s in s | Or v0 v1 -> let s = 1 in let s = size_fo_formula v1 + s in let s = size_fo_formula v0 + s in s | Not v0 -> let s = 1 in let s = size_fo_formula v0 + s in s | FTrue -> let s = 1 in s | FFalse -> let s = 1 in s | PApp v0 v1 -> let s = 1 in let s = size_fo_term_list v1 + s in let s = size_symbol v0 + s in s end let rec lemma size_positive_lemma_fo_formula (t:fo_formula 'b0 'b1) : unit ensures { size_fo_formula t > 0 } variant { nat_to_int (nat_size_fo_formula t) } = match t with | Forall v0 -> size_positive_lemma_fo_formula v0 ; () | Exists v0 -> size_positive_lemma_fo_formula v0 ; () | And v0 v1 -> size_positive_lemma_fo_formula v0 ; size_positive_lemma_fo_formula v1 ; () | Or v0 v1 -> size_positive_lemma_fo_formula v0 ; size_positive_lemma_fo_formula v1 ; () | Not v0 -> size_positive_lemma_fo_formula v0 ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> size_positive_lemma_symbol v0 ; size_positive_lemma_fo_term_list v1 ; () end function rename_fo_formula (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : fo_formula 'c0 'c1 = match t with | Forall v0 -> Forall (rename_fo_formula v0 s0 (olift s1)) | Exists v0 -> Exists (rename_fo_formula v0 s0 (olift s1)) | And v0 v1 -> And (rename_fo_formula v0 s0 s1) (rename_fo_formula v1 s0 s1) | Or v0 v1 -> Or (rename_fo_formula v0 s0 s1) (rename_fo_formula v1 s0 s1) | Not v0 -> Not (rename_fo_formula v0 s0 s1) | FTrue -> FTrue | FFalse -> FFalse | PApp v0 v1 -> PApp (rename_symbol v0 s0) (rename_fo_term_list v1 s0 s1) end let rec lemma renaming_composition_lemma_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> 'c0) (s11:'b1 -> 'c1) (s20:'c0 -> 'd0) (s21:'c1 -> 'd1) : unit ensures { rename_fo_formula (rename_fo_formula t s10 s11) s20 s21 = rename_fo_formula t (rcompose s10 s20) (rcompose s11 s21) } variant { size_fo_formula t } = match t with | Forall v0 -> renaming_composition_lemma_fo_formula v0 s10 (olift s11) s20 (olift s21) ; () | Exists v0 -> renaming_composition_lemma_fo_formula v0 s10 (olift s11) s20 (olift s21) ; () | And v0 v1 -> renaming_composition_lemma_fo_formula v0 s10 s11 s20 s21 ; renaming_composition_lemma_fo_formula v1 s10 s11 s20 s21 ; () | Or v0 v1 -> renaming_composition_lemma_fo_formula v0 s10 s11 s20 s21 ; renaming_composition_lemma_fo_formula v1 s10 s11 s20 s21 ; () | Not v0 -> renaming_composition_lemma_fo_formula v0 s10 s11 s20 s21 ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> renaming_composition_lemma_symbol v0 s10 s20 ; renaming_composition_lemma_fo_term_list v1 s10 s11 s20 s21 ; () end let rec lemma renaming_identity_lemma_fo_formula (t:fo_formula 'b0 'b1) : unit ensures { rename_fo_formula t identity identity = t } variant { size_fo_formula t } = match t with | Forall v0 -> renaming_identity_lemma_fo_formula v0 ; () | Exists v0 -> renaming_identity_lemma_fo_formula v0 ; () | And v0 v1 -> renaming_identity_lemma_fo_formula v0 ; renaming_identity_lemma_fo_formula v1 ; () | Or v0 v1 -> renaming_identity_lemma_fo_formula v0 ; renaming_identity_lemma_fo_formula v1 ; () | Not v0 -> renaming_identity_lemma_fo_formula v0 ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> renaming_identity_lemma_symbol v0 ; renaming_identity_lemma_fo_term_list v1 ; () end function subst_fo_formula (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)) : fo_formula 'c0 'c1 = match t with | Forall v0 -> Forall (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity)) | Exists v0 -> Exists (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity)) | And v0 v1 -> And (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) (subst_fo_formula v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) | Or v0 v1 -> Or (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) (subst_fo_formula v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) | Not v0 -> Not (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) | FTrue -> FTrue | FFalse -> FFalse | PApp v0 v1 -> PApp (subst_symbol v0 (rename_subst_symbol s0 identity)) (subst_fo_term_list v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) end let rec lemma rename_then_subst_composition_lemma_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> 'c0) (s11:'b1 -> 'c1) (s20:'c0 -> (symbol 'd0)) (s21:'c1 -> (fo_term 'd0 'd1)) : unit ensures { subst_fo_formula (rename_fo_formula t s10 s11) s20 s21 = subst_fo_formula t (rcompose s10 s20) (rcompose s11 s21) } variant { size_fo_formula t } = match t with | Forall v0 -> rename_then_subst_composition_lemma_fo_formula v0 s10 (olift s11) (rename_subst_symbol s20 identity) (rename_subst_fo_term (olifts_fo_term s21) identity identity) ; () | Exists v0 -> rename_then_subst_composition_lemma_fo_formula v0 s10 (olift s11) (rename_subst_symbol s20 identity) (rename_subst_fo_term (olifts_fo_term s21) identity identity) ; () | And v0 v1 -> rename_then_subst_composition_lemma_fo_formula v0 s10 s11 (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; rename_then_subst_composition_lemma_fo_formula v1 s10 s11 (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () | Or v0 v1 -> rename_then_subst_composition_lemma_fo_formula v0 s10 s11 (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; rename_then_subst_composition_lemma_fo_formula v1 s10 s11 (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () | Not v0 -> rename_then_subst_composition_lemma_fo_formula v0 s10 s11 (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> rename_then_subst_composition_lemma_symbol v0 s10 (rename_subst_symbol s20 identity) ; rename_then_subst_composition_lemma_fo_term_list v1 s10 s11 (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () end let rec lemma subst_then_rename_composition_lemma_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> (symbol 'c0)) (s11:'b1 -> (fo_term 'c0 'c1)) (s20:'c0 -> 'd0) (s21:'c1 -> 'd1) : unit ensures { rename_fo_formula (subst_fo_formula t s10 s11) s20 s21 = subst_fo_formula t (rename_subst_symbol s10 s20) (rename_subst_fo_term s11 s20 s21) } variant { size_fo_formula t } = match t with | Forall v0 -> subst_then_rename_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term (olifts_fo_term s11) identity identity) s20 (olift s21) ; () | Exists v0 -> subst_then_rename_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term (olifts_fo_term s11) identity identity) s20 (olift s21) ; () | And v0 v1 -> subst_then_rename_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) s20 s21 ; subst_then_rename_composition_lemma_fo_formula v1 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) s20 s21 ; () | Or v0 v1 -> subst_then_rename_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) s20 s21 ; subst_then_rename_composition_lemma_fo_formula v1 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) s20 s21 ; () | Not v0 -> subst_then_rename_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) s20 s21 ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> subst_then_rename_composition_lemma_symbol v0 (rename_subst_symbol s10 identity) s20 ; subst_then_rename_composition_lemma_fo_term_list v1 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) s20 s21 ; () end let rec lemma subst_composition_lemma_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> (symbol 'c0)) (s11:'b1 -> (fo_term 'c0 'c1)) (s20:'c0 -> (symbol 'd0)) (s21:'c1 -> (fo_term 'd0 'd1)) : unit ensures { subst_fo_formula (subst_fo_formula t s10 s11) s20 s21 = subst_fo_formula t (subst_compose_symbol s10 s20) (subst_compose_fo_term s11 s20 s21) } variant { size_fo_formula t } = match t with | Forall v0 -> subst_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term (olifts_fo_term s11) identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term (olifts_fo_term s21) identity identity) ; () | Exists v0 -> subst_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term (olifts_fo_term s11) identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term (olifts_fo_term s21) identity identity) ; () | And v0 v1 -> subst_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; subst_composition_lemma_fo_formula v1 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () | Or v0 v1 -> subst_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; subst_composition_lemma_fo_formula v1 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () | Not v0 -> subst_composition_lemma_fo_formula v0 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> subst_composition_lemma_symbol v0 (rename_subst_symbol s10 identity) (rename_subst_symbol s20 identity) ; subst_composition_lemma_fo_term_list v1 (rename_subst_symbol s10 identity) (rename_subst_fo_term s11 identity identity) (rename_subst_symbol s20 identity) (rename_subst_fo_term s21 identity identity) ; () end let rec lemma subst_identity_lemma_fo_formula (t:fo_formula 'b0 'b1) : unit ensures { subst_fo_formula t subst_id_symbol subst_id_fo_term = t } variant { size_fo_formula t } = match t with | Forall v0 -> subst_identity_lemma_fo_formula v0 ; () | Exists v0 -> subst_identity_lemma_fo_formula v0 ; () | And v0 v1 -> subst_identity_lemma_fo_formula v0 ; subst_identity_lemma_fo_formula v1 ; () | Or v0 v1 -> subst_identity_lemma_fo_formula v0 ; subst_identity_lemma_fo_formula v1 ; () | Not v0 -> subst_identity_lemma_fo_formula v0 ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> subst_identity_lemma_symbol v0 ; subst_identity_lemma_fo_term_list v1 ; () end let rec lemma renaming_preserve_size_fo_formula (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : unit ensures { size_fo_formula (rename_fo_formula t s0 s1) = size_fo_formula t } variant { size_fo_formula t } = match t with | Forall v0 -> renaming_preserve_size_fo_formula v0 (s0) ((olift s1)) ; () | Exists v0 -> renaming_preserve_size_fo_formula v0 (s0) ((olift s1)) ; () | And v0 v1 -> renaming_preserve_size_fo_formula v0 (s0) (s1) ; renaming_preserve_size_fo_formula v1 (s0) (s1) ; () | Or v0 v1 -> renaming_preserve_size_fo_formula v0 (s0) (s1) ; renaming_preserve_size_fo_formula v1 (s0) (s1) ; () | Not v0 -> renaming_preserve_size_fo_formula v0 (s0) (s1) ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> renaming_preserve_size_symbol v0 (s0) ; renaming_preserve_size_fo_term_list v1 (s0) (s1) ; () end predicate is_symbol_free_var_in_fo_formula (x:'b0) (t:fo_formula 'b0 'b1) = match t with | Forall v0 -> is_symbol_free_var_in_fo_formula x v0 | Exists v0 -> is_symbol_free_var_in_fo_formula x v0 | And v0 v1 -> is_symbol_free_var_in_fo_formula x v0 \/ is_symbol_free_var_in_fo_formula x v1 | Or v0 v1 -> is_symbol_free_var_in_fo_formula x v0 \/ is_symbol_free_var_in_fo_formula x v1 | Not v0 -> is_symbol_free_var_in_fo_formula x v0 | FTrue -> false | FFalse -> false | PApp v0 v1 -> is_symbol_free_var_in_symbol x v0 \/ is_symbol_free_var_in_fo_term_list x v1 end with is_fo_term_free_var_in_fo_formula (x:'b1) (t:fo_formula 'b0 'b1) = match t with | Forall v0 -> is_fo_term_free_var_in_fo_formula (Some x) v0 | Exists v0 -> is_fo_term_free_var_in_fo_formula (Some x) v0 | And v0 v1 -> is_fo_term_free_var_in_fo_formula x v0 \/ is_fo_term_free_var_in_fo_formula x v1 | Or v0 v1 -> is_fo_term_free_var_in_fo_formula x v0 \/ is_fo_term_free_var_in_fo_formula x v1 | Not v0 -> is_fo_term_free_var_in_fo_formula x v0 | FTrue -> false | FFalse -> false | PApp v0 v1 -> is_fo_term_free_var_in_fo_term_list x v1 end let rec ghost rename_free_var_constructive_inversion_symbol_fo_formula (x:'c0) (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : 'b0 requires { is_symbol_free_var_in_fo_formula x (rename_fo_formula t s0 s1) } ensures { is_symbol_free_var_in_fo_formula result t /\ s0 result = x } variant { size_fo_formula t } = match t with | Forall v0 -> if is_symbol_free_var_in_fo_formula x (rename_fo_formula v0 s0 (olift s1)) then let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x v0 s0 (olift s1) in sumx else absurd | Exists v0 -> if is_symbol_free_var_in_fo_formula x (rename_fo_formula v0 s0 (olift s1)) then let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x v0 s0 (olift s1) in sumx else absurd | And v0 v1 -> if is_symbol_free_var_in_fo_formula x (rename_fo_formula v0 s0 s1) then let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x v0 s0 s1 in sumx else if is_symbol_free_var_in_fo_formula x (rename_fo_formula v1 s0 s1) then let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x v1 s0 s1 in sumx else absurd | Or v0 v1 -> if is_symbol_free_var_in_fo_formula x (rename_fo_formula v0 s0 s1) then let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x v0 s0 s1 in sumx else if is_symbol_free_var_in_fo_formula x (rename_fo_formula v1 s0 s1) then let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x v1 s0 s1 in sumx else absurd | Not v0 -> if is_symbol_free_var_in_fo_formula x (rename_fo_formula v0 s0 s1) then let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x v0 s0 s1 in sumx else absurd | FTrue -> absurd | FFalse -> absurd | PApp v0 v1 -> if is_symbol_free_var_in_symbol x (rename_symbol v0 s0) then let sumx = rename_free_var_constructive_inversion_symbol_symbol x v0 s0 in sumx else if is_symbol_free_var_in_fo_term_list x (rename_fo_term_list v1 s0 s1) then let sumx = rename_free_var_constructive_inversion_symbol_fo_term_list x v1 s0 s1 in sumx else absurd end with lemma rename_free_var_inversion_symbol_fo_formula (x:'c0) (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : unit requires { is_symbol_free_var_in_fo_formula x (rename_fo_formula t s0 s1) } ensures { exists y:'b0. is_symbol_free_var_in_fo_formula y t /\ s0 y = x } variant { 1 + size_fo_formula t } = let sumx = rename_free_var_constructive_inversion_symbol_fo_formula x t s0 s1 in () with ghost rename_free_var_constructive_inversion_fo_term_fo_formula (x:'c1) (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : 'b1 requires { is_fo_term_free_var_in_fo_formula x (rename_fo_formula t s0 s1) } ensures { is_fo_term_free_var_in_fo_formula result t /\ s1 result = x } variant { size_fo_formula t } = match t with | Forall v0 -> if is_fo_term_free_var_in_fo_formula (Some x) (rename_fo_formula v0 s0 (olift s1)) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula (Some x) v0 s0 (olift s1) in match sumx with | None -> absurd | Some sumx -> sumx end else absurd | Exists v0 -> if is_fo_term_free_var_in_fo_formula (Some x) (rename_fo_formula v0 s0 (olift s1)) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula (Some x) v0 s0 (olift s1) in match sumx with | None -> absurd | Some sumx -> sumx end else absurd | And v0 v1 -> if is_fo_term_free_var_in_fo_formula x (rename_fo_formula v0 s0 s1) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula x v0 s0 s1 in sumx else if is_fo_term_free_var_in_fo_formula x (rename_fo_formula v1 s0 s1) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula x v1 s0 s1 in sumx else absurd | Or v0 v1 -> if is_fo_term_free_var_in_fo_formula x (rename_fo_formula v0 s0 s1) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula x v0 s0 s1 in sumx else if is_fo_term_free_var_in_fo_formula x (rename_fo_formula v1 s0 s1) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula x v1 s0 s1 in sumx else absurd | Not v0 -> if is_fo_term_free_var_in_fo_formula x (rename_fo_formula v0 s0 s1) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula x v0 s0 s1 in sumx else absurd | FTrue -> absurd | FFalse -> absurd | PApp v0 v1 -> if is_fo_term_free_var_in_fo_term_list x (rename_fo_term_list v1 s0 s1) then let sumx = rename_free_var_constructive_inversion_fo_term_fo_term_list x v1 s0 s1 in sumx else absurd end with lemma rename_free_var_inversion_fo_term_fo_formula (x:'c1) (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : unit requires { is_fo_term_free_var_in_fo_formula x (rename_fo_formula t s0 s1) } ensures { exists y:'b1. is_fo_term_free_var_in_fo_formula y t /\ s1 y = x } variant { 1 + size_fo_formula t } = let sumx = rename_free_var_constructive_inversion_fo_term_fo_formula x t s0 s1 in () let rec lemma rename_free_var_propagation_symbol_fo_formula (x:'b0) (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : unit ensures { is_symbol_free_var_in_fo_formula x t -> is_symbol_free_var_in_fo_formula (s0 x) (rename_fo_formula t s0 s1) } variant { size_fo_formula t } = match t with | Forall v0 -> rename_free_var_propagation_symbol_fo_formula x v0 (s0) ((olift s1)) ; () | Exists v0 -> rename_free_var_propagation_symbol_fo_formula x v0 (s0) ((olift s1)) ; () | And v0 v1 -> rename_free_var_propagation_symbol_fo_formula x v0 (s0) (s1) ; rename_free_var_propagation_symbol_fo_formula x v1 (s0) (s1) ; () | Or v0 v1 -> rename_free_var_propagation_symbol_fo_formula x v0 (s0) (s1) ; rename_free_var_propagation_symbol_fo_formula x v1 (s0) (s1) ; () | Not v0 -> rename_free_var_propagation_symbol_fo_formula x v0 (s0) (s1) ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> rename_free_var_propagation_symbol_symbol x v0 (s0) ; rename_free_var_propagation_symbol_fo_term_list x v1 (s0) (s1) ; () end with lemma rename_free_var_propagation_fo_term_fo_formula (x:'b1) (t:fo_formula 'b0 'b1) (s0:'b0 -> 'c0) (s1:'b1 -> 'c1) : unit ensures { is_fo_term_free_var_in_fo_formula x t -> is_fo_term_free_var_in_fo_formula (s1 x) (rename_fo_formula t s0 s1) } variant { size_fo_formula t } = match t with | Forall v0 -> rename_free_var_propagation_fo_term_fo_formula (Some x) v0 (s0) ((olift s1)) ; () | Exists v0 -> rename_free_var_propagation_fo_term_fo_formula (Some x) v0 (s0) ((olift s1)) ; () | And v0 v1 -> rename_free_var_propagation_fo_term_fo_formula x v0 (s0) (s1) ; rename_free_var_propagation_fo_term_fo_formula x v1 (s0) (s1) ; () | Or v0 v1 -> rename_free_var_propagation_fo_term_fo_formula x v0 (s0) (s1) ; rename_free_var_propagation_fo_term_fo_formula x v1 (s0) (s1) ; () | Not v0 -> rename_free_var_propagation_fo_term_fo_formula x v0 (s0) (s1) ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> () ; rename_free_var_propagation_fo_term_fo_term_list x v1 (s0) (s1) ; () end let rec ghost subst_free_var_constructive_inversion_symbol_fo_formula (x:'c0) (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)) : sum ('b0) ('b1) requires { is_symbol_free_var_in_fo_formula x (subst_fo_formula t s0 s1) } ensures { let sumx = result in match sumx with | Left sumx -> is_symbol_free_var_in_fo_formula sumx t /\ is_symbol_free_var_in_symbol x (s0 sumx) | Right sumx -> is_fo_term_free_var_in_fo_formula sumx t /\ is_symbol_free_var_in_fo_term x (s1 sumx) end } variant { size_fo_formula t } = match t with | Forall v0 -> if is_symbol_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> match sumx with | None -> absurd | Some sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity (compose some identity) in assert { y = x } ; sumx) end end else absurd | Exists v0 -> if is_symbol_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> match sumx with | None -> absurd | Some sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity (compose some identity) in assert { y = x } ; sumx) end end else absurd | And v0 v1 -> if is_symbol_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx) end else if is_symbol_free_var_in_fo_formula x (subst_fo_formula v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx) end else absurd | Or v0 v1 -> if is_symbol_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx) end else if is_symbol_free_var_in_fo_formula x (subst_fo_formula v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx) end else absurd | Not v0 -> if is_symbol_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx) end else absurd | FTrue -> absurd | FFalse -> absurd | PApp v0 v1 -> if is_symbol_free_var_in_symbol x (subst_symbol v0 (rename_subst_symbol s0 identity)) then let sumx = subst_free_var_constructive_inversion_symbol_symbol x v0 (rename_subst_symbol s0 identity) in let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx else if is_symbol_free_var_in_fo_term_list x (subst_fo_term_list v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_symbol_fo_term_list x v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in match sumx with | Left sumx -> let y = rename_free_var_constructive_inversion_symbol_symbol x (eval s0 sumx) identity in assert { y = x } ; Left sumx | Right sumx -> Right (let y = rename_free_var_constructive_inversion_symbol_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx) end else absurd end with lemma subst_free_var_inversion_symbol_fo_formula (x:'c0) (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)) : unit requires { is_symbol_free_var_in_fo_formula x (subst_fo_formula t s0 s1) } ensures { (exists y:'b0. is_symbol_free_var_in_fo_formula y t /\ is_symbol_free_var_in_symbol x (s0 y)) \/ (exists y:'b1. is_fo_term_free_var_in_fo_formula y t /\ is_symbol_free_var_in_fo_term x (s1 y)) } variant { 1 + size_fo_formula t } = let sumx = subst_free_var_constructive_inversion_symbol_fo_formula x t s0 s1 in match sumx with | Left sumx -> () | Right sumx -> () end with ghost subst_free_var_constructive_inversion_fo_term_fo_formula (x:'c1) (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)) : 'b1 requires { is_fo_term_free_var_in_fo_formula x (subst_fo_formula t s0 s1) } ensures { let sumx = result in is_fo_term_free_var_in_fo_formula sumx t /\ is_fo_term_free_var_in_fo_term x (s1 sumx) } variant { size_fo_formula t } = match t with | Forall v0 -> if is_fo_term_free_var_in_fo_formula (Some x) (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula (Some x) v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity) in match sumx with | None -> absurd | Some sumx -> let y = rename_free_var_constructive_inversion_fo_term_fo_term (Some x) (eval s1 sumx) identity (compose some identity) in assert { y = x } ; sumx end else absurd | Exists v0 -> if is_fo_term_free_var_in_fo_formula (Some x) (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula (Some x) v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term (olifts_fo_term s1) identity identity) in match sumx with | None -> absurd | Some sumx -> let y = rename_free_var_constructive_inversion_fo_term_fo_term (Some x) (eval s1 sumx) identity (compose some identity) in assert { y = x } ; sumx end else absurd | And v0 v1 -> if is_fo_term_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in let y = rename_free_var_constructive_inversion_fo_term_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx else if is_fo_term_free_var_in_fo_formula x (subst_fo_formula v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula x v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in let y = rename_free_var_constructive_inversion_fo_term_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx else absurd | Or v0 v1 -> if is_fo_term_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in let y = rename_free_var_constructive_inversion_fo_term_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx else if is_fo_term_free_var_in_fo_formula x (subst_fo_formula v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula x v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in let y = rename_free_var_constructive_inversion_fo_term_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx else absurd | Not v0 -> if is_fo_term_free_var_in_fo_formula x (subst_fo_formula v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula x v0 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in let y = rename_free_var_constructive_inversion_fo_term_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx else absurd | FTrue -> absurd | FFalse -> absurd | PApp v0 v1 -> if is_fo_term_free_var_in_fo_term_list x (subst_fo_term_list v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity)) then let sumx = subst_free_var_constructive_inversion_fo_term_fo_term_list x v1 (rename_subst_symbol s0 identity) (rename_subst_fo_term s1 identity identity) in let y = rename_free_var_constructive_inversion_fo_term_fo_term x (eval s1 sumx) identity identity in assert { y = x } ; sumx else absurd end with lemma subst_free_var_inversion_fo_term_fo_formula (x:'c1) (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)) : unit requires { is_fo_term_free_var_in_fo_formula x (subst_fo_formula t s0 s1) } ensures { (exists y:'b1. is_fo_term_free_var_in_fo_formula y t /\ is_fo_term_free_var_in_fo_term x (s1 y)) } variant { 1 + size_fo_formula t } = let sumx = subst_free_var_constructive_inversion_fo_term_fo_formula x t s0 s1 in () let rec lemma subst_free_var_propagation_symbol_symbol_fo_formula (x:'b0) (y:'c0) (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)): unit ensures { is_symbol_free_var_in_fo_formula x t /\ is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_fo_formula y (subst_fo_formula t s0 s1) } variant { size_fo_formula t } = match t with | Forall v0 -> subst_free_var_propagation_symbol_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; () | Exists v0 -> subst_free_var_propagation_symbol_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; () | And v0 v1 -> subst_free_var_propagation_symbol_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; subst_free_var_propagation_symbol_symbol_fo_formula x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; () | Or v0 v1 -> subst_free_var_propagation_symbol_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; subst_free_var_propagation_symbol_symbol_fo_formula x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; () | Not v0 -> subst_free_var_propagation_symbol_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> subst_free_var_propagation_symbol_symbol_symbol x y v0 ((rename_subst_symbol s0 identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; subst_free_var_propagation_symbol_symbol_fo_term_list x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_symbol y (eval s0 x) identity ; assert { is_symbol_free_var_in_symbol y (s0 x) -> is_symbol_free_var_in_symbol y (eval ((rename_subst_symbol s0 identity)) x) } ; () end with lemma subst_free_var_propagation_fo_term_symbol_fo_formula (x:'b1) (y:'c0) (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)): unit ensures { is_fo_term_free_var_in_fo_formula x t /\ is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_formula y (subst_fo_formula t s0 s1) } variant { size_fo_formula t } = match t with | Forall v0 -> subst_free_var_propagation_fo_term_symbol_fo_formula (Some x) y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity (compose some identity) ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) (Some x)) } ; () | Exists v0 -> subst_free_var_propagation_fo_term_symbol_fo_formula (Some x) y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity (compose some identity) ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) (Some x)) } ; () | And v0 v1 -> subst_free_var_propagation_fo_term_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity identity ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; subst_free_var_propagation_fo_term_symbol_fo_formula x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity identity ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () | Or v0 v1 -> subst_free_var_propagation_fo_term_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity identity ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; subst_free_var_propagation_fo_term_symbol_fo_formula x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity identity ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () | Not v0 -> subst_free_var_propagation_fo_term_symbol_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity identity ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> () ; subst_free_var_propagation_fo_term_symbol_fo_term_list x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_symbol_fo_term y (eval s1 x) identity identity ; assert { is_symbol_free_var_in_fo_term y (s1 x) -> is_symbol_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () end with lemma subst_free_var_propagation_fo_term_fo_term_fo_formula (x:'b1) (y:'c1) (t:fo_formula 'b0 'b1) (s0:'b0 -> (symbol 'c0)) (s1:'b1 -> (fo_term 'c0 'c1)): unit ensures { is_fo_term_free_var_in_fo_formula x t /\ is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_formula y (subst_fo_formula t s0 s1) } variant { size_fo_formula t } = match t with | Forall v0 -> subst_free_var_propagation_fo_term_fo_term_fo_formula (Some x) (Some y) v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity (compose some identity) ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term (Some y) (eval ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) (Some x)) } ; () | Exists v0 -> subst_free_var_propagation_fo_term_fo_term_fo_formula (Some x) (Some y) v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity (compose some identity) ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term (Some y) (eval ((rename_subst_fo_term (olifts_fo_term s1) identity identity)) (Some x)) } ; () | And v0 v1 -> subst_free_var_propagation_fo_term_fo_term_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity identity ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; subst_free_var_propagation_fo_term_fo_term_fo_formula x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity identity ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () | Or v0 v1 -> subst_free_var_propagation_fo_term_fo_term_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity identity ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; subst_free_var_propagation_fo_term_fo_term_fo_formula x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity identity ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () | Not v0 -> subst_free_var_propagation_fo_term_fo_term_fo_formula x y v0 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity identity ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> () ; subst_free_var_propagation_fo_term_fo_term_fo_term_list x y v1 ((rename_subst_symbol s0 identity)) ((rename_subst_fo_term s1 identity identity)) ; rename_free_var_propagation_fo_term_fo_term y (eval s1 x) identity identity ; assert { is_fo_term_free_var_in_fo_term y (s1 x) -> is_fo_term_free_var_in_fo_term y (eval ((rename_subst_fo_term s1 identity identity)) x) } ; () end let rec lemma free_var_equivalence_of_subst_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> (symbol 'c0)) (s20:'b0 -> (symbol 'c0)) (s11:'b1 -> (fo_term 'c0 'c1)) (s21:'b1 -> (fo_term 'c0 'c1)) : unit requires { forall x:'b0. is_symbol_free_var_in_fo_formula x t -> s10 x = s20 x } requires { forall x:'b1. is_fo_term_free_var_in_fo_formula x t -> s11 x = s21 x } ensures { subst_fo_formula t s10 s11 = subst_fo_formula t s20 s21 } variant { size_fo_formula t } = match t with | Forall v0 -> assert { forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:(option 'b1). is_fo_term_free_var_in_fo_formula x v0 -> match x with | None -> true | Some x -> is_fo_term_free_var_in_fo_formula x t end } ; free_var_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term (olifts_fo_term s11) identity identity)) ((rename_subst_fo_term (olifts_fo_term s21) identity identity)) ; () | Exists v0 -> assert { forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:(option 'b1). is_fo_term_free_var_in_fo_formula x v0 -> match x with | None -> true | Some x -> is_fo_term_free_var_in_fo_formula x t end } ; free_var_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term (olifts_fo_term s11) identity identity)) ((rename_subst_fo_term (olifts_fo_term s21) identity identity)) ; () | And v0 v1 -> assert { forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:'b1. is_fo_term_free_var_in_fo_formula x v0 -> is_fo_term_free_var_in_fo_formula x t } ; free_var_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)) ; assert { forall x:'b0. is_symbol_free_var_in_fo_formula x v1 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:'b1. is_fo_term_free_var_in_fo_formula x v1 -> is_fo_term_free_var_in_fo_formula x t } ; free_var_equivalence_of_subst_fo_formula v1 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)) ; () | Or v0 v1 -> assert { forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:'b1. is_fo_term_free_var_in_fo_formula x v0 -> is_fo_term_free_var_in_fo_formula x t } ; free_var_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)) ; assert { forall x:'b0. is_symbol_free_var_in_fo_formula x v1 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:'b1. is_fo_term_free_var_in_fo_formula x v1 -> is_fo_term_free_var_in_fo_formula x t } ; free_var_equivalence_of_subst_fo_formula v1 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)) ; () | Not v0 -> assert { forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:'b1. is_fo_term_free_var_in_fo_formula x v0 -> is_fo_term_free_var_in_fo_formula x t } ; free_var_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)) ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> assert { forall x:'b0. is_symbol_free_var_in_symbol x v0 -> is_symbol_free_var_in_fo_formula x t } ; free_var_equivalence_of_subst_symbol v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ; assert { forall x:'b0. is_symbol_free_var_in_fo_term_list x v1 -> is_symbol_free_var_in_fo_formula x t } ; assert { forall x:'b1. is_fo_term_free_var_in_fo_term_list x v1 -> is_fo_term_free_var_in_fo_formula x t } ; free_var_equivalence_of_subst_fo_term_list v1 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)) ; () end let lemma free_var_equivalence_of_rename_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> 'c0) (s20:'b0 -> 'c0) (s11:'b1 -> 'c1) (s21:'b1 -> 'c1) : unit requires { forall x:'b0. is_symbol_free_var_in_fo_formula x t -> s10 x = s20 x } requires { forall x:'b1. is_fo_term_free_var_in_fo_formula x t -> s11 x = s21 x } ensures { rename_fo_formula t s10 s11 = rename_fo_formula t s20 s21 } = free_var_equivalence_of_subst_fo_formula t (subst_of_rename_symbol s10) (subst_of_rename_symbol s20) (subst_of_rename_fo_term s11) (subst_of_rename_fo_term s21) let rec lemma free_var_derive_equivalence_of_subst_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> (symbol 'c0)) (s20:'b0 -> (symbol 'c0)) (s11:'b1 -> (fo_term 'c0 'c1)) (s21:'b1 -> (fo_term 'c0 'c1)) : unit ensures { forall x:'b0. is_symbol_free_var_in_fo_formula x t -> s10 x = s20 x } ensures { forall x:'b1. is_fo_term_free_var_in_fo_formula x t -> s11 x = s21 x } requires { subst_fo_formula t s10 s11 = subst_fo_formula t s20 s21 } variant { size_fo_formula t } = match t with | Forall v0 -> free_var_derive_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term (olifts_fo_term s11) identity identity)) ((rename_subst_fo_term (olifts_fo_term s21) identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_formula x v0 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_formula (Some x) v0 -> rename_fo_term (s11 x) identity (compose some identity) = eval ((rename_subst_fo_term (olifts_fo_term s11) identity identity)) (Some x) = eval ((rename_subst_fo_term (olifts_fo_term s21) identity identity)) (Some x) = rename_fo_term (s21 x) identity (compose some identity) && s11 x = rename_fo_term (rename_fo_term (s11 x) identity (compose some identity)) identity (ocase identity y1) = rename_fo_term (rename_fo_term (s21 x) identity (compose some identity)) identity (ocase identity y1) = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_formula (Some x) v0 -> s11 x = s21 x } ; () | Exists v0 -> free_var_derive_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term (olifts_fo_term s11) identity identity)) ((rename_subst_fo_term (olifts_fo_term s21) identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_formula x v0 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_formula (Some x) v0 -> rename_fo_term (s11 x) identity (compose some identity) = eval ((rename_subst_fo_term (olifts_fo_term s11) identity identity)) (Some x) = eval ((rename_subst_fo_term (olifts_fo_term s21) identity identity)) (Some x) = rename_fo_term (s21 x) identity (compose some identity) && s11 x = rename_fo_term (rename_fo_term (s11 x) identity (compose some identity)) identity (ocase identity y1) = rename_fo_term (rename_fo_term (s21 x) identity (compose some identity)) identity (ocase identity y1) = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_formula (Some x) v0 -> s11 x = s21 x } ; () | And v0 v1 -> free_var_derive_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_formula x v0 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_formula x v0 -> rename_fo_term (s11 x) identity identity = eval ((rename_subst_fo_term s11 identity identity)) x = eval ((rename_subst_fo_term s21 identity identity)) x = rename_fo_term (s21 x) identity identity && s11 x = rename_fo_term (rename_fo_term (s11 x) identity identity) identity identity = rename_fo_term (rename_fo_term (s21 x) identity identity) identity identity = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_formula x v0 -> s11 x = s21 x } ; free_var_derive_equivalence_of_subst_fo_formula v1 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_formula x v1 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_formula x v1 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_formula x v1 -> rename_fo_term (s11 x) identity identity = eval ((rename_subst_fo_term s11 identity identity)) x = eval ((rename_subst_fo_term s21 identity identity)) x = rename_fo_term (s21 x) identity identity && s11 x = rename_fo_term (rename_fo_term (s11 x) identity identity) identity identity = rename_fo_term (rename_fo_term (s21 x) identity identity) identity identity = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_formula x v1 -> s11 x = s21 x } ; () | Or v0 v1 -> free_var_derive_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_formula x v0 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_formula x v0 -> rename_fo_term (s11 x) identity identity = eval ((rename_subst_fo_term s11 identity identity)) x = eval ((rename_subst_fo_term s21 identity identity)) x = rename_fo_term (s21 x) identity identity && s11 x = rename_fo_term (rename_fo_term (s11 x) identity identity) identity identity = rename_fo_term (rename_fo_term (s21 x) identity identity) identity identity = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_formula x v0 -> s11 x = s21 x } ; free_var_derive_equivalence_of_subst_fo_formula v1 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_formula x v1 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_formula x v1 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_formula x v1 -> rename_fo_term (s11 x) identity identity = eval ((rename_subst_fo_term s11 identity identity)) x = eval ((rename_subst_fo_term s21 identity identity)) x = rename_fo_term (s21 x) identity identity && s11 x = rename_fo_term (rename_fo_term (s11 x) identity identity) identity identity = rename_fo_term (rename_fo_term (s21 x) identity identity) identity identity = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_formula x v1 -> s11 x = s21 x } ; () | Not v0 -> free_var_derive_equivalence_of_subst_fo_formula v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_formula x v0 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_formula x v0 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_formula x v0 -> rename_fo_term (s11 x) identity identity = eval ((rename_subst_fo_term s11 identity identity)) x = eval ((rename_subst_fo_term s21 identity identity)) x = rename_fo_term (s21 x) identity identity && s11 x = rename_fo_term (rename_fo_term (s11 x) identity identity) identity identity = rename_fo_term (rename_fo_term (s21 x) identity identity) identity identity = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_formula x v0 -> s11 x = s21 x } ; () | FTrue -> () | FFalse -> () | PApp v0 v1 -> free_var_derive_equivalence_of_subst_symbol v0 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_symbol x v0 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_symbol x v0 -> s10 x = s20 x } ; free_var_derive_equivalence_of_subst_fo_term_list v1 ((rename_subst_symbol s10 identity)) ((rename_subst_symbol s20 identity)) ((rename_subst_fo_term s11 identity identity)) ((rename_subst_fo_term s21 identity identity)); assert { (forall x:'b0, y0:'c0. is_symbol_free_var_in_fo_term_list x v1 -> rename_symbol (s10 x) identity = eval ((rename_subst_symbol s10 identity)) x = eval ((rename_subst_symbol s20 identity)) x = rename_symbol (s20 x) identity && s10 x = rename_symbol (rename_symbol (s10 x) identity) identity = rename_symbol (rename_symbol (s20 x) identity) identity = s20 x && s10 x = s20 x) && forall x:'b0. is_symbol_free_var_in_fo_term_list x v1 -> s10 x = s20 x }; assert { (forall x:'b1, y0:'c0, y1:'c1. is_fo_term_free_var_in_fo_term_list x v1 -> rename_fo_term (s11 x) identity identity = eval ((rename_subst_fo_term s11 identity identity)) x = eval ((rename_subst_fo_term s21 identity identity)) x = rename_fo_term (s21 x) identity identity && s11 x = rename_fo_term (rename_fo_term (s11 x) identity identity) identity identity = rename_fo_term (rename_fo_term (s21 x) identity identity) identity identity = s21 x && s11 x = s21 x) && forall x:'b1. is_fo_term_free_var_in_fo_term_list x v1 -> s11 x = s21 x } ; () end let lemma free_var_derive_equivalence_of_rename_fo_formula (t:fo_formula 'b0 'b1) (s10:'b0 -> 'c0) (s20:'b0 -> 'c0) (s11:'b1 -> 'c1) (s21:'b1 -> 'c1) : unit ensures { forall x:'b0. is_symbol_free_var_in_fo_formula x t -> s10 x = s20 x } ensures { forall x:'b1. is_fo_term_free_var_in_fo_formula x t -> s11 x = s21 x } requires { rename_fo_formula t s10 s11 = rename_fo_formula t s20 s21 } = free_var_derive_equivalence_of_subst_fo_formula t (subst_of_rename_symbol s10) (subst_of_rename_symbol s20) (subst_of_rename_fo_term s11) (subst_of_rename_fo_term s21); assert { forall x:'b0. (subst_of_rename_symbol s10 x:symbol 'c0) = (subst_of_rename_symbol s20 x:symbol 'c0) -> (Var_symbol (s10 x):symbol 'c0) = (Var_symbol (s20 x):symbol 'c0) && s10 x = s20 x }; assert { forall x:'b1. (subst_of_rename_fo_term s11 x:fo_term 'c0 'c1) = (subst_of_rename_fo_term s21 x:fo_term 'c0 'c1) -> (Var_fo_term (s11 x):fo_term 'c0 'c1) = (Var_fo_term (s21 x):fo_term 'c0 'c1) && s11 x = s21 x } end
Generated by why3doc 1.7.0