General (#1) - Many top relations in one transformation (#24) - Message List

Many top relations in one transformation
 unsolved

I am trying to create a transformation for sorting Sudoku in such a way that all numbers/cells in the first row is sorted in an ascending order. All values in the rest of the Sudoku need to change value accordingly. My problem is that in the first relation to set the value '1' in the first cell, i also retrieve the value from that cell to use in the rest of the puzzle. Then when I do the same for the e.g. the 8th cell, the problem is that this value might be e.g. 3 resulting in a change of the value 3 that is already in a correct position. In C# I was able to put everything in a single method and avoid this problem. Is there any way to do this cell by cell, each cell being evaluated just once?

Maybe a poor explanation of my problem, but I hope you understand.

My relations look like this:

top relation getFirstValue
{
  row1:Field;
  checkonly domain source puzzle:Puzzle
  {
  };
  checkonly domain source cell:Cell
  {
    iCellValue = row1.cells->at(1).iCellValue
  };
  enforce domain target cell:Cell
  {
    iCellValue = 1
  };
  when
  {
    row1 = puzzle.Elements->select(f : Field | f.oclIsTypeOf(Row))->first();
    --row1.cells->at(1).iCellValue <> 1;
  }
}
top relation getSecondValue
{
  row1:Field;
  checkonly domain source puzzle:Puzzle
  {
  };
  checkonly domain source cell:Cell
  {
    iCellValue = row1.cells->at(2).iCellValue
  };
  enforce domain target cell:Cell
  {
    iCellValue = 2
  };
  when
  {
    row1 = puzzle.Elements->select(f : Field | f.oclIsTypeOf(Row))->first();
    --row1.cells->at(2).iCellValue <> 2;
  }
}
  • Message #54

    I have not yet understood the sorting problem. So first, is the source model the same as the target model? May be you can explain your sorting algorithm better.

    • Message #55

      I am sorting a 9x9 sudoku if that helps.. I think I found the problem in the QVT spcification where it says that the following apply for in-line transformations:
      • A relation is re-evaluated after each enforcement-induced modification to a target pattern instance of the model.
      • A relation’s evaluation stops when all the pattern instances satisfy the relationship.

      every row, column and box (they inherit Field)  contain the numbers (in cells) 1..9 exactly once. I want to transform the values in the cells so that the cells in the first row is sorted in an ascending order. This also means that the rest of the cells in the puzzle need to change cell values like the first row. E.g. all values that were 6 should now be 1, all values that were 4 should now be 2 and so on. So I retrieve the values from the first row, and if the first row is:

      9 8 7 6 5 4 3 2 1 - I want to transform it to
      1 2 3 4 5 6 7 8 9 and thus all 9 must become 1, all 8 must become 2 and so on in the entire puzzle.

      Hope this was a better explanation :)

      • Message #56

        I do not understand your transformation: you set iCellValue to some integer value, but this does not sort the Cell instances but just modifies their attributes. Or do you only require not to sort the instances but to modify their iCellValue attributes, namely to set it to a number i when the Cell instance is the i-th referenced instance in the "Elements" reference.

        • Message #58

          You are right, it is not really "sorting", I just need to modify the values throughout the puzzle so that the first row appears sorted.
          The transformation works perfectly in the sense that the first row ends up correctly, the problem is the rest of the rows, 9 total :)

          I guess what I need is that all relations check the cells one by one, first all relations check the first cell, then the second and so on, and that they never go back to evaluate a cell that has already had its value modified.

          I'll illustrate with an example what I want. My starting model will be the left one, and after transformation I want it to look like the right one.

          2 4 3 1 -> 1 2 3 4
          1 3 4 2 -> 4 3 2 1
          3 1 2 4 -> 3 4 1 2
          4 2 1 3 -> 2 1 4 3

          I want to sort (or just reassign values really) in such a way that the first rows cell values are ascending from 1..9

          foreach cell c
          if c.value = firstcellinfirstrowvalue
          c.value = 1
          else if c.value =secondcellinfirstrowvalue
          c.value = 2
          else if c.value = thirdcellinfirstrowvalue
          c.value = 3
          else if c.value = fourthcellinfirstrowvalue
          c.value = 4


          I can sense that my explaining is horrible today :)

Attachments

No attachments created.