{-
	Copyright (C) 2018 Dr. Alistair Ward

	This file is part of BishBosh.

	BishBosh is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	BishBosh is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with BishBosh.  If not, see <http://www.gnu.org/licenses/>.
-}
{- |
 [@AUTHOR@]	Dr. Alistair Ward

 [@DESCRIPTION@]	Defines the weight associated with each criterion.
-}

module BishBosh.Input.CriteriaWeights(
-- * Types
-- ** Type-synonyms
--	Transformation,
-- ** Data-types
	CriteriaWeights(
--		MkCriteriaWeights,
		getWeightOfMaterial,
		getWeightOfMobility,
		getWeightOfPieceSquareValue,
		getWeightOfCastlingPotential,
		getWeightOfDefence,
		getWeightOfDoubledPawns,
		getWeightOfIsolatedPawns,
		getWeightOfPassedPawns
	),
-- * Constants
	tag,
	weightOfMaterialTag,
--	weightOfMobilityTag,
	weightOfPieceSquareValueTag,
--	weightOfCastlingPotentialTag,
--	weightOfDefenceTag,
--	weightOfDoubledPawnsTag,
--	weightOfIsolatedPawnsTag,
--	weightOfPassedPawnsTag,
	onymousOperators,
-- * Functions
	calculateWeightedMean,
	normalise,
	perturbWeights,
-- ** Constructor
	mkCriteriaWeights
) where

import qualified	BishBosh.Attribute.CriterionValue			as Attribute.CriterionValue
import qualified	BishBosh.Attribute.CriterionWeight			as Attribute.CriterionWeight
import qualified	BishBosh.Attribute.WeightedMeanAndCriterionValues	as Attribute.WeightedMeanAndCriterionValues
import qualified	BishBosh.Data.Exception					as Data.Exception
import qualified	BishBosh.Property.ShowFloat				as Property.ShowFloat
import qualified	BishBosh.Text.ShowList					as Text.ShowList
import qualified	BishBosh.Types						as T
import qualified	Control.Arrow
import qualified	Control.DeepSeq
import qualified	Control.Exception
import qualified	Data.Default
import qualified	System.Random
import qualified	Text.XML.HXT.Arrow.Pickle				as HXT

-- | Used to qualify the XML.
tag :: String
tag :: String
tag					= String
"criteriaWeights"

-- | Used to qualify the XML.
weightOfMaterialTag :: String
weightOfMaterialTag :: String
weightOfMaterialTag			= String
"material"

-- | Used to qualify the XML.
weightOfMobilityTag :: String
weightOfMobilityTag :: String
weightOfMobilityTag			= String
"mobility"

-- | Used to qualify the XML.
weightOfPieceSquareValueTag :: String
weightOfPieceSquareValueTag :: String
weightOfPieceSquareValueTag		= String
"pieceSquareValue"

-- | Used to qualify the XML.
weightOfCastlingPotentialTag :: String
weightOfCastlingPotentialTag :: String
weightOfCastlingPotentialTag		= String
"castlingPotential"

-- | Used to qualify the XML.
weightOfDefenceTag :: String
weightOfDefenceTag :: String
weightOfDefenceTag			= String
"defence"

-- | Used to qualify the XML.
weightOfDoubledPawnsTag :: String
weightOfDoubledPawnsTag :: String
weightOfDoubledPawnsTag			= String
"doubledPawns"

-- | Used to qualify the XML.
weightOfIsolatedPawnsTag :: String
weightOfIsolatedPawnsTag :: String
weightOfIsolatedPawnsTag		= String
"isolatedPawns"

-- | Used to qualify the XML.
weightOfPassedPawnsTag :: String
weightOfPassedPawnsTag :: String
weightOfPassedPawnsTag			= String
"passedPawns"

