| 283 |
(any,any) |
(any,any) |
| 284 |
l |
l |
| 285 |
|
|
|
|
|
|
let cup_product l = |
|
|
List.fold_left |
|
|
(fun (d1,d2) (t1,t2) -> (cup_t d1 t1, cup_t d2 t2)) |
|
|
(empty,empty) |
|
|
l |
|
|
|
|
| 286 |
let rec exists max f = |
let rec exists max f = |
| 287 |
(max > 0) && (f (max - 1) || exists (max - 1) f) |
(max > 0) && (f (max - 1) || exists (max - 1) f) |
| 288 |
|
|
| 289 |
|
let trivially_empty d = equal_descr d empty |
| 290 |
|
|
| 291 |
module Assumptions = Set.Make(struct type t = descr let compare = compare end) |
exception NotEmpty |
| 292 |
|
|
| 293 |
let memo = ref Assumptions.empty |
type slot = { mutable status : status; |
| 294 |
let cache_false = DescrHash.create 33000 |
mutable notify : notify; |
| 295 |
|
mutable active : bool } |
| 296 |
|
and status = Empty | NEmpty | Maybe |
| 297 |
|
and notify = Nothing | Do of slot * (slot -> unit) * notify |
| 298 |
|
|
| 299 |
|
let memo = DescrHash.create 33000 |
| 300 |
|
|
| 301 |
|
let marks = ref [] |
| 302 |
|
let slot_empty = { status = Empty; active = false; notify = Nothing } |
| 303 |
|
let slot_not_empty = { status = NEmpty; active = false; notify = Nothing } |
| 304 |
|
|
| 305 |
|
let rec notify = function |
| 306 |
|
| Nothing -> () |
| 307 |
|
| Do (n,f,rem) -> |
| 308 |
|
if n.status = Maybe then (try f n with NotEmpty -> ()); |
| 309 |
|
notify rem |
| 310 |
|
|
| 311 |
|
let rec iter_s s f = function |
| 312 |
|
| [] -> () |
| 313 |
|
| arg::rem -> f arg s; iter_s s f rem |
| 314 |
|
|
| 315 |
|
|
| 316 |
|
let set s = |
| 317 |
|
s.status <- NEmpty; |
| 318 |
|
notify s.notify; |
| 319 |
|
raise NotEmpty |
| 320 |
|
|
| 321 |
|
let rec big_conj f l n = |
| 322 |
|
match l with |
| 323 |
|
| [] -> set n |
| 324 |
|
| [arg] -> f arg n |
| 325 |
|
| arg::rem -> |
| 326 |
|
let s = { status = Maybe; active = false; notify = Do (n,(big_conj f rem), Nothing) } in |
| 327 |
|
try |
| 328 |
|
f arg s; |
| 329 |
|
if s.active then n.active <- true |
| 330 |
|
with NotEmpty -> if n.status = NEmpty then raise NotEmpty |
| 331 |
|
|
| 332 |
|
let rec guard a f n = |
| 333 |
|
let s = slot a in |
| 334 |
|
match s.status with |
| 335 |
|
| Empty -> () |
| 336 |
|
| Maybe -> n.active <- true; s.notify <- Do (n,f,s.notify) |
| 337 |
|
| NEmpty -> f n |
| 338 |
|
|
| 339 |
|
and slot d = |
| 340 |
|
if not ((Intervals.is_empty d.ints) && |
| 341 |
|
(Atoms.is_empty d.atoms) && |
| 342 |
|
(Chars.is_empty d.chars)) then slot_not_empty |
| 343 |
|
else try DescrHash.find memo d |
| 344 |
|
with Not_found -> |
| 345 |
|
let s = { status = Maybe; active = false; notify = Nothing } in |
| 346 |
|
DescrHash.add memo d s; |
| 347 |
|
(try |
| 348 |
|
iter_s s check_times d.times; |
| 349 |
|
iter_s s check_times d.xml; |
| 350 |
|
iter_s s check_arrow d.arrow; |
| 351 |
|
iter_s s check_record (get_record d.record); |
| 352 |
|
if s.active then marks := s :: !marks else s.status <- Empty; |
| 353 |
|
with |
| 354 |
|
NotEmpty -> ()); |
| 355 |
|
s |
| 356 |
|
|
| 357 |
exception NotEmpty |
and check_times (left,right) s = |
| 358 |
|
let rec aux accu1 accu2 right s = match right with |
| 359 |
|
| (t1,t2)::right -> |
| 360 |
|
if trivially_empty (cap_t accu1 t1) || |
| 361 |
|
trivially_empty (cap_t accu2 t2) then |
| 362 |
|
aux accu1 accu2 right s |
| 363 |
|
else |
| 364 |
|
let accu1' = diff_t accu1 t1 in guard accu1' (aux accu1' accu2 right) s; |
| 365 |
|
let accu2' = diff_t accu2 t2 in guard accu2' (aux accu1 accu2' right) s |
| 366 |
|
| [] -> set s |
| 367 |
|
in |
| 368 |
|
let (accu1,accu2) = cap_product left in |
| 369 |
|
guard accu1 (guard accu2 (aux accu1 accu2 right)) s |
| 370 |
|
|
| 371 |
|
and check_arrow (left,right) s = |
| 372 |
|
let single_right (s1,s2) s = |
| 373 |
|
let rec aux accu1 accu2 left s = match left with |
| 374 |
|
| (t1,t2)::left -> |
| 375 |
|
let accu1' = diff_t accu1 t1 in guard accu1' (aux accu1' accu2 left) s; |
| 376 |
|
let accu2' = cap_t accu2 t2 in guard accu2' (aux accu1 accu2' left) s |
| 377 |
|
| [] -> set s |
| 378 |
|
in |
| 379 |
|
let accu1 = descr s1 in |
| 380 |
|
guard accu1 (aux accu1 (neg (descr s2)) left) s |
| 381 |
|
in |
| 382 |
|
big_conj single_right right s |
| 383 |
|
|
| 384 |
|
and check_record (labels,(oleft,(left_opt,left)),rights) s = |
| 385 |
|
let rec aux rights s = match rights with |
| 386 |
|
| [] -> set s |
| 387 |
|
| (oright,(right_opt,right))::rights -> |
| 388 |
|
let next = |
| 389 |
|
(oleft && (not oright)) || |
| 390 |
|
exists (Array.length left) |
| 391 |
|
(fun i -> |
| 392 |
|
(not (left_opt.(i) && right_opt.(i))) && |
| 393 |
|
(trivially_empty (cap left.(i) right.(i)))) |
| 394 |
|
in |
| 395 |
|
if next then aux rights s |
| 396 |
|
else |
| 397 |
|
for i = 0 to Array.length left - 1 do |
| 398 |
|
let back = left.(i) in |
| 399 |
|
let oback = left_opt.(i) in |
| 400 |
|
let odi = oback && (not right_opt.(i)) in |
| 401 |
|
let di = diff back right.(i) in |
| 402 |
|
if odi then ( |
| 403 |
|
left.(i) <- diff back right.(i); |
| 404 |
|
left_opt.(i) <- odi; |
| 405 |
|
aux rights s; |
| 406 |
|
left.(i) <- back; |
| 407 |
|
left_opt.(i) <- oback; |
| 408 |
|
) else |
| 409 |
|
guard di (fun s -> |
| 410 |
|
left.(i) <- diff back right.(i); |
| 411 |
|
left_opt.(i) <- odi; |
| 412 |
|
aux rights s; |
| 413 |
|
left.(i) <- back; |
| 414 |
|
left_opt.(i) <- oback; |
| 415 |
|
) s |
| 416 |
|
done |
| 417 |
|
in |
| 418 |
|
let rec start i s = |
| 419 |
|
if (i < 0) then aux rights s |
| 420 |
|
else |
| 421 |
|
if left_opt.(i) then start (i - 1) s |
| 422 |
|
else guard left.(i) (start (i - 1)) s |
| 423 |
|
in |
| 424 |
|
start (Array.length left - 1) s |
| 425 |
|
|
| 426 |
|
|
| 427 |
|
let is_empty d = |
| 428 |
|
let s = slot d in |
| 429 |
|
List.iter |
| 430 |
|
(fun s' -> if s'.status = Maybe then s'.status <- Empty; s'.notify <- Nothing) |
| 431 |
|
!marks; |
| 432 |
|
marks := []; |
| 433 |
|
s.status = Empty |
| 434 |
|
|
| 435 |
let trivially_empty d = equal_descr d empty |
|
| 436 |
(* Remove generic equality ... *) |
module Assumptions = Set.Make(struct type t = descr let compare = compare end) |
| 437 |
|
let memo = ref Assumptions.empty |
| 438 |
|
let cache_false = DescrHash.create 33000 |
| 439 |
|
|
| 440 |
let rec empty_rec d = |
let rec empty_rec d = |
| 441 |
if DescrHash.mem cache_false d then false |
if not (Intervals.is_empty d.ints) then false |
|
else if Assumptions.mem d !memo then true |
|
|
else if not (Intervals.is_empty d.ints) then false |
|
| 442 |
else if not (Atoms.is_empty d.atoms) then false |
else if not (Atoms.is_empty d.atoms) then false |
| 443 |
else if not (Chars.is_empty d.chars) then false |
else if not (Chars.is_empty d.chars) then false |
| 444 |
|
else if DescrHash.mem cache_false d then false |
| 445 |
|
else if Assumptions.mem d !memo then true |
| 446 |
else ( |
else ( |
| 447 |
let backup = !memo in |
let backup = !memo in |
| 448 |
memo := Assumptions.add d backup; |
memo := Assumptions.add d backup; |
| 488 |
let rec aux accu1 accu2 = function |
let rec aux accu1 accu2 = function |
| 489 |
| (t1,t2)::left -> |
| (t1,t2)::left -> |
| 490 |
let accu1' = diff_t accu1 t1 in |
let accu1' = diff_t accu1 t1 in |
| 491 |
if not (empty_rec accu1') then aux accu1 accu2 left; |
if not (empty_rec accu1') then aux accu1' accu2 left; |
| 492 |
let accu2' = cap_t accu2 t2 in |
let accu2' = cap_t accu2 t2 in |
| 493 |
if not (empty_rec accu2') then aux accu1 accu2 left |
if not (empty_rec accu2') then aux accu1 accu2' left |
| 494 |
| [] -> raise NotEmpty |
| [] -> raise NotEmpty |
| 495 |
in |
in |
| 496 |
let accu1 = descr s1 in |
let accu1 = descr s1 in |
| 535 |
and empty_rec_record c = |
and empty_rec_record c = |
| 536 |
List.for_all empty_rec_record_aux (get_record c) |
List.for_all empty_rec_record_aux (get_record c) |
| 537 |
|
|
| 538 |
let is_empty d = |
(*let is_empty d = |
| 539 |
empty_rec d |
empty_rec d |
| 540 |
|
*) |
| 541 |
|
|
| 542 |
let non_empty d = |
let non_empty d = |
| 543 |
not (is_empty d) |
not (is_empty d) |