2026-05-08 12:06:53 +00:00
|
|
|
(* NOTE: in previous models foldl & foldr are probably spapped
|
|
|
|
|
<- TODO: fix ? *)
|
|
|
|
|
|
2026-03-29 15:32:35 +00:00
|
|
|
module Relational =
|
|
|
|
|
struct
|
|
|
|
|
open GT
|
2026-05-04 13:42:53 +00:00
|
|
|
open OCanren
|
2026-03-29 15:32:35 +00:00
|
|
|
open OCanren.Std
|
|
|
|
|
|
|
|
|
|
type data_ground = Nat.ground (* with show, gmap *)
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type data_logic = Nat.logic
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type data_injected = Nat.injected
|
|
|
|
|
|
|
|
|
|
module ReadCap = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = Rd | NRd
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module WriteCap = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = AlwaysWr | MayWr | NeverWr
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module CopyCap = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-01 13:45:09 +00:00
|
|
|
type nonrec t = Rf | Cp
|
2026-03-29 15:32:35 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = t
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module InCap = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = In | NIn
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module OutCap = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = Out | NOut
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2026-05-04 13:00:32 +00:00
|
|
|
module Mode = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec ('i, 'o) t = Mode of 'i * 'o
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = (InCap.ground, OutCap.ground) t
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
(* constructors *)
|
|
|
|
|
let n_val = let open InCap in
|
|
|
|
|
let open OutCap in
|
|
|
|
|
ocanren { Mode (NIn, NOut) }
|
|
|
|
|
let i_val = let open InCap in
|
|
|
|
|
let open OutCap in
|
|
|
|
|
ocanren { Mode (In, NOut) }
|
|
|
|
|
let o_val = let open InCap in
|
|
|
|
|
let open OutCap in
|
|
|
|
|
ocanren { Mode (NIn, Out) }
|
|
|
|
|
let io_val = let open InCap in
|
|
|
|
|
let open OutCap in
|
|
|
|
|
ocanren { Mode (In, Out) }
|
|
|
|
|
|
|
|
|
|
(* accessors *)
|
|
|
|
|
let is_ino m = let open InCap in ocanren {
|
|
|
|
|
fresh o_ in
|
|
|
|
|
m == Mode (In, o_) }
|
|
|
|
|
let is_not_ino m = let open InCap in ocanren {
|
|
|
|
|
fresh o_ in
|
|
|
|
|
m == Mode (NIn, o_) }
|
|
|
|
|
let is_outo m = let open OutCap in ocanren {
|
|
|
|
|
fresh i_ in
|
|
|
|
|
m == Mode (i_, Out) }
|
|
|
|
|
let is_not_outo m = let open OutCap in ocanren {
|
|
|
|
|
fresh i_ in
|
|
|
|
|
m == Mode (i_, NOut) }
|
|
|
|
|
|
|
|
|
|
(* module Test = struct *)
|
|
|
|
|
(* @type answer = logic GT.list with show *)
|
|
|
|
|
|
|
|
|
|
(* let test _ = show(answer) (Stream.take (run q (fun q -> let open InCap in *)
|
|
|
|
|
(* let open OutCap in *)
|
|
|
|
|
(* ocanren {q == Mode (In, NOut)}) *)
|
|
|
|
|
(* (fun q -> q#reify reify))) *)
|
|
|
|
|
(* end *)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module Path = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec ('d, 'p) t = VarP of 'd | DerefP of 'p | AccessP of 'p * 'd
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = (Nat.ground, ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module Type = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec ('r, 'w, 'c, 't, 'tl, 'mtl) t = UnitT of 'r * 'w | RefT of 'c * 't | TupleT of 'tl | FunT of 'mtl
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = (ReadCap.ground, WriteCap.ground, CopyCap.ground, ground, ground List.ground, (Mode.ground * ground) List.ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
(* moded type - no separated type ? *)
|
|
|
|
|
|
|
|
|
|
module Expr = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec ('d, 'p, 'el) t = UnitE | PathE of 'p | RefE of 'd | TupleE of 'el
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = (Nat.ground, Path.ground, ground List.ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module Stmt = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec ('p, 'el, 's) t = SkipS | CallS of 'p * 'el | WriteS of 'p | ReadS of 'p | SeqS of 's * 's | ChoiceS of 's * 's
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = (Path.ground, Expr.ground List.ground, ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
(* TODO: list of 3 is not impelmented ?, replaced with two lists for now *)
|
|
|
|
|
module Decl = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-08 12:06:53 +00:00
|
|
|
type nonrec ((* 'd, *) 't, 'e, (* 'dl, *) 'mtl, 's) t = VarD of (* 'd * *) 't * 'e | FunD of (* 'd * 'dl * *) 'mtl * 's
|
2026-05-04 13:00:32 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
2026-05-08 12:06:53 +00:00
|
|
|
type ground = ((* Nat.ground, *) Type.ground, Expr.ground, (* Nat.ground List.ground, *) (Mode.ground * Type.ground) List.ground, Stmt.ground) t
|
2026-05-04 13:00:32 +00:00
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
module Prg = struct
|
2026-05-04 13:00:32 +00:00
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-05 14:35:35 +00:00
|
|
|
type nonrec ('dl, 's) t = Prg of 'dl * 's
|
2026-05-04 13:00:32 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = (Decl.ground List.ground, Stmt.ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
(* NOTE: deepvalue - not used (?) *)
|
|
|
|
|
|
2026-05-13 18:46:01 +00:00
|
|
|
module MemVal = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = ZeroMV | SmthMV | BotMV
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module ReadVal = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = ZeroRV | OneRV | TopRV
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module WriteVal = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = ZeroWV | SmthWV | OneWV
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2026-05-04 13:00:32 +00:00
|
|
|
module Value = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-13 18:46:01 +00:00
|
|
|
type nonrec ('vm, 'vr, 'vw, 'sl, 'd, 'vl) t = UnitV of 'vm * 'vr * 'vw
|
|
|
|
|
| FunV of 'sl
|
|
|
|
|
| RefV of 'd
|
|
|
|
|
| TupleV of 'vl
|
2026-05-04 13:00:32 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
2026-05-13 18:46:01 +00:00
|
|
|
type ground = (MemVal.ground, ReadVal.ground, WriteVal.ground,
|
|
|
|
|
((* Nat.ground List.ground * *) Stmt.ground) List.ground,
|
|
|
|
|
Nat.ground, ground List.ground) t
|
2026-05-04 13:00:32 +00:00
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2026-05-10 17:19:00 +00:00
|
|
|
module RevPath = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec ('d, 'p) t = VarRP | DerefRP of 'p | AccessRP of 'p * 'd
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = (Nat.ground, ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2026-05-13 18:46:01 +00:00
|
|
|
module Action = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec t = ReadA | AlwaysWriteA | MayWriteA
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type ground = t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2026-05-04 13:42:53 +00:00
|
|
|
(* --- *)
|
2026-05-01 13:45:09 +00:00
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
module MemEnv = struct
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-05 14:35:35 +00:00
|
|
|
type nonrec ('vl, 'd) t = MemEnv of 'vl * 'd
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = (Value.ground List.ground, Nat.ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
2026-05-01 13:45:09 +00:00
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
module TypesEnv = struct
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-06 17:17:36 +00:00
|
|
|
type nonrec 'dtl t = TypesEnv of 'dtl (* glob *) * 'dtl (* glob + loc *)
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = ((Nat.ground * Type.ground) List.ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
2026-05-01 13:45:09 +00:00
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
module ValsEnv = struct
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-06 17:17:36 +00:00
|
|
|
type nonrec 'ddl t = ValsEnv of 'ddl (* glob *) * 'ddl (* glob + loc *)
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = ((Nat.ground * Nat.ground) List.ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
2026-05-01 13:45:09 +00:00
|
|
|
|
2026-05-09 17:29:54 +00:00
|
|
|
module VisitedEnv = struct
|
|
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
|
|
|
|
type nonrec 'sl t = VisitedEnv of 'sl
|
|
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
|
|
|
|
type nonrec ground = (Stmt.ground List.ground) t
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
module StEnv = struct
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@@warning "-26-27-32-33-34-35-36-37-38-39-60-66-67"]
|
|
|
|
|
[%%ocanren_inject
|
2026-05-09 17:29:54 +00:00
|
|
|
type nonrec ('mem, 'types, 'vals, 'visited) t = StEnv of 'mem * 'types * 'vals * 'visited
|
2026-05-04 13:42:53 +00:00
|
|
|
[@@deriving gt ~options:{ show; gmap }]
|
2026-05-09 17:29:54 +00:00
|
|
|
type nonrec ground = (MemEnv.ground, TypesEnv.ground, ValsEnv.ground, VisitedEnv.ground) t
|
2026-05-04 13:42:53 +00:00
|
|
|
]
|
|
|
|
|
end
|
2026-05-01 13:45:09 +00:00
|
|
|
|
2026-05-04 13:42:53 +00:00
|
|
|
(* --- *)
|
2026-05-01 13:45:09 +00:00
|
|
|
|
2026-05-04 13:42:53 +00:00
|
|
|
(* - utils *)
|
|
|
|
|
|
|
|
|
|
let rec list_replaceo xs id value ys = ocanren {
|
|
|
|
|
(* xs == [] & ys == [] | (* NOTE: error *) *)
|
|
|
|
|
{ fresh x, xs' in
|
|
|
|
|
xs == x :: xs' &
|
|
|
|
|
id == Nat.o &
|
|
|
|
|
ys == value :: xs' } |
|
|
|
|
|
{ fresh x, xs', id', ys' in
|
|
|
|
|
xs == x :: xs' &
|
|
|
|
|
id == Nat.s id' &
|
|
|
|
|
ys == x :: ys' &
|
|
|
|
|
list_replaceo xs' id' value ys' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let rec list_ntho xs id x' = ocanren {
|
|
|
|
|
(* xs == [] | (* NOTE: error *) *)
|
|
|
|
|
{ fresh y', xs' in
|
|
|
|
|
id == Nat.o &
|
|
|
|
|
y' :: xs' == xs &
|
|
|
|
|
x' == y' } |
|
|
|
|
|
{ fresh id', y', xs' in
|
|
|
|
|
Nat.s id' == id &
|
|
|
|
|
y' :: xs' == xs &
|
|
|
|
|
list_ntho xs' id' x' }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-09 17:29:54 +00:00
|
|
|
let rec list_not_membero xs x = ocanren {
|
|
|
|
|
xs == [] |
|
|
|
|
|
{ fresh x', xs' in
|
|
|
|
|
xs == x' :: xs' &
|
|
|
|
|
x' =/= x &
|
|
|
|
|
list_not_membero xs' x }
|
|
|
|
|
}
|
2026-05-05 14:35:35 +00:00
|
|
|
|
2026-05-08 12:06:53 +00:00
|
|
|
let rec list_foldro f acc xs acc' = ocanren {
|
2026-05-05 14:35:35 +00:00
|
|
|
xs == [] & acc' == acc |
|
|
|
|
|
{ fresh x', xs', acc_upd in
|
|
|
|
|
xs == x' :: xs' &
|
2026-05-08 12:06:53 +00:00
|
|
|
list_foldro f acc xs' acc_upd &
|
2026-05-05 14:35:35 +00:00
|
|
|
f acc_upd x' acc' }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-08 12:06:53 +00:00
|
|
|
let rec list_foldlo f acc xs acc' = ocanren {
|
2026-05-05 14:35:35 +00:00
|
|
|
xs == [] & acc' == acc |
|
|
|
|
|
{ fresh x', xs', acc_upd in
|
|
|
|
|
xs == x' :: xs' &
|
|
|
|
|
f acc x' acc_upd &
|
2026-05-08 12:06:53 +00:00
|
|
|
list_foldlo f acc_upd xs' acc' }
|
2026-05-05 14:35:35 +00:00
|
|
|
(* TODO: inf search on swap, investigate *)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-05-08 12:06:53 +00:00
|
|
|
let rec list_foldl2o f acc xs ys acc' = ocanren {
|
2026-05-05 14:35:35 +00:00
|
|
|
xs == [] & ys == [] & acc' == acc |
|
|
|
|
|
{ fresh x', xs', y', ys', acc_upd in
|
|
|
|
|
xs == x' :: xs' &
|
|
|
|
|
ys == y' :: ys' &
|
|
|
|
|
f acc x' y' acc_upd &
|
2026-05-08 12:06:53 +00:00
|
|
|
list_foldl2o f acc_upd xs' ys' acc' }
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-08 12:06:53 +00:00
|
|
|
let rec list_foldr2o f acc xs ys acc' = ocanren {
|
2026-05-05 14:35:35 +00:00
|
|
|
xs == [] & ys == [] & acc' == acc |
|
|
|
|
|
{ fresh x', xs', y', ys', acc_upd in
|
|
|
|
|
xs == x' :: xs' &
|
|
|
|
|
ys == y' :: ys' &
|
2026-05-08 12:06:53 +00:00
|
|
|
list_foldr2o f acc xs' ys' acc_upd &
|
2026-05-05 14:35:35 +00:00
|
|
|
f acc_upd x' y' acc' }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-08 12:06:53 +00:00
|
|
|
let rec list_foldl3o f acc xs ys zs acc' = ocanren {
|
2026-05-05 14:35:35 +00:00
|
|
|
xs == [] & ys == [] & zs == [] & acc' == acc |
|
|
|
|
|
{ fresh x', xs', y', ys', z', zs', acc_upd in
|
|
|
|
|
xs == x' :: xs' &
|
|
|
|
|
ys == y' :: ys' &
|
|
|
|
|
zs == z' :: zs' &
|
|
|
|
|
f acc x' y' z' acc_upd &
|
2026-05-08 12:06:53 +00:00
|
|
|
list_foldl3o f acc_upd xs' ys' zs' acc' }
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-08 12:06:53 +00:00
|
|
|
let rec list_foldr3o f acc xs ys zs acc' = ocanren {
|
2026-05-05 14:35:35 +00:00
|
|
|
xs == [] & ys == [] & zs == [] & acc' == acc |
|
|
|
|
|
{ fresh x', xs', y', ys', z', zs', acc_upd in
|
|
|
|
|
xs == x' :: xs' &
|
|
|
|
|
ys == y' :: ys' &
|
|
|
|
|
zs == z' :: zs' &
|
2026-05-08 12:06:53 +00:00
|
|
|
list_foldr3o f acc xs' ys' zs' acc_upd &
|
2026-05-05 14:35:35 +00:00
|
|
|
f acc_upd x' y' z' acc' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let rec list_zip_witho f xs ys zs = ocanren {
|
|
|
|
|
{ fresh x, xs', y, ys', z, zs' in
|
|
|
|
|
xs == x :: xs' &
|
|
|
|
|
ys == y :: ys' &
|
|
|
|
|
zs == z :: zs' &
|
|
|
|
|
f x y z &
|
|
|
|
|
list_zip_witho f xs' ys' zs' } |
|
|
|
|
|
{ fresh x, xs' in
|
|
|
|
|
xs == x :: xs' &
|
|
|
|
|
ys == [] &
|
|
|
|
|
zs == [] } |
|
|
|
|
|
{ fresh y, ys' in
|
|
|
|
|
xs == [] &
|
|
|
|
|
ys == y :: ys' &
|
|
|
|
|
zs == [] } |
|
|
|
|
|
{ xs == [] & ys == [] & zs == [] }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-13 18:46:01 +00:00
|
|
|
(* NOTE: unrequired ? *)
|
|
|
|
|
(* let list_map2o f xs ys zs = ocanren { *)
|
|
|
|
|
(* { xs == [] & ys == [] } | *)
|
|
|
|
|
(* { fresh x', xs', y', ys', z', zs' in *)
|
|
|
|
|
(* xs == x' :: xs' & *)
|
|
|
|
|
(* ys == y' :: ys' & *)
|
|
|
|
|
(* f x' y' z' *)
|
|
|
|
|
(* mapo f xs' ys' zs' & *)
|
|
|
|
|
(* zs == z' :: zs' } *)
|
|
|
|
|
(* } *)
|
|
|
|
|
|
2026-05-09 17:29:54 +00:00
|
|
|
(* - state utils *)
|
|
|
|
|
|
|
|
|
|
let types_assoco id types tp =
|
|
|
|
|
let open TypesEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh _glob_tps, tps in
|
|
|
|
|
types == TypesEnv (_glob_tps, tps) &
|
|
|
|
|
List.assoco id tps tp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let vals_assoco id vals v =
|
|
|
|
|
let open ValsEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh _glob_vs, vs in
|
|
|
|
|
vals == ValsEnv (_glob_vs, vs) &
|
|
|
|
|
List.assoco id vs v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let types_glob_addo types x tp types' =
|
|
|
|
|
let open TypesEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh glob_tps, tps in
|
|
|
|
|
types == TypesEnv (glob_tps, tps) &
|
|
|
|
|
types' == TypesEnv ((Std.pair x tp) :: glob_tps,
|
|
|
|
|
(Std.pair x tp) :: tps)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let types_addo types x tp types' =
|
|
|
|
|
let open TypesEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh glob_tps, tps in
|
|
|
|
|
types == TypesEnv (glob_tps, tps) &
|
|
|
|
|
types' == TypesEnv (glob_tps, (Std.pair x tp) :: tps)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let vals_glob_addo vals x v vals' =
|
|
|
|
|
let open ValsEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh glob_vs, vs in
|
|
|
|
|
vals == ValsEnv (glob_vs, vs) &
|
|
|
|
|
vals' == ValsEnv ((Std.pair x v) :: glob_vs,
|
|
|
|
|
(Std.pair x v) :: vs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let vals_addo vals x v vals' =
|
|
|
|
|
let open ValsEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh glob_vs, vs in
|
|
|
|
|
vals == ValsEnv (glob_vs, vs) &
|
|
|
|
|
vals' == ValsEnv (glob_vs, (Std.pair x v) :: vs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let visited_appendo visitedl visitedr visited' =
|
|
|
|
|
let open VisitedEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh vsl, vsr, vs' in
|
|
|
|
|
visitedl == VisitedEnv vsl &
|
|
|
|
|
visitedr == VisitedEnv vsr &
|
|
|
|
|
List.appendo vsl vsr vs' &
|
|
|
|
|
visited' == VisitedEnv vs'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let visited_checko visited stmt =
|
|
|
|
|
let open VisitedEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh vs in
|
|
|
|
|
visited == VisitedEnv vs &
|
|
|
|
|
List.membero vs stmt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let not_visited_checko visited stmt =
|
|
|
|
|
let open VisitedEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh vs in
|
|
|
|
|
visited == VisitedEnv vs &
|
|
|
|
|
list_not_membero vs stmt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let visited_addo visited stmt visited' =
|
|
|
|
|
let open VisitedEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh vs in
|
|
|
|
|
visited == VisitedEnv vs &
|
|
|
|
|
visited' == VisitedEnv (stmt :: vs)
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
(* --- *)
|
|
|
|
|
|
|
|
|
|
let mem_geto mem id v =
|
|
|
|
|
let open MemEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh mem_data, mem_len, rev_id in
|
|
|
|
|
MemEnv (mem_data, mem_len) == mem &
|
|
|
|
|
Nat.addo (Nat.s rev_id) id mem_len &
|
|
|
|
|
list_ntho mem_data rev_id v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mem_addo mem v mem_with_id' =
|
|
|
|
|
let open MemEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh mem_data, mem_len, mem' in
|
|
|
|
|
MemEnv (mem_data, mem_len) == mem &
|
|
|
|
|
mem' == MemEnv (v :: mem_data, Nat.s mem_len) &
|
|
|
|
|
Std.pair mem' mem_len == mem_with_id'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mem_seto mem id v mem' =
|
|
|
|
|
let open MemEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh mem_data, mem_len, rev_id, mem_data' in
|
|
|
|
|
MemEnv (mem_data, mem_len) == mem &
|
|
|
|
|
Nat.addo (Nat.s rev_id) id mem_len &
|
|
|
|
|
list_replaceo mem_data rev_id v mem_data' &
|
|
|
|
|
MemEnv (mem_data', mem_len) == mem'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let is_trivial_vo v =
|
|
|
|
|
let open Value in
|
|
|
|
|
ocanren {
|
2026-05-13 18:46:01 +00:00
|
|
|
fresh v_m, v_r, v_w in
|
|
|
|
|
v == UnitV (v_m, v_r, v_w)
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let rec pathvaro p x =
|
|
|
|
|
let open Path in
|
|
|
|
|
ocanren {
|
|
|
|
|
p == VarP x |
|
|
|
|
|
{ fresh p' in p == DerefP p' & pathvaro p' x } |
|
|
|
|
|
{ fresh p', _id in p == AccessP (p', _id) & pathvaro p' x }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-10 17:19:00 +00:00
|
|
|
let rec pathrevo p rp rp' =
|
|
|
|
|
let open Path in
|
|
|
|
|
let open RevPath in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ fresh _x in
|
|
|
|
|
p == VarP _x &
|
|
|
|
|
rp == rp' } |
|
|
|
|
|
{ fresh p' in
|
|
|
|
|
p == DerefP p' &
|
|
|
|
|
pathrevo p' (DerefRP rp) rp' } |
|
|
|
|
|
{ fresh p', id in
|
|
|
|
|
p == AccessP (p', id) &
|
|
|
|
|
pathrevo p' (AccessRP (rp, id)) rp' }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
let rec pathtypeo types p tp =
|
|
|
|
|
let open Path in
|
|
|
|
|
let open Type in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ fresh x in
|
|
|
|
|
p == VarP x &
|
|
|
|
|
types_assoco x types tp } |
|
|
|
|
|
{ fresh p', tp', _c in
|
|
|
|
|
p == DerefP p' &
|
|
|
|
|
pathtypeo types p' tp' &
|
|
|
|
|
tp' == RefT (_c, tp) } |
|
|
|
|
|
{ fresh p', id', tp', tps in
|
|
|
|
|
p == AccessP (p', id') &
|
|
|
|
|
pathtypeo types p' tp' &
|
|
|
|
|
tp' == TupleT tps &
|
|
|
|
|
list_ntho tps id' tp }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let rec pathvalo mem vals p v =
|
|
|
|
|
let open Path in
|
|
|
|
|
let open Value in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ fresh x, id in
|
|
|
|
|
p == VarP x &
|
|
|
|
|
vals_assoco x vals id &
|
|
|
|
|
mem_geto mem id v } |
|
|
|
|
|
{ fresh p', v', id in
|
|
|
|
|
p == DerefP p' &
|
|
|
|
|
pathvalo mem vals p' v' &
|
|
|
|
|
v' == RefV id &
|
|
|
|
|
mem_geto mem id v } |
|
|
|
|
|
{ fresh p', id, v', vs in
|
|
|
|
|
p == AccessP (p', id) &
|
|
|
|
|
pathvalo mem vals p' v' &
|
|
|
|
|
v' == TupleV vs &
|
|
|
|
|
list_ntho vs id v }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* --- eval rules --- *)
|
|
|
|
|
|
|
|
|
|
(* - value construction *)
|
|
|
|
|
|
|
|
|
|
let rec valcopy_foldero mem_with_vs v tp mem_with_vs' =
|
|
|
|
|
ocanren {
|
2026-05-12 17:06:51 +00:00
|
|
|
fresh mem, vs, mem', v', vs' in
|
2026-05-05 14:35:35 +00:00
|
|
|
Std.pair mem vs == mem_with_vs &
|
2026-05-12 17:06:51 +00:00
|
|
|
valcopyo mem v tp (Std.pair mem' v') &
|
2026-05-05 14:35:35 +00:00
|
|
|
vs' == v' :: vs &
|
2026-05-12 17:06:51 +00:00
|
|
|
mem_with_vs' == Std.pair mem' vs'
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
and valcopyo mem v tp mem_with_id' =
|
|
|
|
|
let open Type in
|
|
|
|
|
let open Value in
|
|
|
|
|
let open ReadCap in
|
|
|
|
|
let open CopyCap in
|
2026-05-13 18:46:01 +00:00
|
|
|
let open MemVal in
|
|
|
|
|
let open ReadVal in
|
|
|
|
|
let open WriteVal in
|
2026-05-05 14:35:35 +00:00
|
|
|
ocanren {
|
|
|
|
|
{ fresh r, w in
|
|
|
|
|
is_trivial_vo v &
|
|
|
|
|
tp == UnitT (r, w) &
|
2026-05-13 18:46:01 +00:00
|
|
|
{ { fresh v_m, _v_r, _v_w in
|
|
|
|
|
r == Rd &
|
|
|
|
|
v == UnitV (v_m, _v_r, _v_w) &
|
|
|
|
|
mem_with_id' == Std.pair mem (UnitV (v_m, ZeroRV, ZeroWV)) } |
|
|
|
|
|
{ r == NRd &
|
|
|
|
|
mem_with_id' == Std.pair mem (UnitV (BotMV, ZeroRV, ZeroWV)) } } } |
|
2026-05-05 14:35:35 +00:00
|
|
|
{ fresh stmts, ts in
|
|
|
|
|
v == FunV stmts &
|
|
|
|
|
tp == FunT ts &
|
|
|
|
|
mem_with_id' == Std.pair mem v } |
|
|
|
|
|
{ fresh c, tp', id in
|
|
|
|
|
v == RefV id &
|
|
|
|
|
tp == RefT (c, tp') &
|
|
|
|
|
{ { c == Rf & mem_with_id' == Std.pair mem v } |
|
2026-05-08 14:50:36 +00:00
|
|
|
{ fresh v', mem_cp, v_cp, mem_add, id_add in
|
2026-05-05 14:35:35 +00:00
|
|
|
c == Cp &
|
2026-05-08 14:50:36 +00:00
|
|
|
mem_geto mem id v' &
|
|
|
|
|
valcopyo mem v' tp' (Std.pair mem_cp v_cp) &
|
|
|
|
|
mem_addo mem_cp v_cp (Std.pair mem_add id_add) &
|
2026-05-05 14:35:35 +00:00
|
|
|
mem_with_id' == (mem_add, RefV id_add) } } } |
|
2026-05-12 17:06:51 +00:00
|
|
|
{ fresh vs, tps, mem', vs' in
|
2026-05-05 14:35:35 +00:00
|
|
|
v == TupleV vs &
|
|
|
|
|
tp == TupleT tps &
|
2026-05-12 17:06:51 +00:00
|
|
|
list_foldr2o valcopy_foldero (Std.pair mem []) vs tps (Std.pair mem' vs') &
|
|
|
|
|
mem_with_id' == Std.pair mem' (TupleV vs') }
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-13 18:46:01 +00:00
|
|
|
(* - action rules *)
|
|
|
|
|
|
|
|
|
|
let memvmodo a v_m v_m' =
|
|
|
|
|
let open MemVal in
|
|
|
|
|
let open Action in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ a == ReadA & v_m == ZeroMV & v_m' == ZeroMV } |
|
|
|
|
|
{ a == AlwaysWriteA & v_m' == ZeroMV } |
|
|
|
|
|
{ a == MayWriteA & v_m == ZeroMV & v_m' == ZeroMV } |
|
|
|
|
|
{ a == MayWriteA & v_m =/= ZeroMV & v_m' == SmthMV }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let readvmodo a v_r v_r' =
|
|
|
|
|
let open ReadVal in
|
|
|
|
|
let open Action in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ v_r == TopRV & v_r' == TopRV } |
|
|
|
|
|
{ v_r == OneRV & v_r' == OneRV } |
|
|
|
|
|
{ a == ReadA & v_r == ZeroRV & v_r' == OneRV } |
|
|
|
|
|
{ a == AlwaysWriteA & v_r == ZeroRV & v_r' == TopRV } |
|
|
|
|
|
{ a == MayWriteA & v_r == ZeroRV & v_r' == ZeroRV }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let writevmodo a v_w v_w' =
|
|
|
|
|
let open WriteVal in
|
|
|
|
|
let open Action in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ a == ReadA & v_w' == v_w } |
|
|
|
|
|
{ a == AlwaysWriteA & v_w' == OneWV } |
|
|
|
|
|
{ a == MayWriteA & v_w == OneWV & v_w' == OneWV } |
|
|
|
|
|
{ a == MayWriteA & v_w =/= OneWV & v_w' == v_w }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
(* - value update *)
|
|
|
|
|
|
2026-05-10 17:19:00 +00:00
|
|
|
(* NOTE: reversed path used *)
|
2026-05-13 18:46:01 +00:00
|
|
|
let rec valchangeo mem v rp b mem_with_v' =
|
2026-05-10 17:19:00 +00:00
|
|
|
let open RevPath in
|
2026-05-05 14:35:35 +00:00
|
|
|
let open Value in
|
|
|
|
|
ocanren {
|
2026-05-10 17:19:00 +00:00
|
|
|
{ rp == VarRP &
|
2026-05-05 14:35:35 +00:00
|
|
|
mem_with_v' == Std.pair mem b } |
|
2026-05-10 17:19:00 +00:00
|
|
|
{ fresh rp', id, v', mem_upd, v_upd, mem_with_v_upd, mem_st in
|
|
|
|
|
rp == DerefRP rp' &
|
2026-05-05 14:35:35 +00:00
|
|
|
v == RefV id &
|
|
|
|
|
mem_geto mem id v' &
|
2026-05-13 18:46:01 +00:00
|
|
|
valchangeo mem v' rp' b mem_with_v_upd &
|
2026-05-05 14:35:35 +00:00
|
|
|
Std.pair mem_upd v_upd == mem_with_v_upd &
|
|
|
|
|
mem_seto mem_upd id v_upd mem_st &
|
|
|
|
|
mem_with_v' == Std.pair mem_st (RefV id) } |
|
2026-05-10 17:19:00 +00:00
|
|
|
{ fresh rp', id, vs', v', mem_upd, v_upd, mem_with_v_upd, vs_upd in
|
|
|
|
|
rp == AccessRP (rp', id) &
|
2026-05-05 14:35:35 +00:00
|
|
|
v == TupleV vs' &
|
|
|
|
|
list_ntho vs' id v' &
|
2026-05-13 18:46:01 +00:00
|
|
|
valchangeo mem v' rp' b mem_with_v_upd &
|
|
|
|
|
Std.pair mem_upd v_upd == mem_with_v_upd &
|
|
|
|
|
list_replaceo vs' id v_upd vs_upd &
|
|
|
|
|
mem_with_v' == Std.pair mem_upd (TupleV vs_upd) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* NOTE: reversed path used *)
|
|
|
|
|
let rec valupdo mem v rp a mem_with_v' =
|
|
|
|
|
let open RevPath in
|
|
|
|
|
let open Value in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ fresh v_m, v_r, v_w,
|
|
|
|
|
v_m', v_r', v_w',
|
|
|
|
|
v' in
|
|
|
|
|
rp == VarRP &
|
|
|
|
|
v == UnitV (v_m, v_r, v_w) &
|
|
|
|
|
memvmodo a v_m v_m' &
|
|
|
|
|
readvmodo a v_r v_r' &
|
|
|
|
|
writevmodo a v_w v_w' &
|
|
|
|
|
v' == UnitV (v_m', v_r', v_w') &
|
|
|
|
|
mem_with_v' == Std.pair mem v' } |
|
|
|
|
|
{ fresh rp', id, v', mem_upd, v_upd, mem_with_v_upd, mem_st in
|
|
|
|
|
rp == DerefRP rp' &
|
|
|
|
|
v == RefV id &
|
|
|
|
|
mem_geto mem id v' &
|
|
|
|
|
valupdo mem v' rp' a mem_with_v_upd &
|
|
|
|
|
Std.pair mem_upd v_upd == mem_with_v_upd &
|
|
|
|
|
mem_seto mem_upd id v_upd mem_st &
|
|
|
|
|
mem_with_v' == Std.pair mem_st (RefV id) } |
|
|
|
|
|
{ fresh rp', id, vs', v', mem_upd, v_upd, mem_with_v_upd, vs_upd in
|
|
|
|
|
rp == AccessRP (rp', id) &
|
|
|
|
|
v == TupleV vs' &
|
|
|
|
|
list_ntho vs' id v' &
|
|
|
|
|
valupdo mem v' rp' a mem_with_v_upd &
|
2026-05-05 14:35:35 +00:00
|
|
|
Std.pair mem_upd v_upd == mem_with_v_upd &
|
|
|
|
|
list_replaceo vs' id v_upd vs_upd &
|
|
|
|
|
mem_with_v' == Std.pair mem_upd (TupleV vs_upd) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* - value combination *)
|
|
|
|
|
|
2026-05-13 18:46:01 +00:00
|
|
|
let memvalcombo u v u' =
|
|
|
|
|
let open MemVal in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ u == ZeroMV & v == ZeroMV & u' == ZeroMV } |
|
|
|
|
|
{ u == BotMV & v == BotMV & u' == BotMV } |
|
|
|
|
|
{ u =/= ZeroMV & v =/= ZeroMV &
|
|
|
|
|
u =/= BotMV & v =/= BotMV &
|
|
|
|
|
u' == SmthMV }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let readvalcombo u v u' =
|
|
|
|
|
let open ReadVal in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ u == TopRV & v == TopRV & u' == TopRV } |
|
|
|
|
|
{ u == ZeroRV & v == ZeroRV & u' == ZeroRV } |
|
|
|
|
|
{ u == TopRV & v == ZeroRV & u' == ZeroRV } |
|
|
|
|
|
{ u == ZeroRV & v == TopRV & u' == ZeroRV } |
|
|
|
|
|
{ u =/= TopRV & v =/= TopRV &
|
|
|
|
|
u =/= ZeroRV & v =/= ZeroRV &
|
|
|
|
|
u' == OneRV }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let writevalcombo u v u' =
|
|
|
|
|
let open WriteVal in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ u == OneWV & v == OneWV & u' == OneWV } |
|
|
|
|
|
{ u == ZeroWV & v == ZeroWV & u' == ZeroWV } |
|
|
|
|
|
{ u =/= ZeroWV & v =/= ZeroWV &
|
|
|
|
|
u =/= OneWV & v =/= OneWV &
|
|
|
|
|
u' == SmthWV }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
let rec valcombo u v u' =
|
|
|
|
|
let open Value in
|
|
|
|
|
ocanren {
|
2026-05-13 18:46:01 +00:00
|
|
|
{ fresh u_m, u_r, u_w,
|
|
|
|
|
v_m, v_r, v_w,
|
|
|
|
|
u_m', u_r', u_w' in
|
|
|
|
|
u == UnitV (u_m, u_r, u_w) &
|
|
|
|
|
v == UnitV (v_m, v_r, v_w) &
|
|
|
|
|
memvalcombo u_m v_m u_m' &
|
|
|
|
|
readvalcombo u_r v_r u_r' &
|
|
|
|
|
writevalcombo u_w v_w u_w' &
|
|
|
|
|
u' == UnitV (u_m', u_r', u_w') } |
|
2026-05-05 14:35:35 +00:00
|
|
|
{ fresh ustmts, vstmts, ustmts' in
|
|
|
|
|
u == FunV ustmts &
|
|
|
|
|
v == FunV vstmts &
|
|
|
|
|
(* TODO: swap stmts order o efficiency ? *)
|
|
|
|
|
List.appendo ustmts vstmts ustmts' &
|
|
|
|
|
u' == FunV ustmts' } |
|
|
|
|
|
{ fresh a, b in
|
|
|
|
|
u == RefV a &
|
|
|
|
|
v == RefV b &
|
|
|
|
|
a == b } |
|
|
|
|
|
{ fresh us, vs, us' in
|
|
|
|
|
u == TupleV us &
|
|
|
|
|
v == TupleV vs &
|
|
|
|
|
list_zip_witho valcombo us vs us' &
|
|
|
|
|
u' == TupleV us' }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 18:14:58 +00:00
|
|
|
let memcombo m n m' =
|
|
|
|
|
let open MemEnv in
|
|
|
|
|
ocanren {
|
2026-05-05 14:35:35 +00:00
|
|
|
fresh mm, ml, nm, nl, mm' in
|
2026-05-05 18:14:58 +00:00
|
|
|
MemEnv (mm, ml) == m &
|
|
|
|
|
MemEnv (nm, nl) == n &
|
2026-05-05 14:35:35 +00:00
|
|
|
list_zip_witho valcombo mm nm mm' &
|
2026-05-05 18:14:58 +00:00
|
|
|
m' == MemEnv (mm', ml)
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* - expression evaluation *)
|
|
|
|
|
|
2026-05-12 17:06:51 +00:00
|
|
|
(* let rec exprval_foldero mem vals vs e vs' = ocanren { *)
|
|
|
|
|
(* fresh v' in *)
|
|
|
|
|
(* exprvalo mem vals e v' & *)
|
|
|
|
|
(* vs' == v' :: vs *)
|
|
|
|
|
(* } *)
|
|
|
|
|
(* and *)
|
|
|
|
|
let rec
|
|
|
|
|
exprvalo mem vals e v' =
|
2026-05-05 14:35:35 +00:00
|
|
|
let open Expr in
|
|
|
|
|
let open Value in
|
2026-05-13 18:46:01 +00:00
|
|
|
let open MemVal in
|
|
|
|
|
let open ReadVal in
|
|
|
|
|
let open WriteVal in
|
2026-05-05 14:35:35 +00:00
|
|
|
ocanren {
|
2026-05-13 18:46:01 +00:00
|
|
|
{ e == UnitE & v' == UnitV (ZeroMV, ZeroRV, ZeroWV) } |
|
2026-05-05 14:35:35 +00:00
|
|
|
{ fresh p in
|
|
|
|
|
e == PathE p &
|
|
|
|
|
pathvalo mem vals p v' } |
|
|
|
|
|
{ fresh x, v in
|
|
|
|
|
e == RefE x &
|
|
|
|
|
vals_assoco x vals v &
|
|
|
|
|
v' == RefV v } |
|
|
|
|
|
{ fresh es, vs' in
|
|
|
|
|
e == TupleE es &
|
2026-05-12 17:06:51 +00:00
|
|
|
(* list_foldro (exprval_foldero mem vals) [] es vs' & *)
|
2026-05-05 14:35:35 +00:00
|
|
|
List.mapo (exprvalo mem vals) es vs' &
|
|
|
|
|
v' == TupleV vs' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* - expression typing *)
|
|
|
|
|
|
|
|
|
|
let rec exprtypeo types e tp' =
|
|
|
|
|
let open Expr in
|
|
|
|
|
let open Type in
|
|
|
|
|
let open ReadCap in
|
|
|
|
|
let open WriteCap in
|
|
|
|
|
let open CopyCap in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ e == UnitE & tp' == UnitT (Rd, NeverWr) } |
|
|
|
|
|
{ fresh p in
|
|
|
|
|
e == PathE p &
|
|
|
|
|
pathtypeo types p tp' } |
|
|
|
|
|
{ fresh x, tp in
|
|
|
|
|
e == RefE x &
|
|
|
|
|
types_assoco x types tp &
|
|
|
|
|
tp' == RefT (Rf, tp) } |
|
|
|
|
|
{ fresh es, tps' in
|
|
|
|
|
e == TupleE es &
|
|
|
|
|
List.mapo (exprtypeo types) es tps' &
|
|
|
|
|
tp' == TupleT tps' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* - context initialization *)
|
|
|
|
|
|
|
|
|
|
let add_declo st x d st' =
|
|
|
|
|
let open StEnv in
|
|
|
|
|
let open Decl in
|
2026-05-08 12:06:53 +00:00
|
|
|
let open Value in
|
|
|
|
|
let open Type in
|
2026-05-05 14:35:35 +00:00
|
|
|
ocanren {
|
2026-05-09 17:29:54 +00:00
|
|
|
fresh mem, types, vals, visited in
|
|
|
|
|
st == StEnv (mem, types, vals, visited) &
|
2026-05-05 14:35:35 +00:00
|
|
|
{
|
|
|
|
|
{ fresh tp, e, v,
|
2026-05-08 12:06:53 +00:00
|
|
|
mem_cp, v_cp,
|
|
|
|
|
mem_add, id_add,
|
2026-05-06 17:17:36 +00:00
|
|
|
types', vals' in
|
2026-05-05 14:35:35 +00:00
|
|
|
d == VarD (tp, e) &
|
2026-05-06 17:17:36 +00:00
|
|
|
exprvalo mem vals e v &
|
2026-05-08 12:06:53 +00:00
|
|
|
valcopyo mem v tp (Pair.pair mem_cp v_cp) &
|
2026-05-12 17:06:51 +00:00
|
|
|
(* mem_cp == mem & v_cp == v & *)
|
2026-05-08 12:06:53 +00:00
|
|
|
mem_addo mem_cp v_cp (Pair.pair mem_add id_add) &
|
2026-05-12 17:06:51 +00:00
|
|
|
(* mem_add == mem_cp & *)
|
2026-05-06 17:17:36 +00:00
|
|
|
types_glob_addo types x tp types' &
|
2026-05-12 17:06:51 +00:00
|
|
|
(* types == types' & *)
|
|
|
|
|
(* vals == vals' & *)
|
2026-05-06 17:17:36 +00:00
|
|
|
vals_glob_addo vals x id_add vals' &
|
2026-05-09 17:29:54 +00:00
|
|
|
st' == StEnv (mem_add, types', vals', visited) } |
|
2026-05-08 12:06:53 +00:00
|
|
|
{ fresh tps, s,
|
|
|
|
|
mem_add, id_add,
|
|
|
|
|
types', vals' in
|
|
|
|
|
d == FunD (tps, s) &
|
|
|
|
|
mem_addo mem (FunV [s]) (Pair.pair mem_add id_add) &
|
|
|
|
|
types_glob_addo types x (FunT tps) types' &
|
|
|
|
|
vals_glob_addo vals x id_add vals' &
|
2026-05-09 17:29:54 +00:00
|
|
|
st' == StEnv (mem_add, types', vals', visited)
|
2026-05-08 12:06:53 +00:00
|
|
|
}
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let empty_memo m =
|
|
|
|
|
let open MemEnv in
|
|
|
|
|
ocanren { m == MemEnv ([], 0) }
|
|
|
|
|
|
|
|
|
|
let empty_stateo st =
|
|
|
|
|
let open StEnv in
|
|
|
|
|
let open TypesEnv in
|
|
|
|
|
let open ValsEnv in
|
2026-05-09 17:29:54 +00:00
|
|
|
let open VisitedEnv in
|
2026-05-05 14:35:35 +00:00
|
|
|
ocanren {
|
|
|
|
|
fresh m in
|
|
|
|
|
empty_memo m &
|
2026-05-09 17:29:54 +00:00
|
|
|
st == StEnv (m, TypesEnv ([], []), ValsEnv ([], []), VisitedEnv [])
|
2026-05-05 14:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* TODO: better way ??? *)
|
2026-05-08 12:06:53 +00:00
|
|
|
let globals_min_ido x = ocanren { x == 10 }
|
2026-05-05 14:35:35 +00:00
|
|
|
|
|
|
|
|
let prog_init_foldero st_with_id d st_with_id' =
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh st, x, st' in
|
|
|
|
|
Std.pair st x == st_with_id &
|
|
|
|
|
add_declo st x d st' &
|
|
|
|
|
st_with_id' == Std.pair st' (Nat.s x)
|
2026-05-04 13:42:53 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
let prog_inito prog st' =
|
|
|
|
|
let open Prg in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh decls, s, st_init, min_id, st_with_id', _id' in
|
|
|
|
|
prog == Prg (decls, s) &
|
|
|
|
|
empty_stateo st_init &
|
|
|
|
|
globals_min_ido min_id &
|
|
|
|
|
list_foldlo prog_init_foldero (Std.pair st_init min_id) decls st_with_id' &
|
|
|
|
|
Std.pair st' _id' == st_with_id'
|
2026-05-04 13:42:53 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
(* - call values spoil *)
|
|
|
|
|
|
|
|
|
|
(* TODO: check that negation is interpreted correctly *)
|
2026-05-13 18:46:01 +00:00
|
|
|
let is_correct_tagso r w m c =
|
2026-05-05 14:35:35 +00:00
|
|
|
let open ReadCap in
|
|
|
|
|
let open WriteCap in
|
|
|
|
|
let open Mode in
|
|
|
|
|
let open CopyCap in
|
|
|
|
|
ocanren {
|
2026-05-08 12:46:53 +00:00
|
|
|
{ r == NRd | r == Rd & is_ino m } &
|
2026-05-13 18:46:01 +00:00
|
|
|
{ is_not_outo m | is_outo m & w == AlwaysWr & c == Rf }
|
2026-05-04 13:42:53 +00:00
|
|
|
}
|
2026-05-01 13:45:09 +00:00
|
|
|
|
2026-05-13 18:46:01 +00:00
|
|
|
let tryreado r v_m v_r v_w v' =
|
|
|
|
|
let open Action in
|
|
|
|
|
let open Value in
|
|
|
|
|
let open ReadCap in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ fresh v_m', v_r', v_w' in
|
|
|
|
|
r == Rd &
|
|
|
|
|
memvmodo ReadA v_m v_m' &
|
|
|
|
|
readvmodo ReadA v_r v_r' &
|
|
|
|
|
writevmodo ReadA v_w v_w' &
|
|
|
|
|
v' == UnitV (v_m', v_r', v_w') } |
|
|
|
|
|
{ r == NRd &
|
|
|
|
|
v' == UnitV (v_m, v_r, v_w)}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let tryspoilo m w v_m v_m' =
|
|
|
|
|
let open Mode in
|
|
|
|
|
let open WriteCap in
|
|
|
|
|
let open MemVal in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ is_outo m & { w == AlwaysWr | w == MayWr } & v_m' == v_m } |
|
|
|
|
|
{ is_not_outo m & w == AlwaysWr & v_m' == BotMV } |
|
|
|
|
|
{ is_not_outo m & w == MayWr & v_m' == SmthMV }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let rec valspoil_foldero m c mem_with_vs tp v mem_with_vs' = ocanren {
|
2026-05-05 16:52:43 +00:00
|
|
|
fresh mem, vs, mem', v' in
|
|
|
|
|
Std.pair mem vs == mem_with_vs &
|
2026-05-13 18:46:01 +00:00
|
|
|
valspoilo mem v tp m c (Std.pair mem' v') &
|
2026-05-05 16:52:43 +00:00
|
|
|
mem_with_vs' == Std.pair mem' (v' :: vs)
|
|
|
|
|
}
|
2026-05-13 18:46:01 +00:00
|
|
|
and valspoilo mem v tp m c mem_with_v' =
|
2026-05-05 16:52:43 +00:00
|
|
|
let open Type in
|
|
|
|
|
let open Value in
|
|
|
|
|
let open WriteCap in
|
|
|
|
|
let open CopyCap in
|
2026-05-13 18:46:01 +00:00
|
|
|
let open Action in
|
2026-05-05 16:52:43 +00:00
|
|
|
ocanren {
|
2026-05-13 18:46:01 +00:00
|
|
|
{ fresh r, w,
|
|
|
|
|
v_m, v_r, v_w,
|
|
|
|
|
v', v'' in
|
2026-05-05 16:52:43 +00:00
|
|
|
tp == UnitT (r, w) &
|
2026-05-13 18:46:01 +00:00
|
|
|
v == UnitV (v_m, v_r, v_w) &
|
|
|
|
|
is_correct_tagso r w m c &
|
|
|
|
|
tryreado r v_m v_r v_w v' &
|
2026-05-05 16:52:43 +00:00
|
|
|
{
|
2026-05-13 18:46:01 +00:00
|
|
|
{ c == Cp & w == NeverWr &
|
|
|
|
|
mem_with_v' == Std.pair mem v' } |
|
|
|
|
|
{ fresh v_m', v_r', v_w',
|
|
|
|
|
v_m'', v_r'', v_w'',
|
|
|
|
|
v_m''' in
|
|
|
|
|
v' == UnitV (v_m', v_r', v_w') &
|
|
|
|
|
{
|
|
|
|
|
{ w == AlwaysWr &
|
|
|
|
|
memvmodo AlwaysWriteA v_m' v_m'' &
|
|
|
|
|
readvmodo AlwaysWriteA v_r' v_r'' &
|
|
|
|
|
writevmodo AlwaysWriteA v_w' v_w'' } |
|
|
|
|
|
{ w == MayWr &
|
|
|
|
|
memvmodo MayWriteA v_m' v_m'' &
|
|
|
|
|
readvmodo MayWriteA v_r' v_r'' &
|
|
|
|
|
writevmodo MayWriteA v_w' v_w'' }
|
|
|
|
|
} &
|
|
|
|
|
tryspoilo m w v_m'' v_m''' &
|
|
|
|
|
v'' == UnitV (v_m''', v_r'', v_w'') &
|
|
|
|
|
mem_with_v' == Std.pair mem v'' }
|
2026-05-05 16:52:43 +00:00
|
|
|
} } |
|
2026-05-13 18:46:01 +00:00
|
|
|
{ fresh ts, _stmts in
|
2026-05-05 16:52:43 +00:00
|
|
|
tp == FunT ts &
|
|
|
|
|
v == FunV _stmts &
|
|
|
|
|
mem_with_v' == Std.pair mem v } |
|
2026-05-14 10:16:33 +00:00
|
|
|
{ fresh ctp', tp', id', v', mem_sp, v_sp, mem_set in
|
2026-05-05 16:52:43 +00:00
|
|
|
tp == RefT (ctp', tp') &
|
|
|
|
|
v == RefV id' &
|
|
|
|
|
mem_geto mem id' v' &
|
2026-05-13 18:46:01 +00:00
|
|
|
valspoilo mem v' tp' m ctp' (Std.pair mem_sp v_sp) &
|
2026-05-05 16:52:43 +00:00
|
|
|
mem_seto mem_sp id' v_sp mem_set &
|
|
|
|
|
mem_with_v' == Std.pair mem_set (RefV id') } |
|
2026-05-14 10:16:33 +00:00
|
|
|
{ fresh tps, vs, mem_sp, vs_sp in
|
2026-05-05 16:52:43 +00:00
|
|
|
tp == TupleT tps &
|
|
|
|
|
v == TupleV vs &
|
2026-05-13 18:46:01 +00:00
|
|
|
list_foldr2o (valspoil_foldero m c)
|
|
|
|
|
(Std.pair mem []) tps vs
|
2026-05-05 16:52:43 +00:00
|
|
|
(Std.pair mem_sp vs_sp) &
|
2026-05-12 17:06:51 +00:00
|
|
|
mem_with_v' == Std.pair mem_sp (TupleV vs_sp)
|
2026-05-05 16:52:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
(* full spoil *)
|
2026-05-05 16:52:43 +00:00
|
|
|
|
2026-05-05 18:14:58 +00:00
|
|
|
let argspoilpo st m tp p mem' =
|
|
|
|
|
let open StEnv in
|
|
|
|
|
let open CopyCap in
|
2026-05-10 17:19:00 +00:00
|
|
|
let open RevPath in
|
2026-05-05 18:14:58 +00:00
|
|
|
ocanren {
|
2026-05-09 17:29:54 +00:00
|
|
|
fresh mem, types, vals, visited,
|
2026-05-13 18:46:01 +00:00
|
|
|
x, id, b(* , tp' *), rp,
|
2026-05-05 18:14:58 +00:00
|
|
|
mem_sp, b_sp, v_sp, mem_upd, v_upd in
|
2026-05-09 17:29:54 +00:00
|
|
|
st == StEnv (mem, types, vals, visited) &
|
2026-05-05 18:14:58 +00:00
|
|
|
pathvaro p x &
|
|
|
|
|
vals_assoco x vals id &
|
|
|
|
|
pathvalo mem vals p b &
|
2026-05-13 18:46:01 +00:00
|
|
|
(* pathtypeo types p tp' & *)
|
2026-05-14 10:16:33 +00:00
|
|
|
valspoilo mem b tp m Cp (Std.pair mem_sp b_sp) &
|
2026-05-05 18:14:58 +00:00
|
|
|
mem_geto mem_sp id v_sp &
|
2026-05-10 17:19:00 +00:00
|
|
|
pathrevo p VarRP rp &
|
2026-05-13 18:46:01 +00:00
|
|
|
valchangeo mem_sp v_sp rp b_sp (Std.pair mem_upd v_upd) &
|
2026-05-05 18:14:58 +00:00
|
|
|
mem_seto mem_upd id v_upd mem'
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-09 17:29:54 +00:00
|
|
|
let rec argspoile_foldero types vals visited m mem tp e mem' =
|
2026-05-05 18:14:58 +00:00
|
|
|
let open StEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh st in
|
2026-05-09 17:29:54 +00:00
|
|
|
st == StEnv (mem, types, vals, visited) &
|
2026-05-05 18:14:58 +00:00
|
|
|
argspoileo st m tp e mem'
|
|
|
|
|
}
|
|
|
|
|
and argspoileo st m tp e mem' =
|
|
|
|
|
let open StEnv in
|
|
|
|
|
let open Expr in
|
|
|
|
|
let open Type in
|
|
|
|
|
let open Path in
|
|
|
|
|
ocanren {
|
2026-05-09 17:29:54 +00:00
|
|
|
fresh _r, _w, mem, types, vals, visited in
|
|
|
|
|
st == StEnv (mem, types, vals, visited) &
|
2026-05-05 18:14:58 +00:00
|
|
|
{
|
|
|
|
|
{ e == UnitE &
|
|
|
|
|
tp == UnitT (_r, _w) &
|
|
|
|
|
mem' == mem } |
|
|
|
|
|
{ fresh p in
|
|
|
|
|
e == PathE p &
|
|
|
|
|
argspoilpo st m tp p mem' } |
|
|
|
|
|
{ fresh x in
|
|
|
|
|
e == RefE x &
|
|
|
|
|
argspoilpo st m tp (VarP x) mem' } |
|
|
|
|
|
{ fresh es, tps in
|
|
|
|
|
e == TupleE es &
|
|
|
|
|
tp == TupleT tps &
|
2026-05-09 17:29:54 +00:00
|
|
|
list_foldl2o (argspoile_foldero types vals visited m) mem tps es mem'}
|
2026-05-05 18:14:58 +00:00
|
|
|
}
|
|
|
|
|
}
|
2026-05-05 14:35:35 +00:00
|
|
|
|
|
|
|
|
(* - funciton argument addition *)
|
2026-05-05 18:14:58 +00:00
|
|
|
|
|
|
|
|
let addargo st oldvals x tp e st' =
|
|
|
|
|
let open StEnv in
|
|
|
|
|
ocanren {
|
2026-05-09 17:29:54 +00:00
|
|
|
fresh mem, types, vals, visited, v,
|
2026-05-06 17:17:36 +00:00
|
|
|
mem_cp, v_cp,
|
|
|
|
|
mem_add, id_add,
|
|
|
|
|
types', vals' in
|
2026-05-09 17:29:54 +00:00
|
|
|
st == StEnv (mem, types, vals, visited) &
|
2026-05-05 18:14:58 +00:00
|
|
|
exprvalo mem oldvals e v &
|
|
|
|
|
valcopyo mem v tp (Std.pair mem_cp v_cp) &
|
|
|
|
|
mem_addo mem_cp v_cp (Std.pair mem_add id_add) &
|
2026-05-06 17:17:36 +00:00
|
|
|
types_addo types x tp types' &
|
|
|
|
|
vals_addo vals x id_add vals' &
|
2026-05-09 17:29:54 +00:00
|
|
|
st' == StEnv (mem_add, types', vals', visited)
|
2026-05-05 18:14:58 +00:00
|
|
|
}
|
2026-05-05 14:35:35 +00:00
|
|
|
|
|
|
|
|
(* - function evaluation *)
|
|
|
|
|
(* NOTE: not needed due to performed optimization in stmt_eval ? *)
|
|
|
|
|
|
2026-05-13 18:46:01 +00:00
|
|
|
let writeval_to_capo v_w w' =
|
|
|
|
|
let open WriteVal in
|
|
|
|
|
let open WriteCap in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ v_w == ZeroWV & w' == NeverWr } |
|
|
|
|
|
{ v_w == SmthWV & w' == MayWr } |
|
|
|
|
|
{ v_w == OneWV & w' == AlwaysWr }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let rec tags_checko mem v tp =
|
|
|
|
|
let open ReadVal in
|
|
|
|
|
let open ReadCap in
|
|
|
|
|
let open Type in
|
|
|
|
|
let open Value in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ fresh v_m, v_r, v_w,
|
|
|
|
|
r, w in
|
2026-05-14 10:16:33 +00:00
|
|
|
v == UnitV (v_m, v_r, v_w) &
|
2026-05-13 18:46:01 +00:00
|
|
|
tp == UnitT (r, w) &
|
|
|
|
|
{
|
2026-05-14 10:16:33 +00:00
|
|
|
{ r == Rd & v_r == OneRV } |
|
2026-05-13 18:46:01 +00:00
|
|
|
{ r == NRd & v_r == ZeroRV } |
|
|
|
|
|
{ r == NRd & v_r == TopRV }
|
|
|
|
|
} &
|
2026-05-14 10:16:33 +00:00
|
|
|
writeval_to_capo v_w w
|
2026-05-13 18:46:01 +00:00
|
|
|
} |
|
|
|
|
|
{ fresh _stmts, _ts in
|
|
|
|
|
v == FunV _stmts &
|
|
|
|
|
tp == FunT _ts } |
|
|
|
|
|
{ fresh id, _c, tp', v' in
|
|
|
|
|
v == RefV id &
|
|
|
|
|
tp == RefT (_c, tp') &
|
|
|
|
|
mem_geto mem id v' &
|
|
|
|
|
tags_checko mem v' tp' } |
|
|
|
|
|
{ fresh vs, ts in
|
|
|
|
|
List.mapo (tags_checko mem) vs ts }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
(* - statement evaluation *)
|
|
|
|
|
|
2026-05-05 18:14:58 +00:00
|
|
|
let rec stmt_addarg_foldero vals st_with_id mtp e st_with_id' = ocanren {
|
|
|
|
|
fresh st, x, m, tp, st' in
|
|
|
|
|
Std.pair st x == st_with_id &
|
|
|
|
|
Std.pair m tp == mtp &
|
|
|
|
|
addargo st vals x tp e st' &
|
|
|
|
|
st_with_id' == Std.pair st' (Nat.s x)
|
|
|
|
|
}
|
2026-05-13 18:46:01 +00:00
|
|
|
and f_tags_check_foldero mem vals x mtp x' = ocanren {
|
|
|
|
|
fresh m, tp, id', v' in
|
|
|
|
|
mtp == Std.pair m tp &
|
|
|
|
|
vals_assoco x vals id' &
|
|
|
|
|
mem_geto mem id' v' &
|
|
|
|
|
tags_checko mem v' tp &
|
|
|
|
|
x' == Nat.s x
|
|
|
|
|
}
|
2026-05-14 10:16:33 +00:00
|
|
|
and stmt_eval_func_foldero mem types vals tps visited stmt visited' =
|
2026-05-09 17:29:54 +00:00
|
|
|
let open StEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
{ fresh visited_add, st,
|
2026-05-13 18:46:01 +00:00
|
|
|
st', mem', types', vals',
|
|
|
|
|
_x' in
|
2026-05-09 17:29:54 +00:00
|
|
|
not_visited_checko visited stmt &
|
|
|
|
|
visited_addo visited stmt visited_add &
|
|
|
|
|
st == StEnv (mem, types, vals, visited_add) &
|
|
|
|
|
stmt_evalo st stmt st' &
|
2026-05-13 18:46:01 +00:00
|
|
|
st' == StEnv (mem', types', vals', visited') &
|
2026-05-14 10:16:33 +00:00
|
|
|
list_foldlo (f_tags_check_foldero mem' vals') 0 tps _x' } |
|
2026-05-09 17:29:54 +00:00
|
|
|
{ visited_checko visited stmt &
|
|
|
|
|
visited == visited' }
|
|
|
|
|
}
|
|
|
|
|
and stmt_eval_spoil_foldero types vals visited mem mtp e mem' =
|
2026-05-05 18:14:58 +00:00
|
|
|
let open StEnv in
|
|
|
|
|
ocanren {
|
|
|
|
|
fresh m, tp, st in
|
|
|
|
|
Std.pair m tp == mtp &
|
2026-05-09 17:29:54 +00:00
|
|
|
st == StEnv (mem, types, vals, visited) &
|
2026-05-05 18:14:58 +00:00
|
|
|
argspoileo st m tp e mem'
|
|
|
|
|
}
|
|
|
|
|
and stmt_evalo st s st' =
|
|
|
|
|
let open StEnv in
|
|
|
|
|
let open Stmt in
|
|
|
|
|
let open Value in
|
|
|
|
|
let open Type in
|
|
|
|
|
let open WriteCap in
|
|
|
|
|
let open TypesEnv in
|
|
|
|
|
let open ValsEnv in
|
2026-05-10 17:19:00 +00:00
|
|
|
let open RevPath in
|
2026-05-13 18:46:01 +00:00
|
|
|
let open Action in
|
2026-05-05 18:14:58 +00:00
|
|
|
ocanren {
|
2026-05-09 17:29:54 +00:00
|
|
|
fresh mem, types, vals, visited in
|
|
|
|
|
st == StEnv (mem, types, vals, visited) &
|
2026-05-05 18:14:58 +00:00
|
|
|
{
|
|
|
|
|
{ s == SkipS & st == st' } |
|
2026-05-06 17:17:36 +00:00
|
|
|
{ fresh f, es, v, tp,
|
|
|
|
|
glob_tps, _tps,
|
|
|
|
|
glob_vs, _vs,
|
2026-05-08 12:06:53 +00:00
|
|
|
types_call, vals_call,
|
|
|
|
|
fstmts, tps, st_call,
|
2026-05-09 17:29:54 +00:00
|
|
|
state_with_args,
|
|
|
|
|
mem_swa, types_swa,
|
|
|
|
|
vals_swa, visited_swa,
|
|
|
|
|
_arg_id, mem_spoiled,
|
|
|
|
|
visited' in
|
2026-05-05 18:14:58 +00:00
|
|
|
s == CallS (f, es) &
|
|
|
|
|
pathvalo mem vals f v &
|
|
|
|
|
pathtypeo types f tp &
|
2026-05-06 17:17:36 +00:00
|
|
|
types == TypesEnv (glob_tps, _tps) &
|
|
|
|
|
vals == ValsEnv (glob_vs, _vs) &
|
2026-05-08 12:06:53 +00:00
|
|
|
types_call == TypesEnv (glob_tps, glob_tps) &
|
|
|
|
|
vals_call == ValsEnv (glob_vs, glob_vs) &
|
2026-05-05 18:14:58 +00:00
|
|
|
v == FunV fstmts &
|
|
|
|
|
tp == FunT tps &
|
2026-05-09 17:29:54 +00:00
|
|
|
st_call == StEnv (mem, types_call, vals_call, visited) &
|
2026-05-05 18:14:58 +00:00
|
|
|
list_foldl2o (stmt_addarg_foldero vals)
|
2026-05-08 12:06:53 +00:00
|
|
|
(Std.pair st_call 0) tps es
|
2026-05-05 18:14:58 +00:00
|
|
|
(Std.pair state_with_args _arg_id) &
|
2026-05-09 17:29:54 +00:00
|
|
|
state_with_args == StEnv (mem_swa, types_swa, vals_swa, visited_swa) &
|
2026-05-14 10:16:33 +00:00
|
|
|
list_foldlo (stmt_eval_func_foldero mem_swa types_swa vals_swa tps) visited_swa fstmts visited' &
|
2026-05-05 18:14:58 +00:00
|
|
|
(* TODO: FIXME check left or right order *)
|
2026-05-09 17:29:54 +00:00
|
|
|
list_foldl2o (stmt_eval_spoil_foldero types vals (* NOTE: not important*) visited')
|
|
|
|
|
mem tps es mem_spoiled &
|
|
|
|
|
st' == StEnv (mem_spoiled, types, vals, visited')
|
2026-05-08 14:50:36 +00:00
|
|
|
} |
|
2026-05-10 17:19:00 +00:00
|
|
|
{ fresh p, tp, _r, w, x, id, v, rp,
|
2026-05-05 18:14:58 +00:00
|
|
|
mem_upd, v_upd, mem_set in
|
|
|
|
|
s == WriteS p &
|
|
|
|
|
pathtypeo types p tp &
|
|
|
|
|
tp == UnitT (_r, w) &
|
|
|
|
|
{ w == AlwaysWr | w == MayWr } &
|
|
|
|
|
pathvaro p x &
|
|
|
|
|
vals_assoco x vals id &
|
|
|
|
|
mem_geto mem id v &
|
2026-05-10 17:19:00 +00:00
|
|
|
pathrevo p VarRP rp &
|
2026-05-13 18:46:01 +00:00
|
|
|
valupdo mem v rp AlwaysWriteA (Std.pair mem_upd v_upd) &
|
2026-05-05 18:14:58 +00:00
|
|
|
mem_seto mem_upd id v_upd mem_set &
|
2026-05-09 17:29:54 +00:00
|
|
|
st' == StEnv (mem_set, types, vals, visited) } |
|
2026-05-13 18:46:01 +00:00
|
|
|
{ fresh p, tp, _r, _w, x, id, v, rp,
|
|
|
|
|
mem_upd, v_upd, mem_set in
|
2026-05-05 18:14:58 +00:00
|
|
|
s == ReadS p &
|
2026-05-13 18:46:01 +00:00
|
|
|
pathtypeo types p tp &
|
|
|
|
|
tp == UnitT (_r, _w) &
|
|
|
|
|
pathvaro p x &
|
|
|
|
|
vals_assoco x vals id &
|
|
|
|
|
mem_geto mem id v &
|
|
|
|
|
pathrevo p VarRP rp &
|
|
|
|
|
valupdo mem v rp ReadA (Std.pair mem_upd v_upd) &
|
|
|
|
|
mem_seto mem_upd id v_upd mem_set &
|
|
|
|
|
st' == StEnv (mem_set, types, vals, visited) } |
|
|
|
|
|
(* { fresh p in *)
|
|
|
|
|
(* s == ReadS p & *)
|
|
|
|
|
(* pathvalo mem vals p ZeroV & *)
|
|
|
|
|
(* st == st' } | *)
|
2026-05-05 18:14:58 +00:00
|
|
|
{ fresh sl, sr, stl in
|
|
|
|
|
s == SeqS (sl, sr) &
|
|
|
|
|
stmt_evalo st sl stl &
|
|
|
|
|
stmt_evalo stl sr st' } |
|
|
|
|
|
{ fresh sl, sr, stl, str,
|
2026-05-09 17:29:54 +00:00
|
|
|
meml, typesl, valsl, visitedl,
|
|
|
|
|
memr, typesr, valsr, visitedr,
|
|
|
|
|
visited', mem' in
|
2026-05-05 18:14:58 +00:00
|
|
|
s == ChoiceS (sl, sr) &
|
|
|
|
|
stmt_evalo st sl stl &
|
|
|
|
|
stmt_evalo st sr str &
|
2026-05-09 17:29:54 +00:00
|
|
|
stl == StEnv (meml, typesl, valsl, visitedl) &
|
|
|
|
|
str == StEnv (memr, typesr, valsr, visitedr) &
|
2026-05-05 18:14:58 +00:00
|
|
|
typesl == typesr &
|
|
|
|
|
valsl == valsr &
|
|
|
|
|
memcombo meml memr mem' &
|
2026-05-09 17:29:54 +00:00
|
|
|
visited_appendo visitedr visitedl visited' &
|
|
|
|
|
st' == StEnv (mem', typesl, valsl, visited') }
|
2026-05-05 18:14:58 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 14:35:35 +00:00
|
|
|
(* --- program execution --- *)
|
|
|
|
|
|
2026-05-05 18:14:58 +00:00
|
|
|
let prog_evalo prog st' =
|
|
|
|
|
let open Prg in
|
|
|
|
|
ocanren {
|
2026-05-06 16:57:14 +00:00
|
|
|
fresh decls, s, init_st in
|
2026-05-05 18:14:58 +00:00
|
|
|
prog == Prg (decls, s) &
|
|
|
|
|
prog_inito prog init_st &
|
|
|
|
|
stmt_evalo init_st s st'
|
|
|
|
|
}
|
2026-03-29 15:32:35 +00:00
|
|
|
end
|