{- |
	* The weight of various criteria used to select a move from alternatives, at specific point in the game.

	* CAVEAT: these weights determine the effective value of /isolated/ or /doubled/ @Pawn@s,
	& this value shouldn't be less than their weighted normalised /rank-value/, otherwise sacrifice would be beneficial.
-}
data CriteriaWeights criterionWeight	= MkCriteriaWeights {
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMaterial		:: Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- ^ The arithmetic difference between the total /rank-value/ of the /piece/s currently in play on either side; <https://www.chessprogramming.org/Material>.
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMobility		:: Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- ^ The arithmetic difference between the reciprocal of the number of destinations available to the /piece/s of either side. N.B. this weight can be derived from 'getWeightOfMaterial' since losing a @Queen@ is less significant than reducing mobility to zero; <https://www.chessprogramming.org/Mobility>.
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPieceSquareValue	:: Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- ^ The arithmetic difference in the values of the squares occupied by the pieces of either side.
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfCastlingPotential	:: Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- ^ Whether each player has been permanently prevented from /Castling/.
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDefence		:: Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- ^ The arithmetic difference between the number of /piece/s defending each of one's own, compared with the opponent.
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDoubledPawns		:: Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- ^ The arithmetic difference between the total number of /doubled/ @Pawn@s on either side; <https://www.chessprogramming.org/Doubled_Pawn>.
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfIsolatedPawns	:: Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- ^ The arithmetic difference between the total number of /isolated/ @Pawn@s on either side; <https://www.chessprogramming.org/Isolated_Pawn>.
	CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPassedPawns		:: Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ The arithmetic difference between the total number of /passed/ @Pawn@s on either side; <https://www.chessprogramming.org/Passed_Pawn>.
} deriving (CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
(CriteriaWeights criterionWeight
 -> CriteriaWeights criterionWeight -> Bool)
-> (CriteriaWeights criterionWeight
    -> CriteriaWeights criterionWeight -> Bool)
-> Eq (CriteriaWeights criterionWeight)
forall criterionWeight.
Eq criterionWeight =>
CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
$c/= :: forall criterionWeight.
Eq criterionWeight =>
CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
== :: CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
$c== :: forall criterionWeight.
Eq criterionWeight =>
CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
Eq, Int -> CriteriaWeights criterionWeight -> ShowS
[CriteriaWeights criterionWeight] -> ShowS
CriteriaWeights criterionWeight -> String
(Int -> CriteriaWeights criterionWeight -> ShowS)
-> (CriteriaWeights criterionWeight -> String)
-> ([CriteriaWeights criterionWeight] -> ShowS)
-> Show (CriteriaWeights criterionWeight)
forall criterionWeight.
Show criterionWeight =>
Int -> CriteriaWeights criterionWeight -> ShowS
forall criterionWeight.
Show criterionWeight =>
[CriteriaWeights criterionWeight] -> ShowS
forall criterionWeight.
Show criterionWeight =>
CriteriaWeights criterionWeight -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CriteriaWeights criterionWeight] -> ShowS
$cshowList :: forall criterionWeight.
Show criterionWeight =>
[CriteriaWeights criterionWeight] -> ShowS
show :: CriteriaWeights criterionWeight -> String
$cshow :: forall criterionWeight.
Show criterionWeight =>
CriteriaWeights criterionWeight -> String
showsPrec :: Int -> CriteriaWeights criterionWeight -> ShowS
$cshowsPrec :: forall criterionWeight.
Show criterionWeight =>
Int -> CriteriaWeights criterionWeight -> ShowS
Show)

-- | Smart-constructor.
mkCriteriaWeights
	:: (Eq criterionWeight, Num criterionWeight)
	=> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /material/.
	-> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /mobility/.
	-> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /pieceSquareValue/.
	-> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /castlingPotential/.
	-> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /defence/.
	-> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /doubledPawns/.
	-> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /isolatedPawns/.
	-> Attribute.CriterionWeight.CriterionWeight criterionWeight	-- ^ /passedPawns/.
	-> CriteriaWeights criterionWeight
mkCriteriaWeights :: CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
mkCriteriaWeights CriterionWeight criterionWeight
a CriterionWeight criterionWeight
b CriterionWeight criterionWeight
c CriterionWeight criterionWeight
d CriterionWeight criterionWeight
e CriterionWeight criterionWeight
f CriterionWeight criterionWeight
g CriterionWeight criterionWeight
h
	| CriteriaWeights criterionWeight
criteriaWeights CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
forall a. Eq a => a -> a -> Bool
== CriteriaWeights criterionWeight
forall a. Bounded a => a
minBound	= Exception -> CriteriaWeights criterionWeight
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> CriteriaWeights criterionWeight)
-> Exception -> CriteriaWeights criterionWeight
forall a b. (a -> b) -> a -> b
$ String -> Exception
Data.Exception.mkInvalidDatum String
"BishBosh.Input.CriteriaWeights.mkCriteriaWeights:\tall weights are zero."
	| Bool
otherwise			= CriteriaWeights criterionWeight
criteriaWeights
	where
		criteriaWeights :: CriteriaWeights criterionWeight
criteriaWeights	= CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
forall criterionWeight.
CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
MkCriteriaWeights CriterionWeight criterionWeight
a CriterionWeight criterionWeight
b CriterionWeight criterionWeight
c CriterionWeight criterionWeight
d CriterionWeight criterionWeight
e CriterionWeight criterionWeight
f CriterionWeight criterionWeight
g CriterionWeight criterionWeight
h

instance Real criterionWeight => Property.ShowFloat.ShowFloat (CriteriaWeights criterionWeight) where
	showsFloat :: (Double -> ShowS) -> CriteriaWeights criterionWeight -> ShowS
showsFloat Double -> ShowS
fromDouble MkCriteriaWeights {
		getWeightOfMaterial :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMaterial		= CriterionWeight criterionWeight
weightOfMaterial,
		getWeightOfMobility :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMobility		= CriterionWeight criterionWeight
weightOfMobility,
		getWeightOfPieceSquareValue :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= CriterionWeight criterionWeight
weightOfPieceSquareValue,
		getWeightOfCastlingPotential :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfCastlingPotential	= CriterionWeight criterionWeight
weightOfCastlingPotential,
		getWeightOfDefence :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDefence		= CriterionWeight criterionWeight
weightOfDefence,
		getWeightOfDoubledPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDoubledPawns		= CriterionWeight criterionWeight
weightOfDoubledPawns,
		getWeightOfIsolatedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= CriterionWeight criterionWeight
weightOfIsolatedPawns,
		getWeightOfPassedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPassedPawns		= CriterionWeight criterionWeight
weightOfPassedPawns
	} = [(String, ShowS)] -> ShowS
