> module Kulitta.QuotientSpaces where
> import Data.List
> import System.Random
> import Control.DeepSeq
> import Data.Maybe
> type EqClass a = [a]
> type QSpace a = [EqClass a]
> type Predicate a = a -> Bool
> type Norm a = a -> a
> type EqRel a = a -> a -> Bool
========= QUOTIENT SPACE IMPLEMENTATION =========
First we define the "slash" operator for S/R.
> (//) :: (Eq a) => [a] -> EqRel a -> QSpace a
> [] // r = []
> xs // r =
> let sx = [y | y <- xs, r y (head xs)]
> in sx : [z | z <- xs, not (elem z sx)] // r
The eqClass function is used to find the equivalence class of an
element, x, given a quotient space and the relation used to form it.
We need to know the relation used, because we do not require that
x is in the quotient space, qs.
> eqClass :: (Eq a, Show a) => QSpace a -> EqRel a -> a -> EqClass a
> eqClass qs r x =
> let ind = findIndex (\e -> r x (head e)) qs
> in maybe (error ("(eqClass) No class for "++show x)) (qs !!) ind
=============================
Code for randomizing a list.
> randomize :: StdGen -> [a] -> [a]
> randomize sg rs =
> let n = length rs
> plist = take n (nub (randomRs (0,n-1) sg))
> in map (rs!!) plist