subsumptionTests :: Spec
subsumptionTests =
  describe ">>> subsumption tests" $ do
    it "should find a subsumed FILLS for EXISTS 1" $
      let subsumed = findSubsumed (Exists 1 "SomeRole") [Fills "SomeRole" $ C "X"]
      in subsumed `shouldBe` Just (Fills "SomeRole" $ C "X")
    it "should find a subsumed EXIST 2 for EXISTS 1" $
      let subsumed = findSubsumed (Exists 1 "SomeRole") [Exists 2 "SomeRole"]
      in subsumed `shouldBe` Just (Exists 2 "SomeRole")
    it "should find NOT a subsumed EXIST 1 for EXISTS 2" $
      let subsumed = findSubsumed (Exists 2 "SomeRole") [Exists 1 "SomeRole"]
      in subsumed `shouldBe` Nothing
    it "should find subsumed recursively for ALL (simple)" $
      let subsumed = findSubsumed (All "People" $ Atomic "HaveLegs") [All "People" $ Atomic "HaveLegs"]
      in subsumed `shouldBe` Just (All "People" $ Atomic "HaveLegs")
    it "should find subsumed for basic AND case" $
      -- let subsumed = And [Atomic "B", Exists 1 "SomeRole", Atomic "C"]
      --     subsumer = And [Exists 2 "SomeRole", Atomic "B"]
      let subsumed = And [Atomic "B", Exists 3 "SomeRole", Atomic "C"]
          subsumer = And [Atomic "B", Exists 2 "SomeRole"]
      in (findSubsumed subsumer [subsumed], subsumedBy subsumed subsumer)
         `shouldBe` (Just (And [Atomic "B",Exists 3 "SomeRole", Atomic "C"]), True)
    it "should work with an example" $
      let subsumer = And [All "Manager" (Atomic "B-SchoolGrad"),
                          Exists 1 "Exchange"]
          subsumed = And [Atomic "Company",
                          All "Manager" (And [Atomic "B-SchoolGrad",
                                              Exists 2 "TechnicalDegree"]),
                          Fills "Exchange" $ C "nasdaq"]
      in subsumedBy subsumed subsumer `shouldBe` True
    it "should find specific `All' concepts inside AND" $
      findSubsumed (All "m" (Atomic "n")) [And [Atomic "A",
                                                Exists 1 "x",
                                                All "m" (Atomic "n")]]
      `shouldBe` Just (And [Atomic "A",Exists 1 "x",All "m" (Atomic "n")])
    it "should find specific `Exists' concepts inside AND" $
      let subsumed = And [Atomic "A", Exists 3 "x"]
      in findSubsumed (Exists 1 "x") [subsumed] `shouldBe` Just subsumed