Text.ShowList.showsAssociationList' ([(String, ShowS)] -> ShowS) -> [(String, ShowS)] -> ShowS
forall a b. (a -> b) -> a -> b
$ ((String, CriterionWeight criterionWeight) -> (String, ShowS))
-> [(String, CriterionWeight criterionWeight)] -> [(String, ShowS)]
forall a b. (a -> b) -> [a] -> [b]
map (
		(CriterionWeight criterionWeight -> ShowS)
-> (String, CriterionWeight criterionWeight) -> (String, ShowS)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
Control.Arrow.second ((CriterionWeight criterionWeight -> ShowS)
 -> (String, CriterionWeight criterionWeight) -> (String, ShowS))
-> (CriterionWeight criterionWeight -> ShowS)
-> (String, CriterionWeight criterionWeight)
-> (String, ShowS)
forall a b. (a -> b) -> a -> b
$ Double -> ShowS
fromDouble (Double -> ShowS)
-> (CriterionWeight criterionWeight -> Double)
-> CriterionWeight criterionWeight
-> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. criterionWeight -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac (criterionWeight -> Double)
-> (CriterionWeight criterionWeight -> criterionWeight)
-> CriterionWeight criterionWeight
-> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CriterionWeight criterionWeight -> criterionWeight
forall criterionWeight.
CriterionWeight criterionWeight -> criterionWeight
Attribute.CriterionWeight.deconstruct
	 ) [
		(
			String
weightOfMaterialTag,		CriterionWeight criterionWeight
weightOfMaterial
		), (
			String
weightOfMobilityTag,		CriterionWeight criterionWeight
weightOfMobility
		), (
			String
weightOfPieceSquareValueTag,	CriterionWeight criterionWeight
weightOfPieceSquareValue
		), (
			String
weightOfCastlingPotentialTag,	CriterionWeight criterionWeight
weightOfCastlingPotential
		), (
			String
weightOfDefenceTag,		CriterionWeight criterionWeight
weightOfDefence
		), (
			String
weightOfDoubledPawnsTag,	CriterionWeight criterionWeight
weightOfDoubledPawns
		), (
			String
weightOfIsolatedPawnsTag,	CriterionWeight criterionWeight
weightOfIsolatedPawns
		), (
			String
weightOfPassedPawnsTag,		CriterionWeight criterionWeight
weightOfPassedPawns
		)
	 ]

instance Num criterionWeight => Data.Default.Default (CriteriaWeights criterionWeight) where
	def :: CriteriaWeights criterionWeight
def = MkCriteriaWeights :: forall criterionWeight.
CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
MkCriteriaWeights {
		getWeightOfMaterial :: CriterionWeight criterionWeight
getWeightOfMaterial		= CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound,
		getWeightOfMobility :: CriterionWeight criterionWeight
getWeightOfMobility		= CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def,
		getWeightOfPieceSquareValue :: CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def,
		getWeightOfCastlingPotential :: CriterionWeight criterionWeight
getWeightOfCastlingPotential	= CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def,
		getWeightOfDefence :: CriterionWeight criterionWeight
getWeightOfDefence		= CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def,
		getWeightOfDoubledPawns :: CriterionWeight criterionWeight
getWeightOfDoubledPawns		= CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def,
		getWeightOfIsolatedPawns :: CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def,
		getWeightOfPassedPawns :: CriterionWeight criterionWeight
getWeightOfPassedPawns		= CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def
	}

instance Control.DeepSeq.NFData criterionWeight => Control.DeepSeq.NFData (CriteriaWeights criterionWeight) where
	rnf :: CriteriaWeights criterionWeight -> ()
rnf (MkCriteriaWeights CriterionWeight criterionWeight
a CriterionWeight criterionWeight
b CriterionWeight criterionWeight
c CriterionWeight criterionWeight
d CriterionWeight criterionWeight
e CriterionWeight criterionWeight
f CriterionWeight criterionWeight
g CriterionWeight criterionWeight
h)	= [CriterionWeight criterionWeight] -> ()
forall a. NFData a => a -> ()
Control.DeepSeq.rnf [CriterionWeight criterionWeight
a, CriterionWeight criterionWeight
b, CriterionWeight criterionWeight
c, CriterionWeight criterionWeight
d, CriterionWeight criterionWeight
e, CriterionWeight criterionWeight
f, CriterionWeight criterionWeight
g, CriterionWeight criterionWeight
h]

instance Num criterionWeight => Bounded (CriteriaWeights criterionWeight) where
	maxBound :: CriteriaWeights criterionWeight
maxBound	= CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
forall criterionWeight.
CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
MkCriteriaWeights CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound CriterionWeight criterionWeight
forall a. Bounded a => a
maxBound
	minBound :: CriteriaWeights criterionWeight
