From hinoglu at gmail.com Sat May 28 11:32:45 2011 From: hinoglu at gmail.com (Ozgur) Date: Sat, 28 May 2011 12:32:45 +0300 Subject: [Python-logic] How does narrowing work in fd.BinaryExpression? Message-ID: <20110528123245.df1d7094.hinoglu@gmail.com> Hi, I'm having a hard time figuring out how narrowing works in fd.BinaryExpression. line 284 in fd.py: ------------------------- try: # iterate for all values for val1 in values1: kwargs[var1] = val1 for val2 in values2: kwargs[var2] = val2 if val1 in keep1 and val2 in keep2 and maybe_entailed == 0: continue if ffunc(**kwargs): keep1[val1] = 1 keep2[val2] = 1 else: maybe_entailed = 0 ---------------------------- so if we have two value lists val1= [1,2,3,4] val2=[3,4,5,6] and a function ffunc(a,b): return a != b then scenario works as this: 1 != 3 1 != 4 1 != 5 1 != 6 2 != 3 2 != 4 2 != 5 2 != 6 3 == 3 3 != 4 4 != 3 keep1: {1: 1, 2: 1, 3: 1, 4: 1} keep2: {3: 1, 4: 1, 5: 1, 6: 1} which is the same as the beginning. and will be the same next time for no value will be removed from the two domains. I'm stuck here while trying to reduce the time spent on looping the domain items (values1 * values2 times at most). Instead of using nested loops, i'm trying to implement the following algorithm: # val = (instructor, room, day, hour) d1 = defaultdict(list) d2 = defaultdict(list) # course duration in hours dur1 = variable1.duration dur2 = variable2.duration # trying to find out if any values clash on instructor and the same hours in the same day for val1 in values1: ins1, room1, day1, hour1 = val1 # first grouping the values on instructor and day d1[(ins1, day1)].append(val1) for val2 in values2: ins2 , room2, day2, hour2 = val2 key = (ins2, day2) # if values2 has possible clashing values, store them if key in d1: d2[key].append(val2) else: # in no way clashes occur with these values in values2 keep2[val2] = 1 for key in set(d1).difference(d2): for i in d1[key]: # in no way clashes occur for these values in values1 keep1[i] = 1 # checking for possible clashes # below here is implemented wrong. what i'm trying to do is to check if any clashes occur # this is where i'm stuck+confused looking at the BinaryExpression's code. if i do the same, there'll be no # narrowing. for key in d1: vals1 = d1.get(key) vals2 = d2.get(key) for val1 in vals1: ins1, room1, day1, hour1 = val1 for val2 in vals2: ins2, room2, day2, hour2 = val2 if not set(xrange(hour1, hour1 + dur1)).intersection(set(xrange(hour2, hour2 + dur2))): keep1[val1] = keep2[val2] = 1 else: maybe_entailed = 0 return maybe_entailed, keep1, keep2 so i'm a bit lost in how does it manage to narrow the domains, a little help would be very much appreciated :) thanks -- Ozgur