Skip to content
2 changes: 1 addition & 1 deletion deme/deme-id-creation.metta
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
;; the number of expansion is set to zero (0) in moses_params.h in the moses_statistics struct

;; for number to string conversion
! (bind! numStr (py-atom str))
!(bind! numStr (py-atom str))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does py-atom work in PeTTa?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it doens't. When there is a file import statement PeTTa won't run if there is syntax error in the imported file. So, I was just fixing that. Not looking into the correctness of the python binidings.


;; DemeId Type
(: DemeId Type)
Expand Down
27 changes: 13 additions & 14 deletions metapopulation/exemplar-selection.metta
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,45 @@
;; which, for now, is not clear what it is

;; removed python binding for compatibility with workflow -- XXX
; ! (bind! rndfloat (py-atom random.random))
; ! (bind! round (py-atom round))
! (bind! NO_EXEMPLAR "empty metapopulation")
! (bind! COMPXY_TEMP 4)
! (bind! INV_TEMP (/ 100.0 COMPXY_TEMP))
;; bind is not supported for constants (as of 13 NOV) in PeTTa -- thus using function style notation
(= (NO_EXEMPLAR) "empty metapopulation")
(= (COMPXY_TEMP) 4)
(= (INV_TEMP) (/ 100.0 (COMPXY_TEMP)))

