aboutsummaryrefslogtreecommitdiffhomepage
path: root/contrib/linear/subst.ml
blob: 8e16565d7a9c542e25b8ed676d34ff9ff25801bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
(***********************************************************************)
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team    *)
(* <O___,, *        INRIA-Rocquencourt  &  LRI-CNRS-Orsay              *)
(*   \VV/  *************************************************************)
(*    //   *      This file is distributed under the terms of the      *)
(*         *       GNU Lesser General Public License Version 2.1       *)
(***********************************************************************)

(*i $Id$ i*)

open General
open Names
open Dpctypes

(* subst_term      : identifier -> term -> term -> term
   subst_list_term : identifier -> term -> term list -> term list *****)

let rec subst_term v t = function
    VAR(s)      -> if s=v then t else (VAR s)
  | GLOB _ as x -> x
  | APP(lt)     -> APP(subst_list_term v t lt)
and subst_list_term v t = function
  t1::l1 -> (subst_term v t t1)::(subst_list_term v t l1)
| [] -> []

(* subst : identifier -> term -> formula -> formula *)

let subst v t =
  let rec subst_rec f = match f with
      Atom(s,lt) -> Atom(s,subst_list_term v t lt)
    | Neg(f1) -> Neg(subst_rec f1)
    | Imp(f1,f2) -> Imp(subst_rec f1,subst_rec f2)
    | Conj(f1,f2) -> Conj(subst_rec f1, subst_rec f2)
    | Disj(f1,f2) -> Disj(subst_rec f1, subst_rec f2)
    | ForAll(s,f1) -> ForAll(s,subst_rec f1)
    | Exists(s,f1) -> Exists(s, subst_rec f1)
  in subst_rec

(* all_lit : formula -> formula list *)

let rec all_lit = function
    Atom((x_0,x_1)) -> [Atom((x_0,x_1))]
  | Neg(f) -> all_lit f
  | Conj(f1,f2) -> (all_lit f1)@(all_lit f2)
  | Disj(f1,f2) -> (all_lit f1)@(all_lit f2)
  | Imp(f1,f2) -> (all_lit f1)@(all_lit f2)
  | _ -> raise Impossible_case

(* occurs : formula -> formula -> bool *)

let occurs s =
  let rec occurs_rec f = if s=f then true else match f with
      Neg(f1) -> (occurs_rec f1)
    | ForAll(s,f1) -> (occurs_rec f1)
    | Exists(s,f1) -> (occurs_rec f1)
    | Imp(f1,f2) -> (occurs_rec f1) or (occurs_rec f2)
    | Conj(f1,f2) -> (occurs_rec f1) or (occurs_rec f2)
    | Disj(f1,f2) -> (occurs_rec f1) or (occurs_rec f2)
    | _ -> false
  in occurs_rec

(* subst_f_f : formula -> formula -> formula -> formula *)

let rec subst_f_f fa fb f = 
  if f=fa 
  then fb
  else match f with
      Atom(_,_) as a -> a
    | Neg(f1) -> Neg(subst_f_f fa fb f1)
    | Conj(f1,f2) -> Conj(subst_f_f fa fb f1,subst_f_f fa fb f2)
    | Disj(f1,f2) -> Disj(subst_f_f fa fb f1,subst_f_f fa fb f2)
    | Imp(f1,f2) -> Imp(subst_f_f fa fb f1,subst_f_f fa fb f2)
    | ForAll(s,f1) -> ForAll(s,subst_f_f fa fb f1)
    | Exists(s,f1) -> Exists(s,subst_f_f fa fb f1)

(* subst_proof2 : identifier -> term -> lkproof2 -> lkproof2 *)

let rec subst_proof2 v t (Proof2(sq1,sq2,rule)) = 
  let sq1' = List.map (subst v t) sq1
  and sq2' = List.map (subst v t) sq2
  in let rule1 = match rule with
       Axiom2(f) -> Axiom2(subst v t f)
     | RWeakening2(f,p) -> RWeakening2(subst v t f,subst_proof2 v t p)
     | LWeakening2(f,p) -> LWeakening2(subst v t f,subst_proof2 v t p)
     | RNeg2(f,p) -> RNeg2(subst v t f,subst_proof2 v t p)
     | LNeg2(f,p) -> LNeg2(subst v t f,subst_proof2 v t p)
     | RConj2(f1,p1,f2,p2) -> RConj2(subst v t f1,subst_proof2 v t p1,
       	       	       	       	   subst v t f2,subst_proof2 v t p2)
     | LDisj2(f1,p1,f2,p2) -> LDisj2(subst v t f1,subst_proof2 v t p1,
       	       	       	       	   subst v t f2,subst_proof2 v t p2)
     | LImp2(f1,p1,f2,p2) -> LImp2(subst v t f1,subst_proof2 v t p1,
       	       	       	       	   subst v t f2,subst_proof2 v t p2)
     | LConj2(f1,f2,p) -> LConj2(subst v t f1,subst v t f2,
      	       	       	       	   subst_proof2 v t p)
     | RDisj2(f1,f2,p) -> RDisj2(subst v t f1,subst v t f2,
      	       	       	       	   subst_proof2 v t p)
     | RImp2(f1,f2,p) -> RImp2(subst v t f1,subst v t f2,
      	       	       	       	   subst_proof2 v t p)
     | RForAll2(s,f,p) -> RForAll2(s,subst v t f,subst_proof2 v t p)
     | LExists2(s,f,p) -> LExists2(s,subst v t f,subst_proof2 v t p)
     | LForAll2(s,t1,f,p) -> LForAll2(s,subst_term v t t1,
      	       	       	       	    subst v t f,subst_proof2 v t p)
     | RExists2(s,t1,f,p) -> RExists2(s,subst_term v t t1,
      	       	       	       	    subst v t f,subst_proof2 v t p)
  in (Proof2(sq1',sq2',rule1))

(* All the free variables of a formula... ******)

let rec all_var_term  = function
     VAR s  -> [s]
   | GLOB _ -> []
   | APP lt -> all_var_list_term lt
and all_var_list_term = function
     t::ll -> union (all_var_term t) (all_var_list_term ll)
   | [] -> []

(* free_var_formula : formula -> identifier list ******)

let rec free_var_formula  = function
    Atom(s,lt) -> all_var_list_term lt
  | Neg(f) -> free_var_formula f
  | Imp(f1,f2) -> union (free_var_formula f1) (free_var_formula f2)
  | Conj(f1,f2) -> union (free_var_formula f1) (free_var_formula f2)
  | Disj(f1,f2) -> union (free_var_formula f1) (free_var_formula f2)
  | ForAll(s,f) -> substract (free_var_formula f) [s]
  | Exists(s,f) -> substract (free_var_formula f) [s]

(*** id_in_term : identifier -> term -> bool
     id_in_list : identifier -> term list -> bool ****)

let rec id_in_term id = function
    VAR id' -> id=id'
  | GLOB _  -> false
  | APP lt  -> id_in_list id lt
and id_in_list id = 
    List.fold_left (fun r t -> if r then true else id_in_term id t) false 


(*** id_in_formula : identifier -> formula -> bool ****)

let rec id_in_formula id = function
     Atom(_,lt) -> id_in_list id lt
   | Neg(f) -> id_in_formula id f
   | Conj(f1,f2) -> (id_in_formula id f1) or (id_in_formula id f2)
   | Disj(f1,f2) -> (id_in_formula id f1) or (id_in_formula id f2)
   | Imp(f1,f2) -> (id_in_formula id f1) or (id_in_formula id f2)
   | ForAll(id',f) -> (id=id') or (id_in_formula id f)
   | Exists(id',f) -> (id=id') or (id_in_formula id f)