library(sets)

# section 3 examples

s <- set(1L, 2L, 3L)
s2 <- as.set(2:4)

test_that("as.set", {
  expect_equal(s2, set(2L, 3L, 4L))
})

test_that("empty set", {
  expect_true(set_is_empty(set()))
})

test_that("less than or equal to", {
  expect_lte(set(1), set(1,2))
})

test_that("length", {
  expect_equal(length(s), 3)
})

test_that("union", {
  expect_equal(s | set("a"), set("a", 1L, 2L, 3L))
})

test_that("intersection", {
  expect_equal(s & s2, set(2L, 3L))
})

test_that("symmetric difference", {
  expect_equal(s %D% s2, set(1L, 4L))
})

test_that("Cartesian product", {
  expect_equal(s * s2,
               set(tuple(1L, 2L), tuple(1L, 3L), tuple(1L, 4L),
                   tuple(2L, 2L), tuple(2L, 3L), tuple(2L, 4L),
                    tuple(3L, 2L), tuple(3L, 3L), tuple(3L, 4L)))
  expect_equal(s ^ 2L,
               set(tuple(1L, 1L), tuple(1L, 2L), tuple(1L, 3L),
                   tuple(2L, 1L), tuple(2L, 2L), tuple(2L, 3L),
                   tuple(3L, 1L), tuple(3L, 2L), tuple(3L, 3L)))
})

test_that("power set", {
  expect_equal(2 ^ s,
               set(set(), set(1L), set(2L), set(3L), set(1L, 2L),
                   set(1L, 3L), set(2L, 3L), set(1L, 2L, 3L)))
})

test_that("relative complement", {
  expect_equal(set_complement(set(1), set(1, 2, 3)), set(2, 3))
})

test_that("absolute complement", {
  expect_equal(!set(1), set())
})

test_that("subsets", {
  expect_equal(set_combn(s, 2L),
               set(set(1L, 2L), set(1L, 3L), set(2L, 3L)))
})

test_that("closure and reduction", {
  cl <- closure(set(set(1), set(2), set(3)), "union")
  expect_equal(cl, set(set(1), set(2), set(3), set(1, 2), set(1, 3),
                       set(2, 3), set(1, 2, 3)))
  expect_equal(reduction(cl, "union"), set(set(1), set(2), set(3)))
})

test_that("sum and range", {
  expect_equal(sum(s), 6)
  expect_equal(range(s), c(1, 3))
})

test_that("subscripting", {
  s2 <- set(1,2, c, list(1,2))
  s2[[c]] <- "foo"
  s2[[list(1, 2)]] <- "bar"
  expect_equal(s2[list("foo", 1)], set("foo", 1))
})

test_that("sapply", {
  expect_equal(sapply(s, sqrt), c(1, sqrt(2), sqrt(3)))
})

test_that("set_outer", {
  expect_true(all(set_outer(set(1, 2), set(1, 2, 3), "/") ==
                    matrix(c(1, 2, 1/2, 1, 1/3, 2/3), ncol = 3)))
})

# section 4 examples

test_that("defining generalized sets", {
  X <- c("A", "B", "C")
  expect_equal(gset(support = X), set("A", "B", "C"))
  expect_equal(gset(support = X, universe = LETTERS[1:10]),
               set("A", "B", "C"))
  ms <- c(0.1, 0.3, 1)
  expect_equal(gset(support = X, memberships = ms),
               gset(elements =
                      list(e("A", 0.1), e("B", 0.3), e("C", 1))))
  f <- function(x) switch(x, A = 0.1, B = 0.2, C = 1, 0)
  expect_equal(gset(universe = X, charfun = f),
               gset(elements =
                      list(e("A", 0.1), e("B", 0.2), e("C", 1))))
})

test_that("generalized set operations", {
  X <- gset(c("A", "B", "C"), 4:6)
  Y <- gset(c("B", "C", "D"), 1:3)
  expect_equal(X | Y, gset(c("A", "B", "C", "D"), c(4, 5, 6, 3)))
  expect_equal(X & Y, gset(c("B", "C"), c(1, 2)))
  expect_equal(X + Y, gset(c("A", "B", "C", "D"), c(4, 6, 8, 3)))
  expect_equal(X - Y, gset(c("A", "B", "C"), c(4, 4, 4)))
  expect_equal(gset_product(X, Y), gset(c("B", "C"), c(5, 12)))
})

test_that("generalized set complements", {
  expect_equal(!gset(1, 0.3), gset(1, 0.7))
  X <- gset("a", universe = letters[1:3])
  expect_equal(!X, set("b", "c"))
  expect_equal(!!X, set("a"))
  expect_equal(!gset(1L, 2, universe = 1:3, bound = 3),
               gset(c(1L, 2L, 3L), c(1, 3, 3)))
})

test_that("generalized set means", {
  x <- gset(1:3, 1:3/3)
  y <- gset(1:2, 1:2/2)
  expect_equal(gset_mean(x, y),
               gset(c(1L, 2L, 3L), c(5/12, 5/6, 1/2)))
  expect_equal(gset_mean(x, y, "harmonic"),
               gset(c(1L, 2L), c(0.4, 0.8)))
  expect_equal(gset_mean(set(1), set(1, 2)),
               gset(c(1, 2), c(1, 0.5)))
})

test_that("transform memberships", {
  x <- gset(1:10, 1:10/10)
  expect_equal(gset_transform_memberships(x, pmax, 0.5),
               gset(1:10, c(rep(0.5, 5), 0.6, 0.7, 0.8, 0.9, 1)))
  x <- gset(1, 2)
  expect_equal(rep(x, 0.5), set(1))
  y <- gset(1:2, 1:2/2)
  expect_equal(gset_dilate(y), gset(1:2, c(1 / sqrt(2), 1)))
  expect_equal(gset_concentrate(y), gset(1:2, c(0.25, 1)))
  expect_equal(gset_normalize(y, 0.5), gset(1:2, c(0.25, 0.5)))
})

test_that("fuzzy logic", {
  x <- 1:10 / 10
  y <- rev(x)
  expect_equal(.S.(x, y),
               c(1.0, 0.9, 0.8, 0.7, 0.6, 0.6, 0.7, 0.8, 0.9, 1.0))
  fuzzy_logic("Fodor")
  expect_equal(.S.(x,y), rep(1, 10))
  X <- gset(c("A", "B", "C"), c(0.3, 0.5, 0.8))
  Y <- gset(c("B", "C", "D"), c(0.1, 0.3, 0.9))
  fuzzy_logic("Zadeh")
  expect_equal(X & Y, gset(c("B", "C"), c(0.1, 0.3)))
  expect_equal(X | Y,
               gset(c("A", "B", "C", "D"), c(0.3, 0.5, 0.8, 0.9)))
  expect_equal(gset_complement(X, Y), gset(c("B", "C", "D"), c(0.1, 0.2, 0.9)))
  fuzzy_logic("Fodor")
  expect_equal(X & Y, gset("C", 0.3))
  expect_equal(X | Y,
               gset(c("A", "B", "C", "D"), c(0.3, 0.5, 1, 0.9)))
  expect_equal(gset_complement(X, Y), gset("D", 0.9))
  expect_equal(cut(X, 0.5), set("B", "C"))
})
