/* Global constraint element_sparse in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Celement_sparse.html """ Constraint element_sparse(ITEM,TABLE,DEFAULT) Purpose ITEM.value is equal to one of the entries of the table TABLE or to the default value DEFAULT if the entry ITEM.index does not exist in TABLE. Example ( , < index-1 value-6, index-2 value-5, index-4 value-2, index-8 value-9 >,5 ) The element_sparse constraint holds since its first argument ITEM corresponds to the second item of the TABLE collection. """ Note: This is about the same as Picat's table_in/2 constraint, but adding a default value. Also, note that we are using arrays here. 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 = 4, ElementTable = new_array(N,2), ElementTable :: 0..9, Item = new_array(2), Item :: 0..9, ItemDefault :: 0..9, Result :: 0..9, % Item = {2,2}, % don't exists: result -> item_default ElementTable = {{1,2}, {2,5}, {4,2}, {8,9}}, ItemDefault #= 5, element_sparse(Item, ElementTable, ItemDefault, Result), Vars = ElementTable.vars ++ Item.vars ++ [ItemDefault,Result], solve(Vars), println(elementTable=ElementTable), println(item=Item), println(itemDefault=ItemDefault), println(result=Result), nl, fail, nl. go => true. % % There is no meaning of setting % Item[2] #= ItemDefault % when there is no item in the element table (since this is always false). % Therefore I added the last argument (item_value) as the result. % element_sparse(Item, ElementTable, ItemDefault, ItemValue) => sum([Item[1] #= ElementTable[I,1] #/\ Item[2] #= ElementTable[I,2] #/\ ItemValue #= ElementTable[I,2] : I in 1..ElementTable.len]) #>= 1 #\/ ItemValue #= ItemDefault.