Docs GODI Archive
Projects Blog Link DB

Search GODI:


More options
File lib/caduceus/why/caduceus_arith.why GODI Package apps-why
 
   caduceus_arith.why  

(* axiomatization of a memory model in which:
	- validity is checked based on arithmetic predicate
	- allocation table is still used
*)

(* bitwise operations *)
logic bw_compl : int -> int

logic bw_and : int,int -> int

logic bw_xor : int,int -> int

logic bw_or : int,int -> int

logic lsl : int,int -> int

logic lsr : int,int -> int

(* default variable initialisation *)

type 'z pointer

parameter any_pointer: unit -> {} 'z pointer { true }

(* pointer arithmetic *)

type 'z addr
type alloc_table
type ('a, 'z) memory

parameter alloc : alloc_table ref

logic null : 'z pointer

logic base_addr: 'z pointer -> 'z addr
logic offset: 'z pointer -> int
logic shift: 'z pointer,int -> 'z pointer
logic sub_pointer: 'z pointer, 'z pointer -> int
(* [arrlen(a,p)] returns the array length of pointer [p], i.e. the number
   of elements that can be accessed in p[0], p[1], etc. *)
logic arrlen: alloc_table, 'z pointer -> int
(* [strlen(m,p)] returns the string length of pointer [p] in memory [m],
   i.e. the number of non-null elements that can be accessed before 
   some null element (usually a byte). *)
logic strlen: ('a, 'z) memory, 'z pointer -> int
(* [full_separated(p,q)] is true when memory zones for pointers [p] and [q] are
   disjoint. *)
predicate full_separated(p:'z pointer,q:'z pointer) =
  p = null or q = null or base_addr(p) <> base_addr(q)

predicate lt_pointer(p1:'z pointer,p2: 'z pointer) =
  base_addr(p1) = base_addr(p2) and offset(p1) < offset(p2)
predicate le_pointer(p1:'z pointer,p2: 'z pointer) =
  base_addr(p1) = base_addr(p2) and offset(p1) <= offset(p2)
predicate gt_pointer(p1:'z pointer,p2: 'z pointer) =
  base_addr(p1) = base_addr(p2) and offset(p1) > offset(p2)
predicate ge_pointer(p1: 'z pointer,p2: 'z pointer) =
  base_addr(p1) = base_addr(p2) and offset(p1) >= offset(p2)

parameter eq_pointer : 
  p:'z pointer -> q: 'z pointer -> {} bool { if result then p=q else p<>q }
parameter neq_pointer : 
  p: 'z pointer -> q: 'z pointer -> {} bool { if result then p<>q else p=q }