;; exemplar selection
;; if the the metapopulation is empty - throw error and quit
;; if only one exemplar in the metapopulation select that
;; if more than one exemplar in mp - get the max penalized score and
;; make a roulette selection on those after converting scores into probability values
(: selectExemplar (-> (OS (Exemplar $a)) (Exemplar $a)))
; (: selectExemplar (-> (OS (Exemplar $a)) (Exemplar $a)))
(= (selectExemplar $metaPop)
(case $metaPop
((NilOS (Error $metaPop NO_EXEMPLAR))
((NilOS (Error $metaPop (NO_EXEMPLAR)))
((ConsOS $x NilOS) $x)
($_ (let* (($probs (getPnScore $metaPop))
($hstScr (List.max >= $probs))
;; get list of normalized ScoreT values
($normalizedProbs (normalizeProbs INV_TEMP $hstScr $probs))
($normalizedProbs (normalizeProbs (INV_TEMP) $hstScr $probs))
($sum (List.sum $normalizedProbs)))
(rouletteSelect $metaPop $probs $sum) )))))

;; get penalized scores of all the exemplars as a list of Numbers
;; (ConsOS $x $xs) -- pattern for the list of exemplars constructed by Cons
;; made use of deconstruction by pattern matching

(: getPnScore (-> (OS (Exemplar $a)) (List Number)))
; (: getPnScore (-> (OS (Exemplar $a)) (List Number)))
(= (getPnScore NilOS) Nil)
(= (getPnScore (ConsOS $x $xs))
(let (mkExemplar $tree1 $demeId1 (mkCscore $scrr $cpxy $cpxyPen $uniPen $penScr) $bscr1) $x
(Cons $penScr (getPnScore $xs))))

;; a function to normalize the score values into normalized scores of Boltzman distribution
;; the function is specific to this distribution type
(: normalizeProbs (-> Number Number (List Number) (List Number)))
; (: normalizeProbs (-> Number Number (List Number) (List Number)))
(= (normalizeProbs $invTemp $best Nil) Nil)
(= (normalizeProbs $invTemp $best (Cons $x $xs))
(let*
(($new (if (isInf $x) 0 (pow-math EXP (* (- $x $best) $invTemp))))
(($new (if (isinf-math $x) 0 (exp (* (- $x $best) $invTemp))))
($c (normalizeProbs $invTemp $best $xs)))

(Cons $new $c)))
Expand All @@ -53,9 +52,9 @@
;; $sum -- sum of penalized score values after normalization using the (pow-math EXP (* (- $val $higestScr) INV_TEMP))
;; to favour the selection of high scoring exemplars -- Boltzman distribution

(: rouletteSelect (-> (OS (Exemplar $a)) (List Number) Number (Exemplar $a)))
; (: rouletteSelect (-> (OS (Exemplar $a)) (List Number) Number (Exemplar $a)))
(= (rouletteSelect $metaPop $probs $sum)
(let* (($rndfloat (randomFloat))
(let* (($rndfloat (random-float 0 1))
($ajstdSum (* $sum $rndfloat))
($index (roulette $probs 0 $ajstdSum)))
(OS.getByIdx $index $metaPop)))
Expand All @@ -64,7 +63,7 @@
;; $probs -- (List Number) -- list of prob values
;; $sIdx -- start index -- 0
;; $ajstdsum -- sum of probabilities which has been multiplied with a random with random value in (0 .. 1) range
(: roulette (-> (List Number) Number Number Number))
; (: roulette (-> (List Number) Number Number Number))
(= (roulette Nil $sIdx $ajstdsum) (- $sIdx 1))
(= (roulette (Cons $p $xs) $sIdx $ajstdsum)
(if (<= (- $ajstdsum $p) 0)
Expand Down
2 changes: 1 addition & 1 deletion metapopulation/exemplar-type.metta
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
;; Penalized Score: very_worst_score (e.g., -1e37) ??
;; Behavioral Score: empty set -- Nil

(: xmplrInit (-> (Tree $a) DemeId Xmplr))
; (: xmplrInit (-> (Tree $a) DemeId Xmplr))
(= (xmplrInit $tree (mkDemeId $id))
(let ($iScore $iComplexity $iComplexityPen $iUinformityPen $iBehavioralScore) ((pow-math 10 -37) 0 0 (pow-math 10 -37) Nil)
(mkXmplr
Expand Down
50 changes: 25 additions & 25 deletions metapopulation/metapopulation.metta
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
;; importing constants -- a suitable value for each of these has to be determined based on experiment
; ! (bind! MIN-POOL-SIZE 250) ;; this is copied from the c++ implementation -- XXX a values that works best for the current implementation should be found by experrimentation??
; ! (bind! COMP-TEMP 6.0)
; ! (bind! CAP-COEF 50)
; !(bind! MIN-POOL-SIZE 250) ;; this is copied from the c++ implementation -- XXX a values that works best for the current implementation should be found by experrimentation??
; !(bind! COMP-TEMP 6.0)
; !(bind! CAP-COEF 50)

;; Exemplar type
(: Exemplar (-> $a Type))
Expand All @@ -13,49 +13,49 @@
;; $compTemp -- used to calculate the range of scores that are likely to be preserved by the selection process
;; $capCoef -- use to balance the number of individuals in the metapopulation by balancing population size so that it neither blows out the RAM or lacks enough variety -- may not even be necessary
;; $genCount -- used with $capCoef in the determination of max pop allowed given the above contstraints
(: resizeMetapop (-> (OS (Exemplar $a)) Number Number Number Number Number (OS (Exemplar $a))))
; (: resizeMetapop (-> (OS (Exemplar $a)) Number Number Number Number Number (OS (Exemplar $a))))
(= (resizeMetapop (ConsOS $exemplar $rest) $nToKeep $minPoolSize $compTemp $capCoef $genCount)
(let ($size $capSize) ((OS.length (ConsOS $exmplar $rest)) (int (capSize $capCoef $genCount))) ;; bind two variables with two function calls
(let ($size $capSize) ((eval (OS.length (ConsOS $exmplar $rest))) (eval (int (capSize $capCoef $genCount)))) ;; bind two variables with two function calls
(if (<= $size $minPoolSize)
(ConsOS $exemplar $rest)
(ConsOS $exemplar $rest)
(let (mkExemplar $tree $demeId $cScore $bScore) $exemplar ;; exemplar with the best score
(chain (getPenScore $cScore) $topScore
(chain (eval (getPenScore $cScore)) $topScore
(chain (- $topScore (usefulScoreRange $compTemp)) $worstScore
(chain (getBetterCandidates (ConsOS $exemplar $rest) $worstScore) $reducedMetapop
(chain (OS.length $reducedMetapop) $popSize
(chain (eval (OS.length $reducedMetapop)) $popSize
(if (<= $popSize $capSize)
$reducedMetapop
(cullAtRandom $reducedMetapop $nToKeep (- $popSize $capSize)))))))))))

;; compute useful range
(: usefulScoreRange (-> Number Number))
; (: usefulScoreRange (-> Number Number))
(= (usefulScoreRange $compTemp) (/ (* $compTemp 30.0) 100.0))

;; calculates cap size based on number of generations -- must be recomuted based on actual data in the new implementation
;; for the time being implement the C++ code as it
(: capSize (-> Number Number Number))
; (: capSize (-> Number Number Number))
(= (capSize $capCoef $genCount)
(* (* $capCoef (+ $genCount 250)) (+ 1 (* 2 (pow-math EXP (/ (* -1 $genCount) 500))))))
(* (* $capCoef (+ $genCount 250)) (+ 1 (* 2 (exp (/ (* -1 $genCount) 500))))))

;; getBetterCandidates -- returns all the memmbers whose score are greater than or equal to a predetermined worst score
(: getBetterCandidates (-> (OS (Exemplar $a)) Number (OS (Exemplar $a))))
; (: getBetterCandidates (-> (OS (Exemplar $a)) Number (OS (Exemplar $a))))
(= (getBetterCandidates NilOS $score) NilOS)
(= (getBetterCandidates (ConsOS $exemplar $rest) $worstScore)
(let (mkExemplar $tree $demeId $cScore $bScore) $exemplar
(chain (getPenScore $cScore) $penScore
(chain (eval (getPenScore $cScore)) $penScore

(if (>= $penScore $worstScore)
(ConsOS $exemplar (getBetterCandidates $rest $worstScore))
NilOS))))

;; cullAtRandom -- maintains the top N exemplars and removes candidates that are in the list with worse scores by chance
;; gives a certain chance for poor candidates to survive
(: cullAtRandom (-> (OS (Exemplar $a)) Number Number (OS (Exemplar $a))))
; (: cullAtRandom (-> (OS (Exemplar $a)) Number Number (OS (Exemplar $a))))
(= (cullAtRandom (ConsOS $exemplar $rest) $offset $nToRemove)
(if (> $nToRemove 0)
(chain (OS.length (ConsOS $exemplar $rest)) $popSize
(chain (random-int &rng $offset $popSize) $index
(chain (OS.removeByIdx (ConsOS $exemplar $rest) $index) $newPop
(chain (eval (OS.length (ConsOS $exemplar $rest))) $popSize
(chain (- (random-int $offset $popSize) 1) $index
(chain (eval (OS.removeByIdx (ConsOS $exemplar $rest) $index)) $newPop
(cullAtRandom $newPop $offset (- $nToRemove 1)))))
(ConsOS $exemplar $rest)))

Expand All @@ -64,37 +64,37 @@
;; (Exemplar $a): First exemplar
;; (Exemplar $a): Second exemplar
;; Return: L (less), E (equal), or G (greater)
(: compareExemplar (-> (Exemplar $a) (Exemplar $a) Atom))
; (: compareExemplar (-> (Exemplar $a) (Exemplar $a) Atom))
(= (compareExemplar
(mkExemplar $tree1 $demeId1 $cscore1 $bscr1)
(mkExemplar $tree2 $demeId2 $cscore2 $bscr2))
(if (apply < $cscore1 $cscore2) L
(if (apply == $cscore1 $cscore2) E G)))
(if (eval (apply < $cscore1 $cscore2) )L
(if (eval (apply == $cscore1 $cscore2)) E G)))

;; Extract BScore from Exemplar
;; Params:
;; (Exemplar $a): exemplar
;; Return: $bscore
(: getExemplarBScore (-> (Exemplar $a) BehavioralScore))
; (: getExemplarBScore (-> (Exemplar $a) BehavioralScore))
(= (getExemplarBScore (mkExemplar $tree $demeId $cscore $bscore)) $bscore)

;; Extract PenScore from Exemplar
;; Params:
;; (Exemplar $a): exemplar
;; Return: $penScore
(: getExemplarPenScore (-> (Exemplar $a) Number))
(= (getExemplarPenScore (mkExemplar $tree $demeId $cscore $bscore)) (getPenScore $cscore))
; (: getExemplarPenScore (-> (Exemplar $a) Number))
(= (getExemplarPenScore (mkExemplar $tree $demeId $cscore $bscore)) (eval (getPenScore $cscore)))

;; Extract Cscore from Exemplar
;; Params:
;; (Exemplar $a): exemplar
;; Return: $cscore
(: getExemplarCscore (-> (Exemplar $a) Cscore))
; (: getExemplarCscore (-> (Exemplar $a) Cscore))
(= (getExemplarCscore (mkExemplar $tree $demeId $cscore $bscore)) $cscore)

;; Extract Tree from Exemplar
;; Params:
;; (Exemplar $a): exemplar
;; Return: $tree
(: getExemplarTree (-> (Exemplar $a) (Tree $a)))
; (: getExemplarTree (-> (Exemplar $a) (Tree $a)))
(= (getExemplarTree (mkExemplar $tree $demeId $cscore $bscore)) $tree)
109 changes: 109 additions & 0 deletions metapopulation/tests/exemplar-selection-test.metta
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
; !(register-module! ../../../metta-moses)
!(import! &self ../../../metta-moses/utilities/ordered-set)
!(import! &self ../../../metta-moses/utilities/list-methods)
!(import! &self ../../../metta-moses/utilities/general-helpers)
!(import! &self ../../../metta-moses/metapopulation/exemplar-selection)
!(import! &self ../../../metta-moses/metapopulation/metapopulation)
!(import! &self ../../../metta-moses/utilities/tree)
(: A Bool)
;; Get penalized scores
; !(assertEqual (getPnScore NilOS) Nil)
; !(assertEqual
; (getPnScore
; (ConsOS (mkExemplar (mkTree (mkNode OR) (Cons (mkTree (mkNode NOT) (Cons (mkTree (mkNode A) Nil) Nil)) (Cons (mkTree (mkNode OR) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode B) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode C) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode D) Nil) Nil)) Nil)))) Nil))) (mkDemeId "1") (mkCscore -0.2 1 0.1 0.1 -0.4) (mkBScore (Cons 0 (Cons 0 Nil))))
; (ConsOS (mkExemplar (mkTree (mkNode OR) (Cons (mkTree (mkNode OR) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode B) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode C) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode D) Nil) Nil)) Nil)))) Nil)) (mkDemeId "1") (mkCscore -0.1 2 0.2 0.3 -0.6) (mkBScore (Cons 0 (Cons 0 Nil))))
; NilOS)))
; (Cons -0.4 (Cons -0.6 Nil)))
; !(assertEqual
; (getPnScore
; (ConsOS
; (mkExemplar (mkTree (mkNode OR) (Cons (mkTree (mkNode OR) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode B) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode C) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode D) Nil) Nil)) Nil)))) Nil)) (mkDemeId "1") (mkCscore -0.1 2 0.2 0.3 -0.6) (mkBScore (Cons 0 (Cons 0 Nil))))
; (ConsOS
; (mkExemplar (mkTree (mkNode OR) (Cons (mkTree (mkNode OR) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode B) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode C) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode D) Nil) Nil)) Nil)))) Nil)) (mkDemeId "1") (mkCscore -0.1 2 0.2 0.3 -0.6) (mkBScore (Cons 0 (Cons 0 Nil))))
; NilOS)))
; (Cons -0.6 (Cons -0.6 Nil)))