subsumptionTests :: Spec
subsumptionTests =
  describe ">>> subsumption tests" $ do
    it "should find a subsumed FILLS for EXISTS 1" $
      let subsumed = findSubsumed (Exists 1 "SomeRole") [Fills "SomeRole" $ C "X"]
      in subsumed `shouldBe` Just (Fills "SomeRole" $ C "X")
    it "should find a subsumed EXIST 2 for EXISTS 1" $
      let subsumed = findSubsumed (Exists 1 "SomeRole") [Exists 2 "SomeRole"]
      in subsumed `shouldBe` Just (Exists 2 "SomeRole")
    it "should find NOT a subsumed EXIST 1 for EXISTS 2" $
      let subsumed = findSubsumed (Exists 2 "SomeRole") [Exists 1 "SomeRole"]
      in subsumed `shouldBe` Nothing
    it "should find subsumed recursively for ALL (simple)" $
      let subsumed = findSubsumed (All "People" $ Atomic "HaveLegs") [All "People" $ Atomic "HaveLegs"]
      in subsumed `shouldBe` Just (All "People" $ Atomic "HaveLegs")
    it "should find subsumed for basic AND case" $
      -- let subsumed = And [Atomic "B", Exists 1 "SomeRole", Atomic "C"]
      --     subsumer = And [Exists 2 "SomeRole", Atomic "B"]
      let subsumed = And [Atomic "B", Exists 3 "SomeRole", Atomic "C"]
          subsumer = And [Atomic "B", Exists 2 "SomeRole"]
      in (findSubsumed subsumer [subsumed], subsumedBy subsumed subsumer)
         `shouldBe` (Just (And [Atomic "B",Exists 3 "SomeRole", Atomic "C"]), True)
    it "should work with an example" $
      let subsumer = And [All "Manager" (Atomic "B-SchoolGrad"),
                          Exists 1 "Exchange"]
          subsumed = And [Atomic "Company",
                          All "Manager" (And [Atomic "B-SchoolGrad",
                                              Exists 2 "TechnicalDegree"]),
                          Fills "Exchange" $ C "nasdaq"]
      in subsumedBy subsumed subsumer `shouldBe` True
    it "should find specific `All' concepts inside AND" $
      findSubsumed (All "m" (Atomic "n")) [And [Atomic "A",
                                                Exists 1 "x",
                                                All "m" (Atomic "n")]]
      `shouldBe` Just (And [Atomic "A",Exists 1 "x",All "m" (Atomic "n")])
    it "should find specific `Exists' concepts inside AND" $
      let subsumed = And [Atomic "A", Exists 3 "x"]
      in findSubsumed (Exists 1 "x") [subsumed] `shouldBe` Just subsumed
subsumptionTests =
  describe ">>> subsumption tests" $ do
    it "should find a subsumed FILLS for EXISTS 1" $
      let subsumed = findSubsumed (Exists 1 "SomeRole") [Fills "SomeRole" $ C "X"]
      in subsumed `shouldBe` Just (Fills "SomeRole" $ C "X")
    it "should find a subsumed EXIST 2 for EXISTS 1" $
      let subsumed = findSubsumed (Exists 1 "SomeRole") [Exists 2 "SomeRole"]
      in subsumed `shouldBe` Just (Exists 2 "SomeRole")
    it "should find NOT a subsumed EXIST 1 for EXISTS 2" $
      let subsumed = findSubsumed (Exists 2 "SomeRole") [Exists 1 "SomeRole"]
      in subsumed `shouldBe` Nothing
    it "should find subsumed recursively for ALL (simple)" $
      let subsumed = findSubsumed (All "People" $ Atomic "HaveLegs") [All "People" $ Atomic "HaveLegs"]
      in subsumed `shouldBe` Just (All "People" $ Atomic "HaveLegs")
    it "should find subsumed for basic AND case" $
      -- let subsumed = And [Atomic "B", Exists 1 "SomeRole", Atomic "C"]
      --     subsumer = And [Exists 2 "SomeRole", Atomic "B"]
      let subsumed = And [Atomic "B", Exists 3 "SomeRole", Atomic "C"]
          subsumer = And [Atomic "B", Exists 2 "SomeRole"]
      in (findSubsumed subsumer [subsumed], subsumedBy subsumed subsumer)
         `shouldBe` (Just (And [Atomic "B",Exists 3 "SomeRole", Atomic "C"]), True)
    it "should work with an example" $
      let subsumer = And [All "Manager" (Atomic "B-SchoolGrad"),
                          Exists 1 "Exchange"]
          subsumed = And [Atomic "Company",
                          All "Manager" (And [Atomic "B-SchoolGrad",
                                              Exists 2 "TechnicalDegree"]),
                          Fills "Exchange" $ C "nasdaq"]
      in subsumedBy subsumed subsumer `shouldBe` True
    it "should find specific `All' concepts inside AND" $
      findSubsumed (All "m" (Atomic "n")) [And [Atomic "A",
                                                Exists 1 "x",
                                                All "m" (Atomic "n")]]
      `shouldBe` Just (And [Atomic "A",Exists 1 "x",All "m" (Atomic "n")])
    it "should find specific `Exists' concepts inside AND" $
      let subsumed = And [Atomic "A", Exists 3 "x"]
      in findSubsumed (Exists 1 "x") [subsumed] `shouldBe` Just subsumed