From 3b8f77e4ff91aa52390a7853d90adcb3cde14981 Mon Sep 17 00:00:00 2001 From: troyyyyy <49091847+troyyyyy@users.noreply.github.com> Date: Mon, 5 Dec 2022 16:33:36 +0800 Subject: [PATCH] Add zoopt option --- abducer/kb.py | 103 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/abducer/kb.py b/abducer/kb.py index 9ff7652..7ca8a25 100644 --- a/abducer/kb.py +++ b/abducer/kb.py @@ -20,6 +20,7 @@ from itertools import product, combinations import pyswip + class KBBase(ABC): def __init__(self): pass @@ -31,10 +32,20 @@ class KBBase(ABC): @abstractmethod def abduce_candidates(self): pass - + + + def address(self, address_num, pred_res, key): + new_candidates = [] + address_idx_list = list(combinations(list(range(len(pred_res))), address_num)) + + for address_idx in address_idx_list: + candidates = self.address_by_idx(pred_res, key, address_idx) + new_candidates += candidates + return new_candidates def abduction(self, pred_res, key, max_address_num, require_more_address): candidates = [] + for address_num in range(len(pred_res) + 1): if address_num == 0: if abs(self.logic_forward(pred_res) - key) <= 1e-3: @@ -106,6 +117,11 @@ class ClsKB(KBBase): + def hamming_dist(self, A, B): + B = np.array(B) + A = np.expand_dims(A, axis = 0).repeat(axis=0, repeats=(len(B))) + return np.sum(A != B, axis = 1) + def abduce_from_GKB(self, pred_res, key, max_address_num, require_more_address): if self.base == {} or len(pred_res) not in self.len_list: return [] @@ -124,28 +140,18 @@ class ClsKB(KBBase): candidates = [all_candidates[idx] for idx in idxs] return candidates, min_address_num, address_num - - def hamming_dist(self, A, B): - B = np.array(B) - A = np.expand_dims(A, axis = 0).repeat(axis=0, repeats=(len(B))) - return np.sum(A != B, axis = 1) - - def address(self, address_num, pred_res, key): - new_candidates = [] - all_address_candidate = self.all_address_candidate_dict[address_num] - address_idx_list = list(combinations(list(range(len(pred_res))), address_num)) - for address_idx in address_idx_list: - for c in all_address_candidate: - candidate = pred_res.copy() - for i, idx in enumerate(address_idx): - candidate[idx] = c[i] - if self.logic_forward(candidate) == key: - if sum(pred_res[idx] != candidate[idx] for idx in range(len(pred_res))) == address_num: - new_candidates.append(candidate) - return new_candidates - + def address_by_idx(self, pred_res, key, address_idx): + candidates = [] + abduce_c = self.all_address_candidate_dict[len(address_idx)] + for c in abduce_c: + candidate = pred_res.copy() + for i, idx in enumerate(address_idx): + candidate[idx] = c[i] + if self.logic_forward(candidate) == key: + candidates.append(candidate) + return candidates def _dict_len(self, dic): @@ -208,19 +214,32 @@ class prolog_KB(KBBase): def abduce_candidates(self, pred_res, key, max_address_num, require_more_address): return self.abduction(pred_res, key, max_address_num, require_more_address) - def address(self, address_num, pred_res, key): - new_candidates = [] - address_idx_list = list(combinations(list(range(len(pred_res))), address_num)) - for address_idx in address_idx_list: - query_string = self.get_query_string(pred_res, address_idx) - abduce_c = [list(z.values()) for z in list(self.prolog.query(query_string % key))] - for c in abduce_c: - candidate = pred_res.copy() - for i, idx in enumerate(address_idx): - candidate[idx] = c[i] - if sum(pred_res[idx] != candidate[idx] for idx in range(len(pred_res))) == address_num: - new_candidates.append(candidate) - return new_candidates + + + def address_by_idx(self, pred_res, key, address_idx, verbose=True): + candidates = [] + query_string = self.get_query_string(pred_res, address_idx) + abduce_c = [list(z.values()) for z in list(self.prolog.query(query_string % key))] + for c in abduce_c: + candidate = pred_res.copy() + for i, idx in enumerate(address_idx): + candidate[idx] = c[i] + candidates.append(candidate) + return candidates + + def address_by_idx2(self, pred_res, key, address_idx): + candidates = [] + query_string = self.get_query_string(pred_res, address_idx) + abduce_c = [list(z.values()) for z in list(self.prolog.query(query_string % key))] + # print('abduce_c:', abduce_c) + for c in abduce_c: + candidate = pred_res.copy() + for i, idx in enumerate(address_idx): + candidate[idx] = c[i] + candidates.append(candidate) + return candidates + + class add_prolog_KB(prolog_KB): @@ -240,6 +259,22 @@ class add_prolog_KB(prolog_KB): return query_string +class hed_prolog_KB(prolog_KB): + def __init__(self, pseudo_label_list = list(range(10))): + super().__init__(pseudo_label_list) + self.prolog.assertz("addition(Z1, Z2, Res) :- pseudo_label(Z1), pseudo_label(Z2), Res is Z1+Z2") + + def logic_forward(self, nums): + return list(self.prolog.query("addition(%s, %s, Res)." %(nums[0], nums[1])))[0]['Res'] + + def get_query_string(self, pred_res, address_idx): + query_string = "addition(" + for idx, i in enumerate(pred_res): + tmp = 'Z' + str(idx) + ',' if idx in address_idx else str(i) + ',' + query_string += tmp + query_string += "%s)." + return query_string + class RegKB(KBBase): def __init__(self, GKB_flag = False, X = None, Y = None):