minBound	= CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
forall criterionWeight.
CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
MkCriteriaWeights CriterionWeight criterionWeight
forall a. Bounded a => a
minBound CriterionWeight criterionWeight
forall a. Bounded a => a
minBound CriterionWeight criterionWeight
forall a. Bounded a => a
minBound CriterionWeight criterionWeight
forall a. Bounded a => a
minBound CriterionWeight criterionWeight
forall a. Bounded a => a
minBound CriterionWeight criterionWeight
forall a. Bounded a => a
minBound CriterionWeight criterionWeight
forall a. Bounded a => a
minBound CriterionWeight criterionWeight
forall a. Bounded a => a
minBound

instance (
	HXT.XmlPickler	criterionWeight,
	Num		criterionWeight,
	Ord		criterionWeight,
	Show		criterionWeight
 ) => HXT.XmlPickler (CriteriaWeights criterionWeight) where
	xpickle :: PU (CriteriaWeights criterionWeight)
xpickle	= CriteriaWeights criterionWeight
-> PU (CriteriaWeights criterionWeight)
-> PU (CriteriaWeights criterionWeight)
forall a. Eq a => a -> PU a -> PU a
HXT.xpDefault CriteriaWeights criterionWeight
forall a. Default a => a
Data.Default.def (PU (CriteriaWeights criterionWeight)
 -> PU (CriteriaWeights criterionWeight))
-> (PU (CriteriaWeights criterionWeight)
    -> PU (CriteriaWeights criterionWeight))
-> PU (CriteriaWeights criterionWeight)
-> PU (CriteriaWeights criterionWeight)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> PU (CriteriaWeights criterionWeight)
-> PU (CriteriaWeights criterionWeight)
forall a. String -> PU a -> PU a
HXT.xpElem String
tag (PU (CriteriaWeights criterionWeight)
 -> PU (CriteriaWeights criterionWeight))
-> PU (CriteriaWeights criterionWeight)
-> PU (CriteriaWeights criterionWeight)
forall a b. (a -> b) -> a -> b
$ ((CriterionWeight criterionWeight, CriterionWeight criterionWeight,
  CriterionWeight criterionWeight, CriterionWeight criterionWeight,
  CriterionWeight criterionWeight, CriterionWeight criterionWeight,
  CriterionWeight criterionWeight, CriterionWeight criterionWeight)
 -> CriteriaWeights criterionWeight,
 CriteriaWeights criterionWeight
 -> (CriterionWeight criterionWeight,
     CriterionWeight criterionWeight, CriterionWeight criterionWeight,
     CriterionWeight criterionWeight, CriterionWeight criterionWeight,
     CriterionWeight criterionWeight, CriterionWeight criterionWeight,
     CriterionWeight criterionWeight))
-> PU
     (CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight)
-> PU (CriteriaWeights criterionWeight)
forall a b. (a -> b, b -> a) -> PU a -> PU b
HXT.xpWrap (
		\(CriterionWeight criterionWeight
a, CriterionWeight criterionWeight
b, CriterionWeight criterionWeight
c, CriterionWeight criterionWeight
d, CriterionWeight criterionWeight
e, CriterionWeight criterionWeight
f, CriterionWeight criterionWeight
g, CriterionWeight criterionWeight
h) -> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
forall criterionWeight.
(Eq criterionWeight, Num criterionWeight) =>
CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
mkCriteriaWeights CriterionWeight criterionWeight
a CriterionWeight criterionWeight
b CriterionWeight criterionWeight
c CriterionWeight criterionWeight
d CriterionWeight criterionWeight
e CriterionWeight criterionWeight
f CriterionWeight criterionWeight
g CriterionWeight criterionWeight
h,	-- Construct.
		\MkCriteriaWeights {
			getWeightOfMaterial :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMaterial		= CriterionWeight criterionWeight
weightOfMaterial,
			getWeightOfMobility :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMobility		= CriterionWeight criterionWeight
weightOfMobility,
			getWeightOfPieceSquareValue :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= CriterionWeight criterionWeight
weightOfPieceSquareValue,
			getWeightOfCastlingPotential :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfCastlingPotential	= CriterionWeight criterionWeight
weightOfCastlingPotential,
			getWeightOfDefence :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDefence		= CriterionWeight criterionWeight
weightOfDefence,
			getWeightOfDoubledPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDoubledPawns		= CriterionWeight criterionWeight
weightOfDoubledPawns,
			getWeightOfIsolatedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= CriterionWeight criterionWeight
weightOfIsolatedPawns,
			getWeightOfPassedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPassedPawns		= CriterionWeight criterionWeight
weightOfPassedPawns
		} -> (
			CriterionWeight criterionWeight
weightOfMaterial,
			CriterionWeight criterionWeight
weightOfMobility,
			CriterionWeight criterionWeight
weightOfPieceSquareValue,
			CriterionWeight criterionWeight
weightOfCastlingPotential,
			CriterionWeight criterionWeight
weightOfDefence,
			CriterionWeight criterionWeight
weightOfDoubledPawns,
			CriterionWeight criterionWeight
weightOfIsolatedPawns,
			CriterionWeight criterionWeight
weightOfPassedPawns
		) -- Deconstruct.
	 ) (PU
   (CriterionWeight criterionWeight, CriterionWeight criterionWeight,
    CriterionWeight criterionWeight, CriterionWeight criterionWeight,
    CriterionWeight criterionWeight, CriterionWeight criterionWeight,
    CriterionWeight criterionWeight, CriterionWeight criterionWeight)
 -> PU (CriteriaWeights criterionWeight))
