content: > module Kulitta.QuotientSpaces where
  > import Data.List
  > import System.Random
  > import Control.DeepSeq
  > import Data.Maybe
  
  
  > type EqClass a = [a] -- equivalence class
  > type QSpace a = [EqClass a] -- quotient space
  > type Predicate a = a -> Bool
  > type Norm a = a -> a -- normalizations
  > type EqRel a = a -> a -> Bool -- equivalence relations
  
  ========= 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