normalizationTests :: Spec
normalizationTests =
  let atomics = Map.fromList [("SomeExists", Exists 2 "Something"),
                              ("Jess", Exists 1 "AJess")]
  in describe ">>> normalization tests" $ do
    -- trivial test of replacing an atomic with it's definition
    it "should resolve simple atomics" $
      normalize (Atomic "SomeExists") atomics `shouldBe` Exists 2 "Something"
    -- test `normalize' handling of `All'
    it "should normalize ALL's component" $
      normalize (All "xyz" (Atomic "SomeExists")) atomics `shouldBe`
      All "xyz" (Exists 2 "Something")
    -- test of `combineAlls'
    it "should combine ALLs" $
      combineAlls [All "a" $ Atomic "Jess",
                   Atomic "Separator",
                   All "b" $ Atomic "SomethingElseEntirely",
                   All "a" $ And [Atomic "Michael", Atomic "Balint"]] atomics
      `shouldBe` [Atomic "Separator",
                  All "a" (And [Atomic "Michael",
                                Atomic "Balint",
                                Exists 1 "AJess"]),
                  All "b" (Atomic "SomethingElseEntirely")]
    -- test of `combineExists'
    it "should combine EXISTSs" $
      combineExists [Exists 2 "Monkey",
                     Atomic "Separator",
                     Exists 8 "Fireball",
                     Exists 3 "Monkey"]
      `shouldBe` [Atomic "Separator",Exists 8 "Fireball",Exists 3 "Monkey"]
    -- same as previous through `normalize'
    it "should combine EXISTSs with `normalize'" $
      normalize (And [Exists 2 "Monkey",
                      Atomic "Separator",
                      Exists 8 "Fireball",
                      Exists 3 "Monkey"]) atomics
      `shouldBe` And [Atomic "Separator",Exists 8 "Fireball",Exists 3 "Monkey"]
    -- XXXX
    it "should normalize a complex structure" $
      let complexConcept =
            All "a" $ And [Exists 2 "AJess", Atomic "Jess"]
      in normalize complexConcept atomics
         `shouldBe` All "a" (Exists 2 "AJess")
    it "should normalize an example" $
      let atomics' = Map.fromList
                     [("WellRoundedCo", And [Atomic "Company",
                                             -- where all managers are biz school grads
                                             All "Manager" (And [Atomic "B-SchoolGrad",
                                                                 -- and have at least 1 tech degree
                                                                 Exists 1 "TechnicalDegree"])]),
                      ("HighTechCo", And [Atomic "Company",
                                          Fills "Exchange" (C "nasdaq"),
                                          All "Manager" (Atomic "Techie")]),
                      ("Techie", Exists 2 "TechnicalDegree")]
          exampleConcept = And [Atomic "WellRoundedCo", Atomic "HighTechCo"]
      in normalize exampleConcept atomics'
         `shouldBe` And [Atomic "Company",Fills "Exchange" (C "nasdaq"),All "Manager" (And [Atomic "B-SchoolGrad",Exists 2 "TechnicalDegree"])]

-- =========== --
-- subsumption --
-- =========== --
-- check by structure matching
-- e = subsuming concept
-- d = set to search for subsumed concept
normalizationTests :: Spec
normalizationTests =
  let atomics = Map.fromList [("SomeExists", Exists 2 "Something"),
                              ("Jess", Exists 1 "AJess")]
  in describe ">>> normalization tests" $ do
    -- trivial test of replacing an atomic with it's definition
    it "should resolve simple atomics" $
      normalize (Atomic "SomeExists") atomics `shouldBe` Exists 2 "Something"
    -- test `normalize' handling of `All'
    it "should normalize ALL's component" $
      normalize (All "xyz" (Atomic "SomeExists")) atomics `shouldBe`
      All "xyz" (Exists 2 "Something")
    -- test of `combineAlls'
    it "should combine ALLs" $
      combineAlls [All "a" $ Atomic "Jess",
                   Atomic "Separator",
                   All "b" $ Atomic "SomethingElseEntirely",
                   All "a" $ And [Atomic "Michael", Atomic "Balint"]] atomics
      `shouldBe` [Atomic "Separator",
                  All "a" (And [Atomic "Michael",
                                Atomic "Balint",
                                Exists 1 "AJess"]),
                  All "b" (Atomic "SomethingElseEntirely")]
    -- test of `combineExists'
    it "should combine EXISTSs" $
      combineExists [Exists 2 "Monkey",
                     Atomic "Separator",
                     Exists 8 "Fireball",
                     Exists 3 "Monkey"]
      `shouldBe` [Atomic "Separator",Exists 8 "Fireball",Exists 3 "Monkey"]
    -- same as previous through `normalize'
    it "should combine EXISTSs with `normalize'" $
      normalize (And [Exists 2 "Monkey",
                      Atomic "Separator",
                      Exists 8 "Fireball",
                      Exists 3 "Monkey"]) atomics
      `shouldBe` And [Atomic "Separator",Exists 8 "Fireball",Exists 3 "Monkey"]
    -- XXXX
    it "should normalize a complex structure" $
      let complexConcept =
            All "a" $ And [Exists 2 "AJess", Atomic "Jess"]
      in normalize complexConcept atomics
         `shouldBe` All "a" (Exists 2 "AJess")
    it "should normalize an example" $
      let atomics' = Map.fromList
                     [("WellRoundedCo", And [Atomic "Company",
                                             -- where all managers are biz school grads
                                             All "Manager" (And [Atomic "B-SchoolGrad",
                                                                 -- and have at least 1 tech degree
                                                                 Exists 1 "TechnicalDegree"])]),
                      ("HighTechCo", And [Atomic "Company",
                                          Fills "Exchange" (C "nasdaq"),
                                          All "Manager" (Atomic "Techie")]),
                      ("Techie", Exists 2 "TechnicalDegree")]
          exampleConcept = And [Atomic "WellRoundedCo", Atomic "HighTechCo"]
      in normalize exampleConcept atomics'
         `shouldBe` And [Atomic "Company",Fills "Exchange" (C "nasdaq"),All "Manager" (And [Atomic "B-SchoolGrad",Exists 2 "TechnicalDegree"])]