; ;; max of list of values of (List $a) type
; !(assertEqual (List.max >= Nil) Nil)
; !(assertEqual (List.max >= (Cons 0.75 Nil)) 0.75)
; !(assertEqual (List.max >= (Cons 0.9 (Cons 0.5 Nil))) 0.9)
; !(assertEqual (List.max >= (Cons 0.1 (Cons 0.4 (Cons 0.65 (Cons 0.9 Nil))))) 0.9)

; ;; Boltzman adjusted probablity values
; !(assertEqual (let $a (List.sum (normalizeProbs (INV_TEMP) 0.5 (Cons 0.3 Nil))) (get-type $a)) Number)
; !(assertEqual (let $a (List.sum (normalizeProbs (INV_TEMP) 0.7 (Cons 0.6 (Cons 0.2 Nil)))) (get-type $a)) Number)
; !(assertEqual (let $a (List.sum (normalizeProbs (INV_TEMP) 0.95 (Cons 0.95 (Cons 0.9 (Cons 0.85 Nil))))) (get-type $a)) Number)
; !(assertEqual (let $a (List.sum (normalizeProbs (INV_TEMP) 1.0 (Cons 0.9 (Cons 0.85 (Cons 0.95 (Cons 0.7 Nil)))))) (get-type $a)) Number)

