-- This file is part of the 'term-rewriting' library. It is licensed -- under an MIT license. See the accompanying 'LICENSE' file for details. -- -- Authors: Bertram Felgenhauer {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-} -- Types and Arbitrary instances for tests. module Arbitrary ( Var', Fun', Term', Rule', Subst', ) where import Data.Rewriting.Term (Term (..)) import Data.Rewriting.Rule (Rule (..)) import qualified Data.Rewriting.Rule as Rule import Data.Rewriting.Substitution (Subst, GSubst) import qualified Data.Rewriting.Substitution.Type as Subst import Test.QuickCheck (Arbitrary (..), CoArbitrary (..), (><)) import Test.QuickCheck.Gen import Control.Applicative import Control.Monad import qualified Data.Map as M newtype Var' = Var' Char deriving (Eq, Ord) newtype Fun' = Fun' Char deriving (Eq, Ord) type Term' = Term Fun' Var' type Rule' = Rule Fun' Var' type Subst' = Subst Fun' Var' instance Show Var' where showsPrec p (Var' c) = showsPrec p c instance Show Fun' where showsPrec p (Fun' c) = showsPrec p c instance Arbitrary Var' where arbitrary = Var' <$> growingElements "xyzuvw" instance CoArbitrary Var' where coarbitrary (Var' c) = coarbitrary c instance Arbitrary Fun' where arbitrary = Fun' <$> growingElements "fghijk" instance CoArbitrary Fun' where coarbitrary (Fun' c) = coarbitrary c constant :: Gen Fun' constant = Fun' <$> growingElements "abcd" instance Arbitrary Term' where arbitrary = oneof [ Var <$> arbitrary, Fun <$> constant <*> pure [], Fun <$> arbitrary <*> args] where args = sized $ \n -> do k <- choose (1, 1 `max` n) let n' = if k == 1 then n else 2*n `div` k replicateM k (resize n' arbitrary) instance CoArbitrary Term' where coarbitrary (Var x) = variant 0 . coarbitrary x coarbitrary (Fun f ts) = variant (-1) . (coarbitrary f >< coarbitrary ts) instance Arbitrary Rule' where arbitrary = (Rule <$> arbitrary <*> arbitrary) `suchThat` Rule.isValid instance CoArbitrary Rule' where coarbitrary (Rule l r) = coarbitrary l >< coarbitrary r instance Arbitrary Subst' where arbitrary = Subst.fromMap . M.fromList <$> arbitrary instance CoArbitrary Subst' where coarbitrary = coarbitrary . M.toList . Subst.toMap