Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Generating Data for Referential Integrity

Help
GMK
2012-02-15
2013-05-30
  • GMK
    GMK
    2012-02-15

    Hello Everyone,

      I am interested in using JaCoP to generate data that will
      fulfill the schema constraints associated with a relational
      database.  Many I am able to implement programs that
      will generate data for several types of constraints, already.

      However, I am having trouble with the referential integrity
      constraint and I am hoping that you can provide assistance.

      Basically, there is a StudentResidence variable that
      references the ResidenceName variable.  As such, this
      means that whatever values JaCoP generates for
      ResidenceName define the possible values for StudentResidence.

      Here is some source code excerpted from my current system:

      // Declare the ResidenceName
    IntVar ResidenceName = new IntVar;
    for(int i = 0; i < 3; i++)
        {

    SmallDenseDomain values = new SmallDenseDomain(1,5);
    ResidenceName_ =
        new IntVar(store, values);

    variables.add(ResidenceName);

        }

           // Declare the StudentId and StudentResidence
    for(int i = 0; i < 2; i++)
        {

    SmallDenseDomain values = new SmallDenseDomain(1,5);
    StudentResidence =
        new IntVar(store, values);

    variables.add(StudentResidence);

        }

      One tactic that I tried is to use the Among command like:

      IntVar count = new IntVar(store, "count", 2,2);
    IntervalDomain values = new IntervalDomain(1,5);
    store.impose(new Among(StudentResidence,
           values, count));

      However, this will allow StudentResidence to take on
      values that do not occur in Residence name, especially
      if I use an IndomainRandom.  Here is sample output:

      Time-out 1s
    Depth First Search DFS0
    JaCoP.search.InputOrderSelect@b58e73No of solutions : 79964
    Last Solution : [_0=58, _1=84, _2=64, _3=5, _4=1, _5=3, _6=68, _7=1, _8=52, _9=4
    ]
    Nodes : 79973
    Decisions : 79973
    Wrong Decisions : 0
    Backtracks : 79973
    Max Depth : 144

    Solution ResidenceCapacity: _0 = 58, _1 = 84, _2 = 64
    Solution ResidenceName: _3 = 5, _4 = 1, _5 = 3
    Solution StudentId: _6 = 68, _8 = 52
    Solution StudentResidence: _7 = 1, _9 = 4

    All solutions:

    Number of Solutions: 79964
    58 84 64 5 1 3 63 1 99 2
    58 84 64 5 1 3 63 1 99 3
    58 84 64 5 1 3 63 1 99 5
    58 84 64 5 1 3 63 1 99 4

    Note that there is a 2 in the solution in the first row
    and this should not be allowed because it was not
    selected by the data generator.

    After reading the documentation, it seems that I really want to use an
    AmongVar constraint.  However, when I tried this, the system fails
    at execution due to a ClassCastException.  I have tried multiple
    versions with an AmongVar and they all raise different types of
    Exceptions that normally look something like:

    IntVar count = new IntVar(store, "count", 2,2);
    IntervalDomain values = new IntervalDomain(1,5);
    store.impose(new AmongVar(StudentResidence,
           ResidenceName, count));

    Exception in thread "main" java.lang.ClassCastException: JaCoP.core.SmallDenseDomain cannot be cast to JaCoP.core.IntervalDomain
    at JaCoP.constraints.AmongVar.consistency(AmongVar.java:589)
    at JaCoP.core.Store.consistency(Store.java:640)
    at JaCoP.search.DepthFirstSearch.labeling(DepthFirstSearch.java:941)
    at dbatdg.StudentResidenceSatisfy.main(StudentResidenceSatisfy.java:193)

    I also tried a large or constraint that basically said that StudentResidence could be
    equal to ResidenceName or  or  (and then the same for StudentResidence).
    However, this causes JaCoP to return no results.  I can enforce smaller constraints
    on some of the rows of StudentResidence and ResidenceName, but these are not
    general and thus do not fully adhere to the spirit of referential integrity.

    So, thank you for implementing this powerful library!  If possible, can you please make
    some suggestions as to how I can generate data that will adhere to the referential
    integrity constraint for a relational database system?  Thank you in advance!

    _

     
  • kris
    kris
    2012-02-15

    Hi!

    If I understand your problem correctly, you want to define constraints between StudentResidence variable and ResidenceName variable. The easiest way to do so is to use ExtensionalSupport* constraint. It basically can define any type of relations between n variables.

    Regarding the problem with AmongVar, try to use the following definition for count

    IntVar count = new IntVar(store, "count", new IntervalDomain(2,2));

    This is a bug in AmongVar but you might omit it by using the definition above.

    Best regards,
    /Kris

     
  • Hi,

    This ClassCast Exception you get is a problem with AmongVar implementation. It is not trivial to fix it as it requires some decision how to change interfaces and consistency AmongVar to remove dependency on efficient implementation for some internal aspects of IntervalDomain.

    A simple approach to avoid this problem is use IntervalDomain for variables used in AmongVar.

    However, as Kris already pointed out it looks like ExtensionalSupport* constraints may be appropriate for you too.

    best regards,
    Radek