; ;; roulette -- spinning the wheel favoring expressions with higher scores
; !(assertEqual (roulette (Cons 1.0 Nil) 0 0.57) 0)
; !(assertEqual (roulette (Cons 1.0 (Cons 0.0067 Nil)) 0 0.9564) 0)
; !(assertEqual (roulette (Cons 0.0821 (Cons 0.0067 (Cons 1 Nil))) 0 0.7622) 2)
; !(assertEqual (roulette (Cons 0.2 (Cons 0.5 (Cons 0.6 (Cons 0.2 Nil)))) 0 1.1) 2)
; !(assertEqual (roulette (Cons 0.0067 (Cons 0.0821 (Cons 1.0 Nil))) 0 0.0108) 1)

;; Tree Definitions
(= (treeA) (mkTree (mkNode A) Nil))
(= (treeB) (mkTree (mkNode AND) (Cons (mkTree (mkNode A) Nil) (Cons (mkTree (mkNode C) Nil) Nil))))
(= (treeC) (mkTree (mkNode OR) (Cons (mkTree (mkNode A) Nil) (Cons (mkTree (mkNode B) Nil) Nil))))
(= (treeY) (mkTree (mkNode AND) (Cons (mkTree (mkNode A) Nil) (Cons (mkTree (mkNode Z) Nil) Nil))))
(= (treeZ) (mkTree (mkNode OR) (Cons (mkTree (mkNode A) Nil) (Cons (mkTree (mkNode X) Nil) Nil))))
(= (tree2) (mkTree (mkNode AND) (Cons (mkTree (mkNode A) Nil) Nil)))
(= (tree3) (mkTree (mkNode AND) (Cons (mkTree (mkNode A) Nil) (Cons (mkTree (mkNode E) Nil) Nil))))

