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