def queryLogical()

in data/question-gen/engine.py [0:0]


    def queryLogical(self, ent):
        qns = []
        rooms_done = set()

        # the entities queue contains a list of object entities
        for i in ent['elements']:
            # ignore objects with (1) multiple and (2) no room names
            if len(i.rooms[0].name) > 1:
                if self.debug == True:
                    print(
                        'exception in queryLogical. room has multiple names.',
                        i.rooms[0].name)
                continue
            elif i.rooms[0].name == []:
                if self.debug == True:
                    print('exception in queryLogical. room has no name.',
                          i.name, i.rooms[0].name)
                continue

            if i.rooms[0].name[0] in rooms_done: continue
            # get list of all objects present in the same as room as the current object
            # note that as we iterate throgh the ent queue, all the objects in the same room
            # will generate identical list -- so we save the rooms processed in the room_done set

            # For example : if the first obj is a bed inside a bedroom, and this bedroom has
            # a total of 5 objects= : ['chair', 'bed', 'chair', 'dressing_table', 'curtains']
            # Then, whenever any of these objects is encountered in the loop (for i in ent['elements'])
            # we will end up generating the same list as shown
            local_list = [(x, x.name) for x in ent['elements']
                          if len(x.rooms[0].name) == 1
                          and x.rooms[0].name[0] == i.rooms[0].name[0]]
            local_objects_list_ = [obj for (obj, _) in local_list]
            local_object_names_list = [name for (_, name) in local_list]

            # get list of objects which are not present in the room where i resides.
            # this list is also pruned based on frequency
            # again, this list will be identical for all objects in the same room
            objs_not_present = [
                x[0] for x in self.global_obj_by_room[i.rooms[0].name[0]]
                if x[0] not in local_object_names_list
            ]

            both_present, both_absent, only_one_present = [], [], []
            # print ("Room : %s" % i.rooms[0].name)

            # populate objects for yes answer questions
            for i_idx in range(len(local_object_names_list)):
                for j_idx in range(i_idx + 1, len(local_object_names_list)):
                    if local_object_names_list[
                            i_idx] == local_object_names_list[j_idx]:
                        continue
                    both_present.append((local_object_names_list[i_idx],
                                         local_object_names_list[j_idx]))

            # populate objects for no answer questions -- part 1
            for i_idx in range(len(objs_not_present)):
                for j_idx in range(i_idx + 1, len(objs_not_present)):
                    if objs_not_present[i_idx] == objs_not_present[j_idx]:
                        continue
                    both_absent.append((objs_not_present[i_idx],
                                        objs_not_present[j_idx]))

            # populate objects for no answer questions -- part 2
            for obj1 in local_object_names_list:
                for obj2 in objs_not_present:
                    only_one_present.append((obj1, obj2))

            # generate a question for each object pairs in the 3 lists
            shuffle(both_present)
            shuffle(both_absent)
            shuffle(only_one_present)
            num_yes = num_no = len(both_present)
            only_one_present, both_absent = only_one_present[:int(
                num_no - num_no / 2)], both_absent[:int(num_no / 2)]

            for (obj1, obj2) in both_present:
                obj1_entity, obj2_entity = objectEntity(obj1, {},
                                                        {}), objectEntity(
                                                            obj2, {}, {})
                obj1_entity.rooms.append(i.rooms[0])
                qns.append(
                    self.q_obj_builder('exist_logic',
                                       [(obj1_entity, obj2_entity)], 'yes',
                                       'exist_logical_positive'))
                qns.append(
                    self.q_obj_builder('exist_logic',
                                       [(obj1_entity, obj2_entity)], 'yes',
                                       'exist_logical_or_positive_1'))
            for (obj1, obj2) in both_absent:
                obj1_entity, obj2_entity = objectEntity(obj1, {},
                                                        {}), objectEntity(
                                                            obj2, {}, {})
                obj1_entity.rooms.append(
                    i.rooms[0]
                )  # this is not technically correct, just so that q_string_builder works
                qns.append(
                    self.q_obj_builder('exist_logic',
                                       [(obj1_entity, obj2_entity)], 'no',
                                       'exist_logical_negative_1'))
                qns.append(
                    self.q_obj_builder('exist_logic',
                                       [(obj1_entity, obj2_entity)], 'no',
                                       'exist_logical_or_negative'))

            for (obj1, obj2) in only_one_present:
                obj1_entity, obj2_entity = objectEntity(obj1, {},
                                                        {}), objectEntity(
                                                            obj2, {}, {})
                obj1_entity.rooms.append(i.rooms[0])
                qns.append(
                    self.q_obj_builder('exist_logic',
                                       [(obj1_entity, obj2_entity)], 'no',
                                       'exist_logical_negative_2'))
                qns.append(
                    self.q_obj_builder('exist_logic',
                                       [(obj1_entity, obj2_entity)], 'yes',
                                       'exist_logical_or_positive_2'))

            # mark room as done
            rooms_done.add(i.rooms[0].name[0])

        return qns