;; rouletteSelect
(= (exemplar-list0) (ConsOS (mkExemplar (treeA) (mkDemeId "1") (mkCscore 0.9 0.5 0.2 0.1 -0.6) (mkBscore (Cons 1 (Cons 0 Nil))))
(ConsOS (mkExemplar (treeB) (mkDemeId "2") (mkCscore 0.85 0.6 0.1 0.05 0.6) (mkBscore (Cons 1 (Cons 0 Nil))))
(ConsOS (mkExemplar (treeC) (mkDemeId "3") (mkCscore 0.4 0.7 0.05 0.01 0.3) (mkBscore (Cons 1 (Cons 0 Nil))))
NilOS))))
!(assertEqual
(let $choice (rouletteSelect (exemplar-list0)
(Cons 0.996 (Cons 1.0 (Cons 0.9857 Nil))) 2.9817)
(OS.contains (exemplar-list0) $choice)) True)

(= (exemplar-list1) (ConsOS (mkExemplar (treeA) (mkDemeId "9") (mkCscore 0.91 0.3 0.25 0.13 0.3) (mkBscore (Cons 1 (Cons 0 Nil))))
(ConsOS (mkExemplar (treeY) (mkDemeId "10") (mkCscore 0.88 0.4 0.22 0.12 0.4) (mkBscore (Cons 1 (Cons 1 Nil))))
(ConsOS (mkExemplar (treeZ) (mkDemeId "11") (mkCscore 0.83 0.5 0.15 0.10 0.5) (mkBscore (Cons 0 (Cons 1 Nil))))
NilOS))))
!(assertEqual
(let $choice (rouletteSelect (exemplar-list1) (Cons 0.9753 (Cons 0.9936 (Cons 1.0 Nil))) 2.9689)
(OS.contains (exemplar-list1) $choice )) True)

(= (exemplar-list2) (ConsOS (mkExemplar (treeA) (mkDemeId "7") (mkCscore 0.95 0.3 0.2 0.1 0.2) (mkBscore (Cons 1 (Cons 1 Nil))))
(ConsOS (mkExemplar (tree2) (mkDemeId "8") (mkCscore 0.80 0.6 0.1 0.05 0.2) (mkBscore (Cons 1 (Cons 1 Nil))))
(ConsOS (mkExemplar (tree3) (mkDemeId "12") (mkCscore 0.5 0.9 0.05 0.03 0.1) (mkBscore (Cons 1 (Cons 0 Nil))))
NilOS))))

