src/HOL/Tools/Quickcheck/PNF_Narrowing_Engine.hs
author bulwahn
Mon, 18 Jul 2011 10:34:21 +0200
changeset 43875 485d2ad43528
parent 43313 d3c34987863b
child 44751 f523923d8182
permissions -rw-r--r--
adding random, exhaustive and SML quickcheck as testers
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43313
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     1
{-
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     2
A narrowing-based Evaluator for Formulas in Prefix Normal Form based on the compilation technique of LazySmallCheck
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     3
-}
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     4
module Narrowing_Engine where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     5
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     6
import Monad
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     7
import Control.Exception
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     8
import System.Exit
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
     9
import Maybe
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    10
import List (partition, findIndex)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    11
import Code
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    12
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    13
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    14
type Pos = [Int]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    15
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    16
-- Term refinement
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    17
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    18
-- Operation: termOf
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    19
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    20
posOf :: Edge -> Pos
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    21
posOf (VN pos _) = pos
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    22
posOf (CtrB pos _) = pos
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    23
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    24
tailPosEdge :: Edge -> Edge
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    25
tailPosEdge (VN pos ty) = VN (tail pos) ty
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    26
tailPosEdge (CtrB pos ts) = CtrB (tail pos) ts
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    27
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    28
termOf :: Pos -> Path -> Narrowing_term
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    29
termOf pos (CtrB [] i : es) = Ctr i (termListOf pos es)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    30
termOf pos [VN [] ty] = Var pos ty
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    31
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    32
termListOf :: Pos -> Path -> [Narrowing_term]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    33
termListOf pos es = termListOf' 0 es
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    34
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    35
    termListOf' i [] = []
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    36
    termListOf' i (e : es) =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    37
      let 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    38
        (ts, rs) = List.partition (\e -> head (posOf e) == i) (e : es)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    39
        t = termOf (pos ++ [i]) (map tailPosEdge ts)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    40
      in
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    41
        (t : termListOf' (i + 1) rs) 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    42
{-
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    43
conv :: [[Term] -> a] -> Term -> a
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    44
conv cs (Var p _) = error ('\0':map toEnum p)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    45
conv cs (Ctr i xs) = (cs !! i) xs
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    46
-}
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    47
-- Answers
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    48
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    49
data Answer = Known Bool | Unknown Pos deriving Show;
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    50
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    51
answer :: a -> (a -> IO b) -> (Pos -> IO b) -> IO b
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    52
answer a known unknown =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    53
  do res <- try (evaluate a)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    54
     case res of
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    55
       Right b -> known b
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    56
       Left (ErrorCall ('\0':p)) -> unknown (map fromEnum p)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    57
       Left e -> throw e
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    58
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    59
--  Proofs and Refutation
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    60
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    61
data Quantifier = ExistentialQ | UniversalQ
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    62
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    63
data EvaluationResult = Eval Bool | UnknownValue Bool deriving Eq
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    64
{-
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    65
instance Show EvaluationResult where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    66
  show (Eval True) = "T"
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    67
  show (Eval False) = "F"
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    68
  show (UnknownValue False) = "U"
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    69
  show (UnknownValue True) = "X"
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    70
-}
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    71
uneval = UnknownValue True
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    72
unknown = UnknownValue False
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    73
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    74
andOp :: EvaluationResult -> EvaluationResult -> EvaluationResult
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    75
andOp (Eval b1) (Eval b2) = Eval (b1 && b2)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    76
andOp (Eval True) (UnknownValue b) = UnknownValue b
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    77
andOp (Eval False) (UnknownValue _) = Eval False
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    78
andOp (UnknownValue b) (Eval True) = UnknownValue b
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    79
andOp (UnknownValue _) (Eval False) = Eval False
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    80
andOp (UnknownValue b1) (UnknownValue b2) = UnknownValue (b1 || b2)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    81
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    82
orOp :: EvaluationResult -> EvaluationResult -> EvaluationResult
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    83
orOp (Eval b1) (Eval b2) = Eval (b1 || b2)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    84
orOp (Eval False) (UnknownValue b) = UnknownValue b
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    85
orOp (Eval True) (UnknownValue _) = Eval True
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    86
orOp (UnknownValue b) (Eval False) = UnknownValue b
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    87
orOp (UnknownValue _) (Eval True) = Eval True
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    88
orOp (UnknownValue b1) (UnknownValue b2) = UnknownValue (b1 && b2)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    89
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    90
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    91
data Edge = VN Pos Narrowing_type | CtrB Pos Int
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    92
type Path = [Edge]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    93
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    94
data QuantTree = Node EvaluationResult
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    95
  | VarNode Quantifier EvaluationResult Pos Narrowing_type QuantTree
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    96
  | CtrBranch Quantifier EvaluationResult Pos [QuantTree]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    97
{-
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    98
instance Show QuantTree where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
    99
  show (Node r) = "Node " ++ show r
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   100
  show (VarNode q r p _ t) = "VarNode " ++ show q ++ " " ++ show r ++ " " ++ show p ++ " " ++ show t
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   101
  show (CtrBranch q r p ts) = "CtrBranch " ++ show q ++ show r ++ show p ++ show ts
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   102
-}
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   103
evalOf :: QuantTree -> EvaluationResult
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   104
evalOf (Node r) = r
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   105
evalOf (VarNode _ r _ _ _) = r
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   106
evalOf (CtrBranch _ r _ _) = r
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   107
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   108
-- Operation find: finds first relevant unevaluated node and returns its path
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   109
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   110
find :: QuantTree -> Path
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   111
find (Node (UnknownValue True)) = []
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   112
find (VarNode _ _ pos ty t) = VN pos ty : (find t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   113
find (CtrBranch _ _ pos ts) = CtrB pos i : find (ts !! i)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   114
  where  
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   115
    Just i = findIndex (\t -> evalOf t == uneval) ts
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   116
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   117
-- Operation: updateNode ( and simplify)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   118
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   119
{- updates the Node and the stored evaluation results along the upper nodes -}
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   120
updateNode :: Path -> EvaluationResult -> QuantTree -> QuantTree
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   121
updateNode [] v (Node _) = Node v
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   122
updateNode (VN _ _ : es) v (VarNode q r p ty t) = VarNode q (evalOf t') p ty t'
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   123
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   124
    t' = updateNode es v t    
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   125
updateNode (CtrB _ i : es) v (CtrBranch q r pos ts) = CtrBranch q r' pos ts' 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   126
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   127
    (xs, y : ys) = splitAt i ts
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   128
    y' = updateNode es v y
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   129
    ts' = xs ++ (y' : ys)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   130
    r' = foldl (\s t -> oper s (evalOf t)) neutral ts'
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   131
    (neutral, oper) = case q of { UniversalQ -> (Eval True, andOp); ExistentialQ -> (Eval False, orOp)}
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   132
 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   133
-- Operation: refineTree
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   134
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   135
updateTree :: (QuantTree -> QuantTree) -> Path -> QuantTree -> QuantTree
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   136
updateTree f [] t = (f t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   137
updateTree f (VN _ _ : es) (VarNode q r pos ty t) = VarNode q r pos ty (updateTree f es t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   138
updateTree f (CtrB _ i : es) (CtrBranch q r pos ts) = CtrBranch q r pos (xs ++ (updateTree f es y : ys))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   139
   where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   140
     (xs, y : ys) = splitAt i ts
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   141
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   142
refineTree :: [Edge] -> Pos -> QuantTree -> QuantTree
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   143
refineTree es p t = updateTree refine (pathPrefix p es) t
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   144
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   145
    pathPrefix p es = takeWhile (\e -> posOf e /= p) es  
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   146
    refine (VarNode q r p (SumOfProd ps) t) =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   147
      CtrBranch q r p [ foldr (\(i,ty) t -> VarNode q r (p++[i]) ty t) t (zip [0..] ts) | ts <- ps ]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   148
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   149
-- refute
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   150
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   151
refute :: ([Narrowing_term] -> Bool) -> Int -> QuantTree -> IO QuantTree
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   152
refute exec d t = ref t
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   153
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   154
    ref t =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   155
      let path = find t in
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   156
        do
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   157
          t' <- answer (exec (termListOf [] path)) (\b -> return (updateNode path (Eval b) t))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   158
            (\p -> return (if length p < d then refineTree path p t else updateNode path unknown t));
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   159
          case evalOf t' of
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   160
            UnknownValue True -> ref t'
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   161
            _ -> return t'
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   162
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   163
depthCheck :: Int -> Property -> IO ()
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   164
depthCheck d p = refute (checkOf p) d (treeOf 0 p) >>= (\t -> 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   165
  case evalOf t of
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   166
   Eval False -> putStrLn ("SOME (" ++ show (counterexampleOf (reifysOf p) (exampleOf 0 t)) ++ ")")  
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   167
   _ -> putStrLn ("NONE"))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   168
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   169
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   170
-- presentation of counterexample
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   171
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   172
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   173
instance Show Typerep where {
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   174
  show (Typerep c ts) = "Type (\"" ++ c ++ "\", " ++ show ts ++ ")";
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   175
};
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   176
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   177
instance Show Term where {
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   178
  show (Const c t) = "Const (\"" ++ c ++ "\", " ++ show t ++ ")";
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   179
  show (App s t) = "(" ++ show s ++ ") $ (" ++ show t ++ ")";
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   180
  show (Abs s ty t) = "Abs (\"" ++ s ++ "\", " ++ show ty ++ ", " ++ show t ++ ")";
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   181
  show (Free s ty) = "Free (\"" ++ s ++  "\", " ++ show ty ++ ")";
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   182
};
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   183
{-
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   184
posOf :: Edge -> Pos
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   185
posOf (VN pos _) = pos
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   186
posOf (CtrB pos _) = pos
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   187
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   188
tailPosEdge :: Edge -> Edge
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   189
tailPosEdge (VN pos ty) = VN (tail pos) ty
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   190
tailPosEdge (CtrB pos ts) = CtrB (tail pos) ts
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   191
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   192
termOf :: Pos -> Tree -> (Narrowing_term, Tree)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   193
termOf pos = if Ctr i (termListOf (pos ++ [i]) )
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   194
termOf pos [VN [] ty] = Var pos ty
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   195
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   196
termListOf :: Pos -> [Narrowing_term]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   197
termListOf pos es = termListOf' 0 es
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   198
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   199
    termListOf' i [] = []
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   200
    termListOf' i (e : es) =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   201
      let
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   202
        (ts, rs) = List.partition (\e -> head (posOf e) == i) (e : es)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   203
        t = termOf (pos ++ [i]) (map tailPosEdge ts)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   204
      in
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   205
        (t : termListOf' (i + 1) rs) 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   206
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   207
termlist_of :: Pos -> QuantTree -> ([Term], QuantTree)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   208
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   209
termlist_of p' (Node r)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   210
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   211
term_of p' (VarNode _ _ p ty t) = if p == p' then
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   212
    (Some (Var ty), t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   213
  else
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   214
    (None, t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   215
term_of p' (CtrBranch q _ p ts) =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   216
  if p == p' then
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   217
    let
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   218
      i = findindex (\t -> evalOf t == Eval False)        
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   219
    in
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   220
      Ctr i (termlist_of (p ++ [i])  (ts ! i) [])
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   221
  else
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   222
    error ""
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   223
-}
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   224
termlist_of :: Pos -> ([Narrowing_term], QuantTree) -> ([Narrowing_term], QuantTree)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   225
termlist_of p' (terms, Node b) = (terms, Node b) 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   226
termlist_of p' (terms, VarNode q r p ty t) = if p' == take (length p') p then
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   227
    termlist_of p' (terms ++ [Var p ty], t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   228
  else
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   229
    (terms, VarNode q r p ty t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   230
termlist_of p' (terms, CtrBranch q r p ts) = if p' == take (length p') p then
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   231
    let
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   232
      Just i = findIndex (\t -> evalOf t == Eval False) ts
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   233
      (subterms, t') = fixp (\j -> termlist_of (p ++ [j])) 0 ([], ts !! i)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   234
    in
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   235
      (terms ++ [Ctr i subterms], t')
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   236
  else
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   237
    (terms, CtrBranch q r p ts)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   238
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   239
    fixp f j s = if length (fst (f j s)) == length (fst s) then s else fixp f (j + 1) (f j s)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   240
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   241
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   242
alltermlist_of :: Pos -> ([Narrowing_term], QuantTree) -> [([Narrowing_term], QuantTree)]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   243
alltermlist_of p' (terms, Node b) = [(terms, Node b)] 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   244
alltermlist_of p' (terms, VarNode q r p ty t) = if p' == take (length p') p then
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   245
    alltermlist_of p' (terms ++ [Var p ty], t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   246
  else
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   247
    [(terms, VarNode q r p ty t)]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   248
alltermlist_of p' (terms, CtrBranch q r p ts) =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   249
  if p' == take (length p') p then
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   250
    let
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   251
      its = filter (\(i, t) -> evalOf t == Eval False) (zip [0..] ts)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   252
    in
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   253
      concatMap
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   254
        (\(i, t) -> map (\(subterms, t') -> (terms ++ [Ctr i subterms], t'))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   255
           (fixp (\j -> alltermlist_of (p ++ [j])) 0 ([], t))) its
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   256
  else
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   257
    [(terms, CtrBranch q r p ts)]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   258
  where
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   259
    fixp f j s = case (f j s) of
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   260
      [s'] -> if length (fst s') == length (fst s) then [s'] else concatMap (fixp f (j + 1)) (f j s)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   261
      _ -> concatMap (fixp f (j + 1)) (f j s)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   262
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   263
data Example = UnivExample Narrowing_term Example | ExExample [(Narrowing_term, Example)] | EmptyExample
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   264
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   265
quantifierOf (VarNode q _ _ _ _) = q
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   266
quantifierOf (CtrBranch q _ _ _) = q
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   267
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   268
exampleOf :: Int -> QuantTree -> Example
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   269
exampleOf _ (Node _) = EmptyExample
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   270
exampleOf p t =
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   271
   case quantifierOf t of
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   272
     UniversalQ ->
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   273
       let
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   274
         ([term], rt) = termlist_of [p] ([], t)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   275
       in UnivExample term (exampleOf (p + 1) rt)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   276
     ExistentialQ ->
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   277
       ExExample (map (\([term], rt) -> (term, exampleOf (p + 1) rt)) (alltermlist_of [p] ([], t)))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   278
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   279
data Counterexample = Universal_Counterexample (Term, Counterexample)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   280
  | Existential_Counterexample [(Term, Counterexample)] | Empty_Assignment
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   281
  
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   282
instance Show Counterexample where {
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   283
show Empty_Assignment = "Narrowing_Generators.Empty_Assignment";
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   284
show (Universal_Counterexample x) = "Narrowing_Generators.Universal_Counterexample" ++ show x;
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   285
show (Existential_Counterexample x) = "Narrowing_Generators.Existential_Counterexample" ++ show x;
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   286
};
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   287
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   288
counterexampleOf :: [Narrowing_term -> Term] -> Example -> Counterexample
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   289
counterexampleOf [] EmptyExample = Empty_Assignment
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   290
counterexampleOf (reify : reifys) (UnivExample t ex) = Universal_Counterexample (reify t, counterexampleOf reifys ex)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   291
counterexampleOf (reify : reifys) (ExExample exs) = Existential_Counterexample (map (\(t, ex) -> (reify t, counterexampleOf reifys ex)) exs)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   292
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   293
checkOf :: Property -> [Narrowing_term] -> Bool
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   294
checkOf (Property b) = (\[] -> b)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   295
checkOf (Universal _ f _) = (\(t : ts) -> checkOf (f t) ts)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   296
checkOf (Existential _ f _) = (\(t : ts) -> checkOf (f t) ts)
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   297
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   298
dummy = Var [] (SumOfProd [[]])
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   299
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   300
treeOf :: Int -> Property -> QuantTree
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   301
treeOf n (Property _) = Node uneval
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   302
treeOf n (Universal ty f _)  = VarNode UniversalQ uneval [n] ty (treeOf (n + 1) (f dummy)) 
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   303
treeOf n (Existential ty f _) = VarNode ExistentialQ uneval [n] ty (treeOf (n + 1) (f dummy))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   304
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   305
reifysOf :: Property -> [Narrowing_term -> Term]
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   306
reifysOf (Property _) = []
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   307
reifysOf (Universal _ f r)  = (r : (reifysOf (f dummy)))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   308
reifysOf (Existential _ f r) = (r : (reifysOf (f dummy)))
d3c34987863b adding narrowing engine for existentials
bulwahn
parents:
diff changeset
   309