(* a pointer [p] is valid iff its array length is strictly positive *)
predicate valid(a:alloc_table, p: 'z pointer) = 
	arrlen(a,p) > 0

(* an index [i] from a pointer [p] is valid iff [i] is strictly less than 
   its array length, and greater than 0 *)
predicate valid_index(a:alloc_table, p: 'z pointer, i:int) =
	0 <= i < arrlen(a,p)

(* a range [i,j] from a pointer [p] is valid iff both integers are valid 
   indices, and form a range *)
predicate valid_range(a:alloc_table, p: 'z pointer, i:int, j:int) =
	0 <= i <= j < arrlen(a,p)

axiom offset_shift :
(*   forall p: 'z pointer. forall i:int.  *)
  forall p: 'z pointer. forall i:int [offset(shift(p,i))]. 
  offset(shift(p,i)) = offset(p)+i

axiom shift_zero :
(*   forall p: 'z pointer. shift(p,0) = p *)
  forall p: 'z pointer [shift(p,0)]. shift(p,0) = p

axiom shift_shift :
(*   forall p:'z pointer. forall i:int. forall j:int. *)
  forall p:'z pointer. forall i:int. forall j:int [shift(shift(p,i),j)].
  shift(shift(p,i),j) = shift(p,i+j)

axiom base_addr_shift :
(*   forall p:'z pointer. forall i:int. *)
  forall p:'z pointer. forall i:int [base_addr(shift(p,i))].
  base_addr(shift(p,i)) = base_addr(p)

axiom pointer_pair_1 :
  forall p1:'z pointer. forall p2:'z pointer.
  (base_addr(p1) = base_addr(p2) and offset(p1) = offset(p2)) -> p1 = p2

axiom pointer_pair_2 :
  forall p1:'z pointer. forall p2:'z pointer.
  p1 = p2 -> (base_addr(p1) = base_addr(p2) and offset(p1) = offset(p2))

(* the following properties can be proved; here to help Simplify *)
axiom neq_base_addr_neq_shift :
  forall p1:'z pointer. forall p2: 'z pointer.
  forall i:int. forall j:int.
  base_addr(p1) <> base_addr(p2) -> shift(p1,i) <> shift(p2,j)

axiom neq_offset_neq_shift :
  forall p1: 'z pointer. forall p2: 'z pointer.
  forall i:int. forall j:int.
  offset(p1)+i <> offset(p2)+j -> shift(p1,i) <> shift(p2,j)

axiom eq_offset_eq_shift :
  forall p1:'z pointer. forall p2: 'z pointer.
  forall i:int. forall j:int.
  base_addr(p1) = base_addr(p2) -> 
	offset(p1)+i = offset(p2)+j -> shift(p1,i) = shift(p2,j)

axiom valid_index_valid_shift :
  forall a:alloc_table. forall p:'z pointer. forall i:int. 
  valid_index(a,p,i) -> valid(a,shift(p,i))

(* redondant avec le predecent et le suivant, mais utile *)
axiom valid_range_valid_shift :
  forall a:alloc_table. forall p:'z pointer. forall i:int. forall j:int. forall k:int.
  valid_range(a,p,i,j) -> i <= k <= j -> valid(a,shift(p,k))

axiom valid_range_valid :
  forall a:alloc_table. forall p:'z pointer. forall i:int. forall j:int. 
  valid_range(a,p,i,j) -> i <= 0 <= j -> valid(a,p)

axiom valid_range_valid_index :
  forall a:alloc_table. forall p:'z pointer. forall i:int. forall j:int. forall k:int.
  valid_range(a,p,i,j) -> i <= k <= j -> valid_index(a,p,k)

axiom sub_pointer_def :
  forall p1:'z pointer. forall p2:'z pointer.
  base_addr(p1) = base_addr(p2) -> sub_pointer(p1,p2) = offset(p1)-offset(p2)

axiom sub_pointer_self :
  forall p:'z pointer. sub_pointer(p,p) = 0

axiom sub_pointer_shift1 :
  forall p:'z pointer. forall q:'z pointer. forall i:int.
    sub_pointer(shift(p,i),q) = sub_pointer(p,q) + i

axiom sub_pointer_shift2 :
  forall p:'z pointer. forall q:'z pointer. forall i:int.
    sub_pointer(p,shift(q,i)) = sub_pointer(p,q) - i

axiom shift_sub_pointer :
  forall p:'z pointer. forall q:'z pointer [sub_pointer(p,q)].
    p = shift(q,sub_pointer(p,q))

parameter shift_ : p:'z pointer -> i:int -> 
  { } 'z pointer { result = shift(p,i) }

parameter sub_pointer_ : p1:'z pointer -> p2:'z pointer ->
  { base_addr(p1) = base_addr(p2) } int { result = offset(p1) - offset(p2) }

parameter lt_pointer_ : p1:'z pointer -> p2:'z pointer ->
  { base_addr(p1) = base_addr(p2) } bool 
  { if result then offset(p1) < offset(p2) else offset(p1) >= offset(p2) }

parameter le_pointer_ : p1:'z pointer -> p2:'z pointer ->
  { base_addr(p1) = base_addr(p2) } bool 
  { if result then offset(p1) <= offset(p2) else offset(p1) > offset(p2) }

parameter gt_pointer_ : p1:'z pointer -> p2:'z pointer ->
  { base_addr(p1) = base_addr(p2) } bool 
  { if result then offset(p1) > offset(p2) else offset(p1) <= offset(p2) }

parameter ge_pointer_ : p1:'z pointer -> p2:'z pointer ->
  { base_addr(p1) = base_addr(p2) } bool 
  { if result then offset(p1) >= offset(p2) else offset(p1) < offset(p2) }

(* pointer access *)
logic acc: ('a,'z) memory, 'z pointer -> 'a
parameter acc_ : m: ('a,'z) memory ref -> p:'z pointer -> 
  { valid(alloc,p) }
  'a reads alloc,m
  { result = acc(m,p) }
parameter acc_offset : m: ('a,'z) memory ref -> p:'z pointer -> 
	i : int -> n : int ->
  { 0 <= i < n }
  'a reads alloc,m
  { result = acc(m,p) }
parameter safe_acc_ : m: ('a,'z) memory ref -> p:'z pointer -> 
  { }
  'a reads alloc,m
  { result = acc(m,p) }

(* pointer update *)
logic upd: ('a,'z) memory, 'z pointer, 'a -> ('a,'z) memory
parameter upd_ : m:('a,'z) memory ref -> p:'z pointer -> v:'a -> 
  { valid(alloc,p) }
  unit reads alloc,m writes m
  { m = upd(m@,p,v) }
parameter upd_offset : m:('a,'z) memory ref -> p:'z pointer -> v:'a -> i:int ->
	size:int -> 
  { 0<= i < size }
  unit reads alloc,m writes m
  { m = upd(m@,p,v) }
parameter safe_upd_ : m:('a,'z) memory ref -> p:'z pointer -> v:'a -> 
  { }
  unit reads alloc,m writes m
  { m = upd(m@,p,v) }

axiom acc_upd : 
  forall m : ('a,'z) memory. forall p : 'z pointer. forall a: 'a [acc(upd(m,p,a),p)].
    acc(upd(m,p,a),p) = a
 
axiom acc_upd_eq : 
  forall m : ('a,'z) memory. forall p1: 'z pointer. forall p2 : 'z pointer. 
  forall a: 'a [acc(upd(m,p1,a),p2)].
    p1=p2 -> acc(upd(m,p1,a),p2) = a
 
axiom acc_upd_neq : 
  forall m : ('a,'z) memory. forall p1: 'z pointer. forall p2 : 'z pointer. 
  forall a: 'a [acc(upd(m,p1,a),p2)].
    p1 <> p2 -> acc(upd(m,p1,a),p2) = acc(m,p2)

(* axiomatic definition of [arrlen] *)
axiom arrlen_shift :
  forall a:alloc_table. forall p: 'z pointer. 
  forall i:int [arrlen(a,shift(p,i))].
    i >= 0 -> arrlen(a,shift(p,i)) = arrlen(a,p)-i

axiom arrlen_sub_pointer :
  forall a:alloc_table. forall p: 'z pointer. forall q:'z pointer
  [sub_pointer(q,p)].
    0 <= sub_pointer(q,p) -> arrlen(a,q) = arrlen(a,p) - sub_pointer(q,p)

(* axiomatic definition of [strlen] *)
axiom strlen_create :
  forall m : (int,'z) memory. forall p: 'z pointer. 
  forall i:int [strlen(upd(m,shift(p,i),0),p)].
    i >= 0 -> 0 <= strlen(upd(m,shift(p,i),0),p) <= i

axiom strlen_init :
  forall m : (int,'z) memory. forall p: 'z pointer. 
  forall i:int [strlen(upd(m,shift(p,i),0),p)]. 
    i >= 0 and (forall j:int. 0 <= j < i -> acc(m,shift(p,j)) <> 0)
    -> strlen(upd(m,shift(p,i),0),p) = i

axiom strlen_is_zero :
  forall m : (int,'z) memory. 
  forall p: 'z pointer [acc(m,shift(p,strlen(m,p)))]. 
    strlen(m,p) >= 0 -> acc(m,shift(p,strlen(m,p))) = 0

axiom strlen_not_zero :
  forall m : (int,'z) memory. forall p: 'z pointer. 
  forall i:int [strlen(m,p),acc(m,shift(p,i))]. 
    0 <= i <= strlen(m,p) and acc(m,shift(p,i)) <> 0 -> i < strlen(m,p)

axiom strlen_zero :
  forall m : (int,'z) memory. forall p: 'z pointer. 
  forall i:int [strlen(m,p),acc(m,shift(p,i))]. 
    0 <= i <= strlen(m,p) and acc(m,shift(p,i)) = 0 -> i = strlen(m,p)

axiom strlen_shift :
  forall m : ('a,'z) memory. forall p: 'z pointer. 
  forall i:int [strlen(m,shift(p,i))].
  0 <= i -> strlen(m,shift(p,i)) = strlen(m,p)-i

axiom strlen_update_before :
  forall m : ('a,'z) memory. forall p: 'z pointer. 
  forall v:'a. forall i:int [strlen(upd(m,shift(p,i),v),p)]. 
    0 <= i < strlen(m,p) -> strlen(upd(m,shift(p,i),v),p) <= strlen(m,p)

axiom strlen_update_before_not_zero :
  forall m : (int,'z) memory. forall p: 'z pointer. 
  forall v:int. forall i:int [strlen(upd(m,shift(p,i),v),p)]. 
    0 <= i < strlen(m,p) and v <> 0 
      -> strlen(upd(m,shift(p,i),v),p) = strlen(m,p)

axiom strlen_update_zero :
  forall m : (int,'z) memory. forall p: 'z pointer. 
  forall i:int [strlen(upd(m,shift(p,i),0),p)]. 
    0 <= i <= strlen(m,p) -> strlen(upd(m,shift(p,i),0),p) = i

(* axiom linking [arrlen] and [strlen] *)
axiom arrlen_strlen :
  forall a:alloc_table. forall m : ('a,'z) memory. 
  forall p: 'z pointer [strlen(m,p), arrlen(a,p)]. 
    strlen(m,p) >= 0 -> strlen(m,p) < arrlen(a,p)

(* axioms only to help automatic proof *)
axiom full_separated_strlen_upd :
  forall m : ('a,'z) memory. forall p: 'z pointer. forall q : 'z pointer.
    forall v:'a. forall i:int [strlen(upd(m,shift(p,i),v),q)]. 
      full_separated(p,q) -> strlen(upd(m,shift(p,i),v),q) = strlen(m,q)

axiom full_separated_shift1 :
  forall p: 'z pointer. forall q : 'z pointer. forall i: int.
    full_separated(p,q) -> full_separated(p,shift(q,i))

axiom full_separated_shift2 :
  forall p: 'z pointer. forall q : 'z pointer. forall i: int.
    full_separated(p,q) -> full_separated(shift(q,i),p)

axiom full_separated_shift3 :
  forall p: 'z pointer. forall q : 'z pointer. forall i: int.
    full_separated(q,p) -> full_separated(shift(q,i),p)

axiom full_separated_shift4 :
  forall p: 'z pointer. forall q : 'z pointer. forall i: int.
    full_separated(q,p) -> full_separated(p,shift(q,i))

(* min/max *)

logic min: int,int -> int
logic max: int,int -> int

axiom min_below :
  forall i:int. forall j:int. min(i,j) <= i and min(i,j) <= j

axiom min_above :
  forall i:int. forall j:int. min(i,j) >= i or min(i,j) >= j

axiom max_above :
  forall i:int. forall j:int. max(i,j) >= i and max(i,j) >= j

axiom max_below :
  forall i:int. forall j:int. max(i,j) <= i or max(i,j) <= j

(* exceptions *)
exception Break
exception Continue
exception Return
exception Return_int of int
exception Return_real of real
exception Return_pointer (*of 'z pointer*)

(* for Simplify *)

axiom false_not_true : false <> true

(* modeling assigns clauses 
   the type (pset) represents a set of pointers *)

type 'z pset

logic pset_empty : -> 'z pset
logic pset_singleton : 'z pointer -> 'z pset
logic pset_star : 'z pset, ('y pointer,'z) memory -> 'y pset (* *l or l->x *)

logic pset_all : 'z pset -> 'z pset (* l(..) *)
logic pset_range : 'z pset, int, int -> 'z pset (* l(a..b) *)
logic pset_range_left : 'z pset, int -> 'z pset (* l(..b) *)
logic pset_range_right : 'z pset, int -> 'z pset (* l(a..) *)

logic pset_acc_all : 'z pset, ('y pointer,'z) memory -> 'y pset (* l(..) *)
logic pset_acc_range : 'z pset, ('y pointer,'z) memory, int, int -> 'y pset (* l(a..b) *)
logic pset_acc_range_left : 'z pset, ('y pointer,'z) memory, int -> 'y pset (* l(..b) *)
logic pset_acc_range_right : 'z pset, ('y pointer,'z) memory, int -> 'y pset (* l(a..) *)

logic pset_union : 'z pset, 'z pset -> 'z pset

logic not_in_pset : 'z pointer, 'z pset -> prop (* not_in_pset(p,s) = p is not in s *)

predicate not_assigns 
	(a:alloc_table,m1:('a,'z) memory,m2:('a,'z) memory,l:'z pset) =
 forall p:'z pointer.
    valid(a,p) -> not_in_pset(p,l) -> acc(m2,p)=acc(m1,p)

axiom pset_empty_intro :
  forall p:'z pointer. not_in_pset(p, pset_empty)

axiom pset_singleton_intro : 
  forall p1:'z pointer.forall p2:'z pointer [not_in_pset(p1, pset_singleton(p2))].
    p1 <> p2 -> not_in_pset(p1, pset_singleton(p2))

axiom pset_singleton_elim : 
  forall p1:'z pointer. forall p2:'z pointer [not_in_pset(p1, pset_singleton(p2))].
    not_in_pset(p1, pset_singleton(p2)) -> p1 <> p2

axiom not_not_in_singleton :
  forall p:'z pointer. not not_in_pset(p, pset_singleton(p))

axiom pset_union_intro : 
  forall l1:'z pset. forall l2:'z pset. forall p:'z pointer
	[not_in_pset(p, pset_union(l1,l2))].
     not_in_pset(p, l1) and not_in_pset(p, l2) -> 
     not_in_pset(p, pset_union(l1,l2))

axiom pset_union_elim1 : 
  forall l1:'z pset. forall l2:'z pset. forall p:'z pointer
	[not_in_pset(p, pset_union(l1,l2))].
    not_in_pset(p, pset_union(l1,l2)) -> not_in_pset(p,l1) 

axiom pset_union_elim2 : 
  forall l1:'z pset. forall l2:'z pset. forall p:'z pointer
	[not_in_pset(p, pset_union(l1,l2))].
    not_in_pset(p, pset_union(l1,l2)) -> not_in_pset(p,l2)

axiom pset_star_intro :
  forall l:'z pset. forall m:('y pointer,'z) memory. forall p:'y pointer
	[not_in_pset(p, pset_star(l, m))].
    (forall p1:'z pointer. p = acc(m,p1) -> not_in_pset(p1, l)) ->
    not_in_pset(p, pset_star(l, m))

axiom pset_star_elim :
  forall l:'z pset. forall m:('y pointer,'z) memory. forall p:'y pointer
	[not_in_pset(p, pset_star(l, m))].
    not_in_pset(p, pset_star(l, m)) ->
    (forall p1:'z pointer. p = acc(m,p1) -> not_in_pset(p1, l))

(* s(..) *)

axiom pset_all_intro :
  forall p:'z pointer. forall l:'z pset [not_in_pset(p, pset_all(l))].
    (forall p1:'z pointer. 
       (not not_in_pset(p1,l)) -> base_addr(p) <> base_addr(p1)) ->
    not_in_pset(p, pset_all(l))

axiom pset_all_elim :
  forall p:'z pointer. forall l:'z pset [not_in_pset(p, pset_all(l))].
    not_in_pset(p, pset_all(l)) ->
    (forall p1:'z pointer. 
       (not not_in_pset(p1,l)) -> base_addr(p) <> base_addr(p1))

axiom pset_range_intro :
  forall p:'z pointer. forall l:'z pset. forall a:int. forall b:int
	[not_in_pset(p, pset_range(l,a,b))].
    (forall p1:'z pointer. not_in_pset(p1, l) or
	forall i:int. (a <= i <= b) -> (p <> shift(p1,i))) -> 
    not_in_pset(p, pset_range(l,a,b))	

axiom pset_range_elim :
  forall p:'z pointer. forall l:'z pset. forall a:int. forall b:int
	[not_in_pset(p, pset_range(l,a,b))].
    not_in_pset(p, pset_range(l,a,b)) ->
      forall p1:'z pointer. (not not_in_pset(p1, l)) ->
	forall i:int. a <= i <= b -> shift(p1,i) <> p

axiom pset_range_left_intro :
  forall p:'z pointer. forall l:'z pset. forall a:int
	[not_in_pset(p, pset_range_left(l,a))].
    (forall p1:'z pointer. not_in_pset(p1, l) or
	forall i:int. (i <= a) -> (p <> shift(p1,i))) -> 
    not_in_pset(p, pset_range_left(l,a))	

axiom pset_range_left_elim :
  forall p:'z pointer. forall l:'z pset. forall a:int
	[not_in_pset(p, pset_range_left(l,a))]. 
    not_in_pset(p, pset_range_left(l,a)) ->
      forall p1:'z pointer. (not not_in_pset(p1, l)) ->
	forall i:int. i <= a -> shift(p1,i) <> p

axiom pset_range_right_intro :
  forall p:'z pointer. forall l:'z pset. forall a:int
	[not_in_pset(p, pset_range_right(l,a))].
    (forall p1:'z pointer. not_in_pset(p1, l) or
	forall i:int. (a <= i) -> (p <> shift(p1,i))) -> 
    not_in_pset(p, pset_range_right(l,a))	

axiom pset_range_right_elim :
  forall p:'z pointer. forall l:'z pset. forall a:int
	[not_in_pset(p, pset_range_right(l,a))].
    not_in_pset(p, pset_range_right(l,a)) ->
      forall p1:'z pointer. (not not_in_pset(p1, l)) ->
	forall i:int. a <= i -> shift(p1,i) <> p

(* elements of s(..) *)
axiom pset_acc_all_intro :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory
	[not_in_pset(p, pset_acc_all(l, m))].
    (forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> forall i:int. p <> acc(m, shift(p1,i))) ->
    not_in_pset(p, pset_acc_all(l, m))

axiom pset_acc_all_elim :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory
	[not_in_pset(p, pset_acc_all(l, m))].
    not_in_pset(p, pset_acc_all(l, m)) ->
    forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> forall i:int. acc(m, shift(p1,i)) <> p

axiom pset_acc_range_intro :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory. 
  forall a:int. forall b:int [not_in_pset(p, pset_acc_range(l, m, a, b))].
    (forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> 
      forall i:int. a <= i <= b -> p <> acc(m, shift(p1,i))) ->
    not_in_pset(p, pset_acc_range(l, m, a, b))

axiom pset_acc_range_elim :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory.
  forall a:int. forall b:int.
    not_in_pset(p, pset_acc_range(l, m, a, b)) ->
    forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> 
	 forall i:int. a <= i <= b -> acc(m, shift(p1,i)) <> p

axiom pset_acc_range_left_intro :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory. 
  forall a:int [not_in_pset(p, pset_acc_range_left(l, m, a))].
    (forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> 
      forall i:int. i <= a -> p <> acc(m, shift(p1,i))) ->
    not_in_pset(p, pset_acc_range_left(l, m, a))

axiom pset_acc_range_left_elim :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory.
  forall a:int [not_in_pset(p, pset_acc_range_left(l, m, a))].
    not_in_pset(p, pset_acc_range_left(l, m, a)) ->
    forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> 
	 forall i:int. i <= a -> acc(m, shift(p1,i)) <> p

axiom pset_acc_range_right_intro :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory. 
  forall a:int [not_in_pset(p, pset_acc_range_right(l, m, a))].
    (forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> 
      forall i:int. a <= i -> p <> acc(m, shift(p1,i))) ->
    not_in_pset(p, pset_acc_range_right(l, m, a))

axiom pset_acc_range_right_elim :
  forall p:'y pointer. forall l:'z pset. forall m:('y pointer,'z) memory.
  forall a:int [not_in_pset(p, pset_acc_range_right(l, m, a))].
    not_in_pset(p, pset_acc_range_right(l, m, a)) ->
    forall p1:'z pointer.
      (not not_in_pset(p1,l)) -> 
	 forall i:int. a <= i -> acc(m, shift(p1,i)) <> p

(* lemmas on not_assigns *)

axiom not_assigns_trans :
  forall a:alloc_table. forall l:'z pset. 
  forall m1:('a,'z) memory. forall m2:('a,'z) memory. forall m3: ('a,'z) memory.
  not_assigns(a,m1,m2,l) -> not_assigns(a,m2,m3,l) -> not_assigns(a,m1,m3,l)

axiom not_assigns_refl :
  forall a:alloc_table. forall l:'z pset. 
  forall m:('a,'z) memory. not_assigns(a,m,m,l)

(* validity *)

predicate valid_acc(m1: ('y pointer,'z) memory) =
	forall p : 'z pointer. forall a : alloc_table.
	valid(a,p) -> valid(a,acc(m1, p)) 

predicate valid_acc_range (m1: ('y pointer,'z) memory, size : int) =
	forall p : 'z pointer. forall a : alloc_table.
	valid(a,p) -> valid_range (a,acc (m1, p), 0, size-1) 

axiom valid_acc_range_valid : 
  forall m1: ('y pointer,'z) memory.
  forall size : int. forall p : 'z pointer. forall a : alloc_table.
  valid_acc_range(m1,size) -> valid(a,p) -> valid(a, acc(m1,p))

(* separation *)

predicate separation1(m1:('y pointer,'z) memory, m2:('y pointer,'z) memory) =
  forall p:'z pointer. forall a : alloc_table.
    valid(a, p) -> base_addr(acc(m1, p)) <> base_addr(acc(m2, p))

predicate separation1_range1(m1:('y pointer,'z) memory,
	m2:('y pointer,'z) memory, size : int) =
	forall p : 'z pointer.forall a : alloc_table.
	valid(a,p) -> forall i : int . 0 <= i < size ->
	base_addr(acc(m1,(shift (p,i)))) <> base_addr(acc(m2, p))	

predicate separation1_range(m:('y pointer,'z) memory, size:int) =
	forall p : 'z pointer.forall a : alloc_table.
	valid(a,p) -> forall i1 : int. forall i2 : int. 
	0 <= i1 < size -> 0 <= i2 < size -> i1 <> i2 -> 
	base_addr(acc(m,(shift (p,i1)))) <> base_addr(acc(m,shift (p,i2)))  


predicate separation2(m1:('y pointer,'z) memory, m2:('y pointer,'z) memory) =
  forall p1:'z pointer. forall p2:'z pointer.
    p1 <> p2 -> base_addr(acc(m1, p1)) <> base_addr(acc(m2, p2))
	
predicate separation2_range1(m1:('y pointer,'z) memory,
	m2:('y pointer,'z) memory, size : int) =
	forall p : 'z pointer. forall q : 'z pointer.forall a : alloc_table.
	forall i : int . 0 <= i < size ->
	base_addr(acc(m1,(shift (p,i)))) <> base_addr(acc(m2, q))

(* memory allocation *)

logic on_heap : alloc_table, 'z pointer -> prop
logic on_stack : alloc_table, 'z pointer -> prop

(* fresh(a,p) means that the memory block of p is not allocated in a *)
logic fresh : alloc_table,'z pointer -> prop

axiom fresh_not_valid :
  forall a:alloc_table. forall p:'z pointer. 
    fresh(a,p) -> not(valid(a,p))

axiom fresh_not_valid_shift :
  forall a:alloc_table. forall p:'z pointer. 
    fresh(a,p) -> forall i:int. not(valid(a,shift(p,i)))

axiom fresh_full_separated :
  forall a:alloc_table. forall p:'z pointer. forall q:'z pointer. 
    fresh(a,p) -> valid(a,q) -> full_separated(p,q)

(***
predicate alloc_heap(a1 : alloc_table, a2 : alloc_table) =
  forall p:'z pointer. 
    arrlen(a1,p) > 0 -> arrlen(a1,p) = arrlen(a2,p)

axiom alloc_heap_valid : 
  forall a1:alloc_table. forall a2:alloc_table.
    alloc_heap(a1,a2) -> forall p:'z pointer. valid(a1,p) -> valid(a2,p)

axiom alloc_heap_valid_range : 
  forall a1:alloc_table. forall a2:alloc_table.
    alloc_heap(a1,a2) -> 
    forall p:'z pointer. forall i:int. forall j:int.
      valid_range(a1,p,i,j) -> valid_range(a2,p,i,j)
***)

logic alloc_extends : alloc_table, alloc_table -> prop

axiom alloc_extends_valid : 
  forall a1:alloc_table. forall a2:alloc_table.
    alloc_extends(a1,a2) -> forall q:'y pointer. valid(a1,q) -> valid(a2,q)

axiom alloc_extends_arrlen : 
  forall a1:alloc_table. forall a2:alloc_table.
    alloc_extends(a1,a2) -> forall q:'y pointer. 
      valid(a1,q) -> arrlen(a2,q) = arrlen(a1,q)

axiom alloc_extends_valid_index : 
  forall a1:alloc_table. forall a2:alloc_table.
    alloc_extends(a1,a2) -> 
    forall q:'y pointer. forall i:int.
      valid_index(a1,q,i) -> valid_index(a2,q,i)

axiom alloc_extends_valid_range : 
  forall a1:alloc_table. forall a2:alloc_table.
    alloc_extends(a1,a2) -> 
    forall q:'y pointer. forall i:int. forall j:int.
      valid_range(a1,q,i,j) -> valid_range(a2,q,i,j)

axiom alloc_extends_refl : forall a:alloc_table. alloc_extends(a,a) 

axiom alloc_extends_trans : 
  forall a1,a2,a3:alloc_table [alloc_extends(a1,a2), alloc_extends(a2,a3)]. 
    alloc_extends(a1,a2) -> 
    alloc_extends(a2,a3) -> 
    alloc_extends(a1,a3) 

(*
logic free_heap : 'z pointer, alloc_table, alloc_table -> prop

parameter free_block : p:'z pointer -> 
	{ valid(alloc,p) and offset(p) = 0 and on_heap(alloc,p) }
	unit writes alloc
	{ free_heap(p, alloc@, alloc) }
*)

(*

  (free_stack(a1,a2,a3)) specifies the relations between states of allocation table before and after a function body is executed :

  a1 : alloc_table at beginning
  a2 : alloc_table before return: some allocations occured in (a1) both 
       on heap and on stack 
  a3 : alloc_table after return: allocations on stack between (a1) and 
       (a2) are not valid anymore

*)

logic free_stack : alloc_table, alloc_table, alloc_table -> prop

axiom free_stack_heap : 
  forall a1 : alloc_table. forall a2 : alloc_table. forall a3 : alloc_table. 
    free_stack(a1,a2,a3) -> 
      (forall p : 'z pointer. valid(a2, p) -> on_heap(a2,p) -> valid(a3, p))

axiom free_stack_stack : 
  forall a1 : alloc_table. forall a2 : alloc_table. forall a3 : alloc_table. 
     free_stack(a1,a2,a3) -> 
      (forall p : 'z pointer. valid(a1, p) -> on_stack(a1,p) -> valid(a3, p))

parameter alloca_parameter : n:int -> 
	{ n >= 0 }
	'z pointer writes alloc
	{ valid(alloc,result) and offset(result) = 0 and 	
	  arrlen(alloc,result) = n and valid_range(alloc,result,0,n-1)
	  and fresh(alloc@,result) and on_stack(alloc,result) 
	  and alloc_extends (alloc@,alloc) }

parameter malloc_parameter : n:int -> 
	{ n >= 0 }
	'z pointer writes alloc
	{ valid(alloc,result) and offset(result) = 0 and 	
	  arrlen(alloc,result) = n and valid_range(alloc,result,0,n-1)
	  and fresh(alloc@,result) and on_heap(alloc,result)
	  and alloc_extends (alloc@,alloc) }



This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml