twee-lib-2.1: misc/test.hs
{-# LANGUAGE TemplateHaskell, FlexibleInstances, FlexibleContexts, UndecidableInstances, StandaloneDeriving, ScopedTypeVariables, TupleSections, DeriveGeneric #-}
import Twee.Constraints
import Twee.Term hiding (subst, canonicalise, F)
import Twee.Term.Core hiding (F)
import Test.QuickCheck hiding (Function, Fun)
import Test.QuickCheck.All
import Twee.Pretty
import Twee.CP
import Twee.Proof
import qualified Twee.KBO as Ord
import Text.PrettyPrint
import Twee.Base hiding (F)
import Twee.Rule
import Twee.Equation
import Control.Monad
import qualified Data.Map as Map
import Data.Maybe
import Data.Ord
import Data.List
import Data.Typeable
import qualified Twee.Index as Index
import Data.Int
import GHC.Generics
newtype Func = F Int deriving (Eq, Ord, Show)
instance Pretty Func where pPrint (F f) = text "f" <> int f
instance PrettyTerm Func
instance Arbitrary (Subst Func) where
arbitrary = fmap fromJust (fmap listToSubst (liftM2 zip (fmap nub arbitrary) (infiniteListOf arbitrary)))
instance Arbitrary Func where
arbitrary = F <$> choose (1, 1)
instance Minimal Func where
minimal = fun (F 0)
instance Sized Func where size _ = 1
instance Arity Func where
arity (F 0) = 0
arity (F 1) = 2
instance Skolem Func
instance EqualsBonus Func
instance Arbitrary Var where arbitrary = fmap V (choose (0, 3))
instance (Ord f, Typeable f, Arbitrary f) => Arbitrary (Fun f) where
arbitrary = fmap fun arbitrary
instance (Ord f, Typeable f, Arbitrary f, Sized f, Arity f) => Arbitrary (Term f) where
arbitrary =
sized $ \n ->
oneof $
[ build <$> var <$> arbitrary ] ++
[ do { f <- arbitrary; build <$> app f <$> vectorOf (arity f) (resize ((n-1) `div` arity f) arbitrary :: Gen (Term f)) } | n > 0 ]
shrink (App f ts0) =
ts ++ (build <$> app f <$> shrinkOne ts)
where
ts = unpack ts0
shrinkOne [] = []
shrinkOne (x:xs) =
[ y:xs | y <- shrink x ] ++
[ x:ys | ys <- shrinkOne xs ]
shrink _ = []
data Pair f = Pair (Term f) (Term f) deriving Show
instance (Ord f, Typeable f, Arbitrary f, Arity f, Sized f) => Arbitrary (Pair f) where
arbitrary = liftM2 Pair arbitrary arbitrary
shrink (Pair x y) =
[ Pair x' y | x' <- shrink x ] ++
[ Pair x y' | y' <- shrink y ] ++
[ Pair x' y' | x' <- shrink x, y' <- shrink y ]
instance Ordered Func where
lessIn = Ord.lessIn
lessEq = Ord.lessEq
instance Function f => Arbitrary (Model f) where
arbitrary = fmap (modelFromOrder . map Variable . nub) arbitrary
shrink = weakenModel
prop_1 :: Model Func -> Pair Func -> Subst Func -> Property
prop_1 model (Pair t u) sub =
counterexample ("Model: " ++ prettyShow model) $
counterexample ("Subst: " ++ prettyShow sub) $
conjoin $ do
let cp = CriticalPair (t :=: u) 0 Nothing (axiom (Axiom 0 "dummy" (t :=: u)))
r@(Rule _ t' u') <- map orient (map cp_eqn (split cp))
return $
counterexample ("LHS: " ++ prettyShow t') $
counterexample ("RHS: " ++ prettyShow u') $
counterexample ("Rule: " ++ prettyShow r) $
counterexample ("Inst: " ++ prettyShow (Rule Oriented (subst sub t') (subst sub u'))) $
counterexample ("Res: " ++ show (lessIn model (subst sub u') (subst sub t'))) $
not (reducesInModel model r sub) || isJust (lessIn model (subst sub u') (subst sub t'))
prop_2 :: Model Func -> Pair Func -> Bool
prop_2 model (Pair t u) =
not (lessIn model t u == Just Strict && isJust (lessIn model u t))
prop_3 :: Pair Func -> Bool
prop_3 (Pair t u) =
not (lessThan t u && lessEq u t)
prop_4 :: Pair Func -> Property
prop_4 (Pair t u) =
t /= u ==>
not (lessEq t u && lessEq u t)
prop_5 :: Term Func -> Property
prop_5 t =
lessEq t t .&&. not (lessThan t t)
prop_paths :: Term Func -> Property
prop_paths t =
forAllShrink (choose (0, len t-1)) shrink $ \n ->
counterexample (show (positionToPath t n)) $
pathToPosition t (positionToPath t n) === n
deriving instance Ord f => Ord (Subst f)
prop_index :: [Term Func] -> Term Func -> Property
prop_index ts u =
counterexample (show ts) $
counterexample (show idx) $
sort (catMaybes [fmap (,t) (match t u) | t <- ts]) ===
sort (Index.matches u idx)
where
idx = foldr (\t -> Index.insert t t) Index.empty ts
deriving instance Eq Symbol
deriving instance Generic Symbol
instance Arbitrary Symbol where
arbitrary =
Symbol <$>
arbitrary <*>
fmap getLarge arbitrary <*>
(fmap (fromIntegral . getLarge) (arbitrary :: Gen (Large Int32)) `suchThat` (> 0) `suchThat` (< 2^31))
shrink s =
filter ok (genericShrink s)
where
ok s = Twee.Term.Core.size s > 0
prop_symbol_1 :: Symbol -> Property
prop_symbol_1 s =
withMaxSuccess 100000 $
counterexample ("fun/index/size = " ++ show (isFun s, index s, Twee.Term.Core.size s)) $
counterexample ("n = " ++ show (fromSymbol s)) $
toSymbol (fromSymbol s) === twiddle s
where
twiddle s =
s { index = fromIntegral (fromIntegral (index s) :: Int32) }
prop_symbol_2 :: Int64 -> Property
prop_symbol_2 n =
withMaxSuccess 100000 $
fromSymbol (toSymbol n) === n
return []
main = $forAllProperties (quickCheckWithResult stdArgs { maxSuccess = 1000000 })
t :: Term Func
t = build (app (fun (F 0)) [app (fun (F 1)) [var (V 0), var (V 1)], var (V 2)])