-> PU
     (CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight)
-> PU (CriteriaWeights criterionWeight)
forall a b. (a -> b) -> a -> b
$ PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
-> PU
     (CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight,
      CriterionWeight criterionWeight, CriterionWeight criterionWeight)
forall a b c d e f g h.
PU a
-> PU b
-> PU c
-> PU d
-> PU e
-> PU f
-> PU g
-> PU h
-> PU (a, b, c, d, e, f, g, h)
HXT.xp8Tuple (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfMaterialTag
	 ) (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfMobilityTag
	 ) (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfPieceSquareValueTag
	 ) (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfCastlingPotentialTag
	 ) (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfDefenceTag
	 ) (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfDoubledPawnsTag
	 ) (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfIsolatedPawnsTag
	 ) (
		String -> PU (CriterionWeight criterionWeight)
xpickle' String
weightOfPassedPawnsTag
	 ) where
		xpickle' :: String -> PU (CriterionWeight criterionWeight)
xpickle'	= CriterionWeight criterionWeight
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
forall a. Eq a => a -> PU a -> PU a
HXT.xpDefault CriterionWeight criterionWeight
forall a. Default a => a
Data.Default.def (PU (CriterionWeight criterionWeight)
 -> PU (CriterionWeight criterionWeight))
-> (String -> PU (CriterionWeight criterionWeight))
-> String
-> PU (CriterionWeight criterionWeight)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
-> PU (CriterionWeight criterionWeight)
-> PU (CriterionWeight criterionWeight)
forall a. String -> PU a -> PU a
`HXT.xpAttr` PU (CriterionWeight criterionWeight)
forall a. XmlPickler a => PU a
HXT.xpickle)