!(assertEqual
(let $choice (rouletteSelect (exemplar-list2) (Cons 0.9654 (Cons 1.0 (Cons 0.9057 Nil))) 2.8711)
(OS.contains (exemplar-list2) $choice)) True)

;; selectExemplar
!(assertEqual (selectExemplar NilOS) (Error NilOS "empty metapopulation"))

(= (treeA-x) (mkExemplar treeA (mkDemeId "7") (mkCscore 0.95 0.3 0.2 0.1 0.4) (mkBscore (Cons 1 (Cons 1 Nil)))))

!(assertEqual (selectExemplar (ConsOS (treeA-x) NilOS)) (treeA-x))

(= (test1-exemplars)
(ConsOS (mkExemplar (treeA) (mkDemeId "1") (mkCscore 0.8 0.3 0.1 0.01 0.4) (mkBscore (Cons 1 (Cons 1 Nil))))
(ConsOS (mkExemplar (tree2) (mkDemeId "2") (mkCscore 0.7 0.4 0.05 0.05 0.5) (mkBscore (Cons 0 (Cons 1 Nil))))
(ConsOS (mkExemplar (tree3) (mkDemeId "3") (mkCscore 0.6 0.5 0.0 0.0 0.6) (mkBscore (Cons 1 (Cons 0 Nil))))
NilOS))))

!(assertEqual (let $choice (selectExemplar (test1-exemplars)) (OS.contains (test1-exemplars) $choice)) True)

(= (test2-exemplars)
(ConsOS (mkExemplar (treeA) (mkDemeId "101") (mkCscore 0.9 0.3 0.05 0.02 0.6)
(mkBscore (Cons 1 (Cons 1 (Cons 1 (Cons 1 Nil))))))
(ConsOS (mkExemplar (treeB) (mkDemeId "102") (mkCscore 0.6 0.5 0.1 0.1 0.5) (mkBscore (Cons 1 (Cons 1 (Cons 1 (Cons 1 Nil))))))
(ConsOS (mkExemplar (treeC) (mkDemeId "103") (mkCscore 0.4 0.4 0.05 0.1 0.4) (mkBscore (Cons 0 (Cons 0 (Cons 1 (Cons 0 Nil))))))
NilOS))))
!(assertEqual (let $choice (selectExemplar (test2-exemplars)) (OS.contains (test2-exemplars) $choice)) True)

(= (metaPop) (ConsOS (mkExemplar (mkTree (mkNode OR) (Cons (mkTree (mkNode NOT) (Cons (mkTree (mkNode A) Nil) Nil)) (Cons (mkTree (mkNode OR) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode B) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode C) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode D) Nil) Nil)) Nil)))) Nil))) (mkDemeId "1") (mkCscore -0.2 1 0.1 0.1 5) (mkBScore (Cons 0 (Cons 0 Nil))))
(ConsOS (mkExemplar (mkTree (mkNode OR) (Cons (mkTree (mkNode OR) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode B) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode C) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode D) Nil) Nil)) Nil)))) Nil)) (mkDemeId "1") (mkCscore -0.1 2 0.2 0.3 -0.6) (mkBScore (Cons 0 (Cons 0 Nil))))
(ConsOS (mkExemplar (mkTree (mkNode OR) (Cons (mkTree (mkNode OR) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode B) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode C) Nil) Nil)) (Cons (mkTree (mkNode AND) (Cons (mkTree (mkNode D) Nil) Nil)) Nil)))) Nil)) (mkDemeId "1") (mkCscore -0.1 2 0.2 0.3 -0.006) (mkBScore (Cons 0 (Cons 0 Nil)))) NilOS))))

; ! (assertEqual (let $choice (selectExemplar metaPop) ((get-type $choice) (OS.contains metaPop $choice))) ((Exemplar Bool) True))
!(assertEqual (let $choice (selectExemplar (metaPop)) (OS.contains (metaPop) $choice)) True)
Loading