-- =========== --
-- subsumption --
-- =========== --
-- check by structure matching
-- e = subsuming concept
-- d = set to search for subsumed concept
normalizationTests =
  let atomics = Map.fromList [("SomeExists", Exists 2 "Something"),
                              ("Jess", Exists 1 "AJess")]
  in describe ">>> normalization tests" $ do
    -- trivial test of replacing an atomic with it's definition
    it "should resolve simple atomics" $
      normalize (Atomic "SomeExists") atomics `shouldBe` Exists 2 "Something"
    -- test `normalize' handling of `All'
    it "should normalize ALL's component" $
      normalize (All "xyz" (Atomic "SomeExists")) atomics `shouldBe`
      All "xyz" (Exists 2 "Something")
    -- test of `combineAlls'
    it "should combine ALLs" $
      combineAlls [All "a" $ Atomic "Jess",
                   Atomic "Separator",
                   All "b" $ Atomic "SomethingElseEntirely",
                   All "a" $ And [Atomic "Michael", Atomic "Balint"]] atomics
      `shouldBe` [Atomic "Separator",
                  All "a" (And [Atomic "Michael",
                                Atomic "Balint",
                                Exists 1 "AJess"]),
                  All "b" (Atomic "SomethingElseEntirely")]
    -- test of `combineExists'
    it "should combine EXISTSs" $
      combineExists [Exists 2 "Monkey",
                     Atomic "Separator",
                     Exists 8 "Fireball",
                     Exists 3 "Monkey"]
      `shouldBe` [Atomic "Separator",Exists 8 "Fireball",Exists 3 "Monkey"]
    -- same as previous through `normalize'
    it "should combine EXISTSs with `normalize'" $
      normalize (And [Exists 2 "Monkey",
                      Atomic "Separator",
                      Exists 8 "Fireball",
                      Exists 3 "Monkey"]) atomics
      `shouldBe` And [Atomic "Separator",Exists 8 "Fireball",Exists 3 "Monkey"]
    -- XXXX
    it "should normalize a complex structure" $
      let complexConcept =
            All "a" $ And [Exists 2 "AJess", Atomic "Jess"]
      in normalize complexConcept atomics
         `shouldBe` All "a" (Exists 2 "AJess")
    it "should normalize an example" $
      let atomics' = Map.fromList
                     [("WellRoundedCo", And [Atomic "Company",
                                             -- where all managers are biz school grads
                                             All "Manager" (And [Atomic "B-SchoolGrad",
                                                                 -- and have at least 1 tech degree
                                                                 Exists 1 "TechnicalDegree"])]),
                      ("HighTechCo", And [Atomic "Company",
                                          Fills "Exchange" (C "nasdaq"),
                                          All "Manager" (Atomic "Techie")]),
                      ("Techie", Exists 2 "TechnicalDegree")]
          exampleConcept = And [Atomic "WellRoundedCo", Atomic "HighTechCo"]
      in normalize exampleConcept atomics'
         `shouldBe` And [Atomic "Company",Fills "Exchange" (C "nasdaq"),All "Manager" (And [Atomic "B-SchoolGrad",Exists 2 "TechnicalDegree"])]

-- =========== --
-- subsumption --
-- =========== --
-- check by structure matching
-- e = subsuming concept
-- d = set to search for subsumed concept