{- |
	* Returns the weighted sum of the specified criteria, divided by the sum of the weights; <https://www.chessprogramming.org/evaluation>

	* Each criterion increases in proportion to some desirable attribute of the proposed /game/.

	* Each criterion should be in the same range of magnitudes, so that none dominates the total, thus making the total a clear measure of the value attributed to each.

	* Also writes individual unweighted /criterion-value/s, to facilitate post-analysis; if the corresponding weight is zero, for efficiency evaluation of the criterion is avoided.
-}
calculateWeightedMean :: (
	Fractional	weightedMean,
	Real		criterionValue,
	Real		criterionWeight
 )
	=> CriteriaWeights criterionWeight
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /material/:	maximum if a player's /move/ equals the maximum total piece value (including /queened/ @Pawn@s), while their opponent has just a @King@.
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /mobility/:	maximum when the opponent is check-mated.
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /pieceSquareValue/:	maximum when this player occupies all the strategically important squares & the opponent none.
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /castlingPotential/:	maximum when this player either has /castled/ or can, but the opponent has been permanently prevented.
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /defence/:	maximum when this player's /piece/s are fully utilised in defence, but none of the opponent's are.
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /doubledPawns/:	maximum when this player hasn't any /doubled/ @Pawn@s & the opponent has two files of four @Pawn@s.
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /isolatedPawns/:	maximum when this player hasn't any /isolated/ @Pawn@s & all the opponent's @Pawn@s are /isolated/.
	-> Attribute.CriterionValue.CriterionValue criterionValue						-- ^ /passedPawns/:	maximum when this player has 8 /passed/ @Pawn@s & the opponent has none.
	-> Attribute.WeightedMeanAndCriterionValues.WeightedMeanAndCriterionValues weightedMean criterionValue	-- ^ The individual /criteria/ values, & their /weighted mean/.
{-# SPECIALISE calculateWeightedMean
	:: CriteriaWeights T.CriterionWeight
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.CriterionValue.CriterionValue T.CriterionValue
	-> Attribute.WeightedMeanAndCriterionValues.WeightedMeanAndCriterionValues T.WeightedMean T.CriterionValue
 #-}
calculateWeightedMean :: CriteriaWeights criterionWeight
-> CriterionValue criterionValue
-> CriterionValue criterionValue
-> CriterionValue criterionValue
-> CriterionValue criterionValue
-> CriterionValue criterionValue
-> CriterionValue criterionValue
-> CriterionValue criterionValue
-> CriterionValue criterionValue
-> WeightedMeanAndCriterionValues weightedMean criterionValue
calculateWeightedMean MkCriteriaWeights {
	getWeightOfMaterial :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMaterial		= CriterionWeight criterionWeight
weightOfMaterial,
	getWeightOfMobility :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMobility		= CriterionWeight criterionWeight
weightOfMobility,
	getWeightOfPieceSquareValue :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= CriterionWeight criterionWeight
weightOfPieceSquareValue,
	getWeightOfCastlingPotential :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfCastlingPotential	= CriterionWeight criterionWeight
weightOfCastlingPotential,
	getWeightOfDefence :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDefence		= CriterionWeight criterionWeight
weightOfDefence,
	getWeightOfDoubledPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDoubledPawns		= CriterionWeight criterionWeight
weightOfDoubledPawns,
	getWeightOfIsolatedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= CriterionWeight criterionWeight
weightOfIsolatedPawns,
	getWeightOfPassedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPassedPawns		= CriterionWeight criterionWeight
weightOfPassedPawns
} CriterionValue criterionValue
material CriterionValue criterionValue
mobility CriterionValue criterionValue
pieceSquareValue CriterionValue criterionValue
castlingPotential CriterionValue criterionValue
defence CriterionValue criterionValue
doubledPawns CriterionValue criterionValue
isolatedPawns CriterionValue criterionValue
passedPawns	= [(CriterionValue criterionValue, CriterionWeight criterionWeight)]
-> WeightedMeanAndCriterionValues weightedMean criterionValue
forall weightedMean criterionValue criterionWeight.
(Fractional weightedMean, Real criterionValue,
 Real criterionWeight) =>
[(CriterionValue criterionValue, CriterionWeight criterionWeight)]
-> WeightedMeanAndCriterionValues weightedMean criterionValue
Attribute.CriterionValue.calculateWeightedMean [
	(
		CriterionValue criterionValue
material,		CriterionWeight criterionWeight
weightOfMaterial
	), (
		CriterionValue criterionValue
mobility,		CriterionWeight criterionWeight
weightOfMobility
	), (
		CriterionValue criterionValue
pieceSquareValue,	CriterionWeight criterionWeight
weightOfPieceSquareValue
	), (
		CriterionValue criterionValue
castlingPotential,	CriterionWeight criterionWeight
weightOfCastlingPotential
	), (
		CriterionValue criterionValue
defence,		CriterionWeight criterionWeight
weightOfDefence
	), (
		CriterionValue criterionValue
doubledPawns,		CriterionWeight criterionWeight
weightOfDoubledPawns
	), (
		CriterionValue criterionValue
isolatedPawns,		CriterionWeight criterionWeight
weightOfIsolatedPawns
	), (
		CriterionValue criterionValue
passedPawns,		CriterionWeight criterionWeight
weightOfPassedPawns
	)
 ]

-- | The type of a function which mutates 'CriteriaWeights'.
type Transformation criterionWeight	= CriteriaWeights criterionWeight -> CriteriaWeights criterionWeight

-- | Adjust the mean weight, so that the maximum weight is @1@.
normalise :: (
	Fractional	criterionWeight,
	Ord		criterionWeight,
	Show		criterionWeight
 ) => Transformation criterionWeight
normalise :: Transformation criterionWeight
normalise criteriaWeights :: CriteriaWeights criterionWeight
criteriaWeights@MkCriteriaWeights {
	getWeightOfMaterial :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMaterial		= CriterionWeight criterionWeight
weightOfMaterial,
	getWeightOfMobility :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMobility		= CriterionWeight criterionWeight
weightOfMobility,
	getWeightOfPieceSquareValue :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= CriterionWeight criterionWeight
weightOfPieceSquareValue,
	getWeightOfCastlingPotential :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfCastlingPotential	= CriterionWeight criterionWeight
weightOfCastlingPotential,
	getWeightOfDefence :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDefence		= CriterionWeight criterionWeight
weightOfDefence,
	getWeightOfDoubledPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDoubledPawns		= CriterionWeight criterionWeight
weightOfDoubledPawns,
	getWeightOfIsolatedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= CriterionWeight criterionWeight
weightOfIsolatedPawns,
	getWeightOfPassedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPassedPawns		= CriterionWeight criterionWeight
weightOfPassedPawns
} = Bool -> Transformation criterionWeight
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (
	CriteriaWeights criterionWeight
criteriaWeights CriteriaWeights criterionWeight
-> CriteriaWeights criterionWeight -> Bool
forall a. Eq a => a -> a -> Bool
/= CriteriaWeights criterionWeight
forall a. Bounded a => a
minBound	-- Guard against divide-by-zero.
 ) MkCriteriaWeights :: forall criterionWeight.
CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
MkCriteriaWeights {
	getWeightOfMaterial :: CriterionWeight criterionWeight
getWeightOfMaterial		= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfMaterial,
	getWeightOfMobility :: CriterionWeight criterionWeight
getWeightOfMobility		= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfMobility,
	getWeightOfPieceSquareValue :: CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfPieceSquareValue,
	getWeightOfCastlingPotential :: CriterionWeight criterionWeight
getWeightOfCastlingPotential	= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfCastlingPotential,
	getWeightOfDefence :: CriterionWeight criterionWeight
getWeightOfDefence		= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfDefence,
	getWeightOfDoubledPawns :: CriterionWeight criterionWeight
getWeightOfDoubledPawns		= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfDoubledPawns,
	getWeightOfIsolatedPawns :: CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfIsolatedPawns,
	getWeightOfPassedPawns :: CriterionWeight criterionWeight
getWeightOfPassedPawns		= CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight CriterionWeight criterionWeight
weightOfPassedPawns
 } where
	normaliseCriterionWeight :: CriterionWeight criterionWeight -> CriterionWeight criterionWeight
normaliseCriterionWeight	= criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
(Num criterionWeight, Ord criterionWeight, Show criterionWeight) =>
criterionWeight -> CriterionWeight criterionWeight
Attribute.CriterionWeight.mkCriterionWeight (criterionWeight -> CriterionWeight criterionWeight)
-> (CriterionWeight criterionWeight -> criterionWeight)
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
		criterionWeight -> criterionWeight -> criterionWeight
forall a. Fractional a => a -> a -> a
/ CriterionWeight criterionWeight -> criterionWeight
forall criterionWeight.
CriterionWeight criterionWeight -> criterionWeight
Attribute.CriterionWeight.deconstruct (
			[CriterionWeight criterionWeight]
-> CriterionWeight criterionWeight
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [
				CriterionWeight criterionWeight
weightOfMaterial,
				CriterionWeight criterionWeight
weightOfMobility,
				CriterionWeight criterionWeight
weightOfPieceSquareValue,
				CriterionWeight criterionWeight
weightOfCastlingPotential,
				CriterionWeight criterionWeight
weightOfDefence,
				CriterionWeight criterionWeight
weightOfDoubledPawns,
				CriterionWeight criterionWeight
weightOfIsolatedPawns,
				CriterionWeight criterionWeight
weightOfPassedPawns
			]
		)
	 ) (criterionWeight -> criterionWeight)
