src/Tools/Metis/src/LiteralNet.sml
author blanchet
Mon, 13 Sep 2010 21:09:43 +0200
changeset 39348 6f9c9899f99f
child 39349 2d0a4361c3ef
permissions -rw-r--r--
new version of the Metis files
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     1
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     2
(* MATCHING AND UNIFICATION FOR SETS OF FIRST ORDER LOGIC LITERALS           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     3
(* Copyright (c) 2001-2006 Joe Hurd, distributed under the GNU GPL version 2 *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     4
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     5
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     6
structure LiteralNet :> LiteralNet =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     7
struct
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     8
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     9
open Useful;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    10
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    11
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    12
(* A type of literal sets that can be efficiently matched and unified.       *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    13
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    14
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    15
type parameters = AtomNet.parameters;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    16
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    17
type 'a literalNet =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    18
    {positive : 'a AtomNet.atomNet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    19
     negative : 'a AtomNet.atomNet};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    20
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    21
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    22
(* Basic operations.                                                         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    23
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    24
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    25
fun new parm = {positive = AtomNet.new parm, negative = AtomNet.new parm};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    26
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    27
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    28
  fun pos ({positive,...} : 'a literalNet) = AtomNet.size positive;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    29
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    30
  fun neg ({negative,...} : 'a literalNet) = AtomNet.size negative;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    31
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    32
  fun size net = pos net + neg net;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    33
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    34
  fun profile net = {positive = pos net, negative = neg net};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    35
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    36
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    37
fun insert {positive,negative} ((true,atm),a) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    38
    {positive = AtomNet.insert positive (atm,a), negative = negative}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    39
  | insert {positive,negative} ((false,atm),a) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    40
    {positive = positive, negative = AtomNet.insert negative (atm,a)};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    41
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    42
fun fromList parm l = foldl (fn (lit_a,n) => insert n lit_a) (new parm) l;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    43
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    44
fun filter pred {positive,negative} =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    45
    {positive = AtomNet.filter pred positive,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    46
     negative = AtomNet.filter pred negative};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    47
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    48
fun toString net = "LiteralNet[" ^ Int.toString (size net) ^ "]";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    49
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    50
fun pp ppA =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    51
    Print.ppMap
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    52
      (fn {positive,negative} => (positive,negative))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    53
      (Print.ppOp2 " + NEGATIVE" (AtomNet.pp ppA) (AtomNet.pp ppA));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    54
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    55
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    56
(* Matching and unification queries.                                         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    57
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    58
(* These function return OVER-APPROXIMATIONS!                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    59
(* Filter afterwards to get the precise set of satisfying values.            *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    60
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    61
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    62
fun match ({positive,...} : 'a literalNet) (true,atm) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    63
    AtomNet.match positive atm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    64
  | match {negative,...} (false,atm) = AtomNet.match negative atm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    65
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    66
fun matched ({positive,...} : 'a literalNet) (true,atm) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    67
    AtomNet.matched positive atm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    68
  | matched {negative,...} (false,atm) = AtomNet.matched negative atm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    69
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    70
fun unify ({positive,...} : 'a literalNet) (true,atm) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    71
    AtomNet.unify positive atm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    72
  | unify {negative,...} (false,atm) = AtomNet.unify negative atm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    73
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    74
end