/* Global constraint indexed_sum in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Cindexed_sum.html """ indexed_sum (ITEMS, TABLE) Purpose Given several items of the collection ITEMS (each of them having a specific fixed index as well as a weight that may be negative or positive), and a table TABLE (each entry of TABLE corresponding to a summation variable), assign each item to an entry of TABLE so that the sum of the weights of the items assigned to that entry is equal to the corresponding summation variable. Example ( , ) The indexed_sum constraint holds since the summation variables associated with each entry of TABLE are equal to the sum of the weights of the items assigned to the corresponding entry: * TABLE[1].summation=ITEMS[2].weight=6 (since TABLE[1].index=ITEMS[2].index=0), * TABLE[2].summation=0 (since TABLE[2].index=1 does not occur as a value of the index attribute of an item of ITEMS), * TABLE[3].summation=ITEMS[1].weight+ITEMS[3].weight=-4+1=-3 (since TABLE[3].index=ITEMS[1].index=ITEMS[3].index=2). """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> N = 3, NumRows = 3, % Note: I changed the item indices to 1-based Items = new_array(NumRows, 2), Items :: -10..10, Table = new_list(N), Table :: -10..10, Items = {{3, -4}, {1, 6}, {3, 1}}, % Table = [6, 0, -3], indexed_sum(Items,Table), Vars = Items.vars ++ Table, solve(Vars), println(table=Table), println(items=Items), nl, fail, nl. go => true. % % indexed_sum % indexed_sum(Items,Table) => foreach(I in 1..Items.len) Items[I,1] #>= 1, Table[I] #= sum([Items[J, 2]*(Items[J, 1] #= I) : J in 1..Table.len]) end.