-> (CriterionWeight criterionWeight -> criterionWeight)
-> CriterionWeight criterionWeight
-> criterionWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CriterionWeight criterionWeight -> criterionWeight
forall criterionWeight.
CriterionWeight criterionWeight -> criterionWeight
Attribute.CriterionWeight.deconstruct

{- |
	* Independently perturbs each /criterion-weight/ by a random value, of configurable magnitude.

	* Under this transformation, /criterion-weight/s of @0@, will remain unchanged, thus irrelevant criteria remain irrelevant.
-}
perturbWeights :: (
	Fractional		criterionWeight,
	Real			criterionWeight,
	Show			criterionWeight,
	System.Random.RandomGen	randomGen
 )
	=> randomGen
	-> criterionWeight	-- ^ Change-magnitude.
	-> Transformation criterionWeight
perturbWeights :: randomGen -> criterionWeight -> Transformation criterionWeight
perturbWeights randomGen
_ criterionWeight
0 CriteriaWeights criterionWeight
criteriaWeights	= CriteriaWeights criterionWeight
criteriaWeights
perturbWeights randomGen
randomGen criterionWeight
changeMagnitude MkCriteriaWeights {
	getWeightOfMaterial :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMaterial		= CriterionWeight criterionWeight
weightOfMaterial,
	getWeightOfMobility :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMobility		= CriterionWeight criterionWeight
weightOfMobility,
	getWeightOfPieceSquareValue :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= CriterionWeight criterionWeight
weightOfPieceSquareValue,
	getWeightOfCastlingPotential :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfCastlingPotential	= CriterionWeight criterionWeight
weightOfCastlingPotential,
	getWeightOfDefence :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDefence		= CriterionWeight criterionWeight
weightOfDefence,
	getWeightOfDoubledPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDoubledPawns		= CriterionWeight criterionWeight
weightOfDoubledPawns,
	getWeightOfIsolatedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= CriterionWeight criterionWeight
weightOfIsolatedPawns,
	getWeightOfPassedPawns :: forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPassedPawns		= CriterionWeight criterionWeight
weightOfPassedPawns
} = Bool -> Transformation criterionWeight
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (criterionWeight
changeMagnitude criterionWeight -> criterionWeight -> Bool
forall a. Ord a => a -> a -> Bool
> criterionWeight
0) Transformation criterionWeight -> Transformation criterionWeight
forall a b. (a -> b) -> a -> b
$ Transformation criterionWeight
forall criterionWeight.
(Fractional criterionWeight, Ord criterionWeight,
 Show criterionWeight) =>
