code: package it.unibz.inf.ontop.iq;
  
  import com.google.common.collect.ImmutableList;
  import com.google.common.collect.ImmutableMap;
  import com.google.common.collect.ImmutableSet;
  import it.unibz.inf.ontop.dbschema.*;
  import it.unibz.inf.ontop.iq.node.ExtensionalDataNode;
  import org.junit.Test;
  
  import static it.unibz.inf.ontop.DependencyTestDBMetadata.PK_TABLE1_AR1;
  import static it.unibz.inf.ontop.OptimizationTestingTools.*;
  import static org.junit.Assert.assertFalse;
  import static org.junit.Assert.assertTrue;
  
  /**
   * TODO: enrich
   */
  public class IsDistinctTest {
  
      public static final RelationDefinition NULLABLE_UC_TABLE1_AR1;
      public static final RelationDefinition NULLABLE_UC_TABLE2_AR2;
  
  
      static {
          OfflineMetadataProviderBuilder3 builder = createMetadataProviderBuilder();
          NULLABLE_UC_TABLE1_AR1 = builder.createRelationWithUC( 1, 1, true);
          NULLABLE_UC_TABLE2_AR2 = builder.createRelationWithUC( 2, 2, true);
      }
  
      @Test
      public void testExtensionalDataNodeNullableUC1() {
          ExtensionalDataNode tree = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE1_AR1, ImmutableMap.of(0, A));
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testExtensionalDataNodeNullableUC2() {
          ExtensionalDataNode tree = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A));
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testExtensionalDataNodeNullableUC3() {
          ExtensionalDataNode tree = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(1, A));
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testExtensionalDataNodeNullableUC4() {
          ExtensionalDataNode tree = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, A));
          assertTrue(tree.isDistinct());
      }
  
      @Test
      public void testExtensionalDataNodeNullableUC5() {
          ExtensionalDataNode tree = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testFilterNullableUC1() {
          ExtensionalDataNode dataNode = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE1_AR1, ImmutableMap.of(0, A));
  
          UnaryIQTree tree = IQ_FACTORY.createUnaryIQTree(
                  IQ_FACTORY.createFilterNode(TERM_FACTORY.getDBIsNotNull(A)),
                  dataNode);
  
          assertTrue(tree.isDistinct());
      }
  
      @Test
      public void testFilterNullableUC2() {
          ExtensionalDataNode dataNode = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
  
          UnaryIQTree tree = IQ_FACTORY.createUnaryIQTree(
                  IQ_FACTORY.createFilterNode(TERM_FACTORY.getDBIsNotNull(B)),
                  dataNode);
  
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testInnerJoinNullableUC1() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, B));
  
          IQTree tree = IQ_FACTORY.createNaryIQTree(
                  IQ_FACTORY.createInnerJoinNode(TERM_FACTORY.getDBIsNotNull(A)),
                  ImmutableList.of(dataNode1, dataNode2));
  
          assertTrue(tree.isDistinct());
      }
  
      @Test
      public void testInnerJoinNullableUC2() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, A));
  
          IQTree tree = IQ_FACTORY.createNaryIQTree(
                  IQ_FACTORY.createInnerJoinNode(),
                  ImmutableList.of(dataNode1, dataNode2));
  
          assertTrue(tree.isDistinct());
      }
  
      @Test
      public void testInnerJoinNullableUC3() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, B));
  
          IQTree tree = IQ_FACTORY.createNaryIQTree(
                  IQ_FACTORY.createInnerJoinNode(),
                  ImmutableList.of(dataNode1, dataNode2));
  
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testLeftJoinNullableUC1() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, B));
  
          IQTree tree = IQ_FACTORY.createBinaryNonCommutativeIQTree(
                  IQ_FACTORY.createLeftJoinNode(TERM_FACTORY.getDBIsNotNull(A)),
                  dataNode1, dataNode2);
  
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testLeftJoinNullableUC2() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, A));
  
          IQTree tree = IQ_FACTORY.createBinaryNonCommutativeIQTree(
                  IQ_FACTORY.createLeftJoinNode(),
                  dataNode1, dataNode2);
  
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testLeftJoinNullableUC3() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, B));
  
          IQTree tree = IQ_FACTORY.createBinaryNonCommutativeIQTree(
                  IQ_FACTORY.createLeftJoinNode(),
                  dataNode1, dataNode2);
  
          assertFalse(tree.isDistinct());
      }
  
      @Test
      public void testLeftJoinNullableUC4() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A, 1, B));
  
          IQTree tree = IQ_FACTORY.createBinaryNonCommutativeIQTree(
                  IQ_FACTORY.createLeftJoinNode(TERM_FACTORY.getDBIsNotNull(A)),
                  dataNode1, dataNode2);
  
          assertTrue(tree.isDistinct());
      }
  
      @Test
      public void testLeftJoinNullableUC5() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, B));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A));
  
          IQTree tree = IQ_FACTORY.createBinaryNonCommutativeIQTree(
                  IQ_FACTORY.createLeftJoinNode(TERM_FACTORY.getDBIsNotNull(A)),
                  dataNode1, dataNode2);
  
          assertTrue(tree.isDistinct());
      }
  
      @Test
      public void testLeftJoinNullableUC6() {
          ExtensionalDataNode dataNode1 = IQ_FACTORY.createExtensionalDataNode(PK_TABLE1_AR1,
                  ImmutableMap.of(0, A));
          ExtensionalDataNode dataNode2 = IQ_FACTORY.createExtensionalDataNode(NULLABLE_UC_TABLE2_AR2, ImmutableMap.of(0, A));
  
          IQTree tree = IQ_FACTORY.createBinaryNonCommutativeIQTree(
                  IQ_FACTORY.createLeftJoinNode(),
                  dataNode1, dataNode2);
  
          assertTrue(tree.isDistinct());
      }
  
      @Test
      public void testUnionConstants() {
          IQTree tree = IQ_FACTORY.createNaryIQTree(
                  IQ_FACTORY.createUnionNode(ImmutableSet.of(X)),
                  ImmutableList.of(
                          IQ_FACTORY.createUnaryIQTree(
                                  IQ_FACTORY.createConstructionNode(ImmutableSet.of(X),
                                          SUBSTITUTION_FACTORY.getSubstitution(ImmutableMap.of(X, ONE))),
                                  IQ_FACTORY.createTrueNode()),
                          IQ_FACTORY.createUnaryIQTree(
                                  IQ_FACTORY.createConstructionNode(ImmutableSet.of(X),
                                          SUBSTITUTION_FACTORY.getSubstitution(ImmutableMap.of(X, TWO))),
                                  IQ_FACTORY.createTrueNode())));
  
          assertTrue(tree.isDistinct());
      }
  }
  