Transformation criterionWeight
normalise MkCriteriaWeights :: forall criterionWeight.
CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
-> CriteriaWeights criterionWeight
MkCriteriaWeights {
	getWeightOfMaterial :: CriterionWeight criterionWeight
getWeightOfMaterial		= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
a CriterionWeight criterionWeight
weightOfMaterial,
	getWeightOfMobility :: CriterionWeight criterionWeight
getWeightOfMobility		= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
b CriterionWeight criterionWeight
weightOfMobility,
	getWeightOfPieceSquareValue :: CriterionWeight criterionWeight
getWeightOfPieceSquareValue	= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
c CriterionWeight criterionWeight
weightOfPieceSquareValue,
	getWeightOfCastlingPotential :: CriterionWeight criterionWeight
getWeightOfCastlingPotential	= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
d CriterionWeight criterionWeight
weightOfCastlingPotential,
	getWeightOfDefence :: CriterionWeight criterionWeight
getWeightOfDefence		= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
e CriterionWeight criterionWeight
weightOfDefence,
	getWeightOfDoubledPawns :: CriterionWeight criterionWeight
getWeightOfDoubledPawns		= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
f CriterionWeight criterionWeight
weightOfDoubledPawns,
	getWeightOfIsolatedPawns :: CriterionWeight criterionWeight
getWeightOfIsolatedPawns	= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
g CriterionWeight criterionWeight
weightOfIsolatedPawns,
	getWeightOfPassedPawns :: CriterionWeight criterionWeight
getWeightOfPassedPawns		= Double
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall criterionWeight a.
(Show criterionWeight, Fractional criterionWeight, Real a,
 Ord criterionWeight) =>
a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy Double
h CriterionWeight criterionWeight
weightOfPassedPawns
} where
	(Double
a : Double
b : Double
c : Double
d : Double
e : Double
f : Double
g : Double
h : [Double]
_)	= (Double, Double) -> randomGen -> [Double]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
System.Random.randomRs (Double
1 :: Double, Double -> Double
forall a. Enum a => a -> a
succ (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ criterionWeight -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac criterionWeight
changeMagnitude) randomGen
randomGen
	reduceBy :: a
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
reduceBy a
randomValue			= criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
(Num criterionWeight, Ord criterionWeight, Show criterionWeight) =>
criterionWeight -> CriterionWeight criterionWeight
Attribute.CriterionWeight.mkCriterionWeight (criterionWeight -> CriterionWeight criterionWeight)
-> (CriterionWeight criterionWeight -> criterionWeight)
-> CriterionWeight criterionWeight
-> CriterionWeight criterionWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (criterionWeight -> criterionWeight -> criterionWeight
forall a. Fractional a => a -> a -> a
/ a -> criterionWeight
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
randomValue) (criterionWeight -> criterionWeight)
-> (CriterionWeight criterionWeight -> criterionWeight)
-> CriterionWeight criterionWeight
-> criterionWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CriterionWeight criterionWeight -> criterionWeight
forall criterionWeight.
CriterionWeight criterionWeight -> criterionWeight
Attribute.CriterionWeight.deconstruct	-- N.B. this always reduces the weight, leaving 'normalise' to correct this.

-- | A list of named accessors & mutators.
onymousOperators :: [
	(
		String,												-- Tag.
		CriteriaWeights criterionWeight -> Attribute.CriterionWeight.CriterionWeight criterionWeight,	-- Accessor.
		Attribute.CriterionWeight.CriterionWeight criterionWeight -> Transformation criterionWeight	-- Mutator.
	) -- Triple.
 ]
onymousOperators :: [(String,
  CriteriaWeights criterionWeight -> CriterionWeight criterionWeight,
  CriterionWeight criterionWeight -> Transformation criterionWeight)]
onymousOperators	= [
	(
		String
weightOfMaterialTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMaterial,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfMaterial :: CriterionWeight criterionWeight
getWeightOfMaterial = CriterionWeight criterionWeight
w }
	), (
		String
weightOfMobilityTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfMobility,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfMobility :: CriterionWeight criterionWeight
getWeightOfMobility = CriterionWeight criterionWeight
w }
	), (
		String
weightOfPieceSquareValueTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPieceSquareValue,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfPieceSquareValue :: CriterionWeight criterionWeight
getWeightOfPieceSquareValue = CriterionWeight criterionWeight
w }
	), (
		String
weightOfCastlingPotentialTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfCastlingPotential,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfCastlingPotential :: CriterionWeight criterionWeight
getWeightOfCastlingPotential = CriterionWeight criterionWeight
w }
	), (
		String
weightOfDefenceTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDefence,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfDefence :: CriterionWeight criterionWeight
getWeightOfDefence = CriterionWeight criterionWeight
w }
	), (
		String
weightOfDoubledPawnsTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfDoubledPawns,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfDoubledPawns :: CriterionWeight criterionWeight
getWeightOfDoubledPawns = CriterionWeight criterionWeight
w }
	), (
		String
weightOfIsolatedPawnsTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfIsolatedPawns,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfIsolatedPawns :: CriterionWeight criterionWeight
getWeightOfIsolatedPawns = CriterionWeight criterionWeight
w }
	), (
		String
weightOfPassedPawnsTag,
		CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
forall criterionWeight.
CriteriaWeights criterionWeight -> CriterionWeight criterionWeight
getWeightOfPassedPawns,
		\CriterionWeight criterionWeight
w CriteriaWeights criterionWeight
criteriaWeights -> CriteriaWeights criterionWeight
criteriaWeights { getWeightOfPassedPawns :: CriterionWeight criterionWeight
getWeightOfPassedPawns = CriterionWeight criterionWeight
w }
	)
 ]