Skip to content

Commit

Permalink
Fix cases where user opinions contain statements that do not occur in…
Browse files Browse the repository at this point in the history
… arguments
  • Loading branch information
Daniel Neugebauer committed Mar 7, 2019
1 parent 484de5c commit baede64
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 6 deletions.
6 changes: 4 additions & 2 deletions dabasco/adf/import_strass.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ def import_adf(dbas_graph, opinion, opinion_strict):
adf = ADF()

# Get accepted/rejected statements from opinion
user_accepted_statements = opinion.get_accepted_statements() if opinion else []
user_rejected_statements = opinion.get_rejected_statements() if opinion else []
user_accepted_statements = opinion.get_accepted_statements().intersection(dbas_graph.statements)\
if opinion else set()
user_rejected_statements = opinion.get_rejected_statements().intersection(dbas_graph.statements)\
if opinion else set()

# Setup statement acceptance functions
for statement in dbas_graph.statements:
Expand Down
99 changes: 99 additions & 0 deletions dabasco/adf/tests/test_import_strass.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,105 @@ def test_discussion3_objective(self):

self.assertTrue(adf_reference.is_equivalent_to(adf_result))

def test_discussion2_user99_defeasible(self):
discussion_id = 2
user_id = 99
strict_opinion = False

dbas_discussion_json = {
"inferences": [
{"conclusion": 1, "id": 1, "is_supportive": True, "premises": [2]},
{"conclusion": 1, "id": 2, "is_supportive": False, "premises": [3]},
{"conclusion": 2, "id": 3, "is_supportive": False, "premises": [4]}
],
"nodes": [1, 2, 3, 4, 5],
"undercuts": [
{"conclusion": 2, "id": 4, "premises": [5]}
]
}
dbas_user_json = {
"accepted_statements_via_click": [3, 4, 99],
"marked_arguments": [],
"marked_statements": [],
"rejected_arguments": [],
"rejected_statements_via_click": [5, 999],
}

dbas_discussion = import_dbas_graph(discussion_id=discussion_id, graph_export=dbas_discussion_json)
dbas_user = import_dbas_user(discussion_id=discussion_id, user_id=user_id, user_export=dbas_user_json)
adf_result = import_adf(dbas_discussion, dbas_user, strict_opinion)

adf_reference = ADF()

# D-BAS Statements
adf_reference.add_statement('s1', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ns1')),
ADFNode(ADFNode.OR, ADFNode(ADFNode.LEAF, 'i1'))
]))
adf_reference.add_statement('ns1', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 's1')),
ADFNode(ADFNode.OR, ADFNode(ADFNode.LEAF, 'i2'))
]))
adf_reference.add_statement('s2', ADFNode(ADFNode.LEAF, ADFNode.CONSTANT_FALSE))
adf_reference.add_statement('ns2', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 's2')),
ADFNode(ADFNode.OR, ADFNode(ADFNode.LEAF, 'i3'))
]))
adf_reference.add_statement('s3', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ns3')),
ADFNode(ADFNode.OR, ADFNode(ADFNode.LEAF, 'ua3'))
]))
adf_reference.add_statement('ns3', ADFNode(ADFNode.LEAF, ADFNode.CONSTANT_FALSE))
adf_reference.add_statement('s4', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ns4')),
ADFNode(ADFNode.OR, ADFNode(ADFNode.LEAF, 'ua4'))
]))
adf_reference.add_statement('ns4', ADFNode(ADFNode.LEAF, ADFNode.CONSTANT_FALSE))
adf_reference.add_statement('s5', ADFNode(ADFNode.LEAF, ADFNode.CONSTANT_FALSE))
adf_reference.add_statement('ns5', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 's5')),
ADFNode(ADFNode.OR, ADFNode(ADFNode.LEAF, 'ur5'))
]))

# User opinion
adf_reference.add_statement('ua3', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ns3')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'nua3'))]))
adf_reference.add_statement('nua3', ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ua3')))
adf_reference.add_statement('ua4', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ns4')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'nua4'))]))
adf_reference.add_statement('nua4', ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ua4')))
adf_reference.add_statement('ur5', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 's5')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'nur5'))]))
adf_reference.add_statement('nur5', ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ur5')))

# D-BAS Inferences
adf_reference.add_statement('i1', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ns1')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ni1')),
ADFNode(ADFNode.LEAF, 's2')]))
adf_reference.add_statement('ni1', ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'i1')))
adf_reference.add_statement('i2', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 's1')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ni2')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'i4')),
ADFNode(ADFNode.LEAF, 's3')]))
adf_reference.add_statement('ni2', ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'i2')))
adf_reference.add_statement('i3', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 's2')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ni3')),
ADFNode(ADFNode.LEAF, 's4')]))
adf_reference.add_statement('ni3', ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'i3')))
adf_reference.add_statement('i4', ADFNode(ADFNode.AND, [
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'i2')),
ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'ni4')),
ADFNode(ADFNode.LEAF, 's5')]))
adf_reference.add_statement('ni4', ADFNode(ADFNode.NOT, ADFNode(ADFNode.LEAF, 'i4')))

self.assertTrue(adf_reference.is_equivalent_to(adf_result))


if __name__ == '__main__':
unittest.main()
4 changes: 2 additions & 2 deletions dabasco/af/import_wyner.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def import_af_wyner(dbas_graph, opinion, opinion_strict):
user_rejected_statements = set()
user_accepted_statements = set()
if opinion:
user_rejected_statements = opinion.get_rejected_statements()
user_accepted_statements = opinion.get_accepted_statements()
user_rejected_statements = opinion.get_rejected_statements().intersection(dbas_graph.statements)
user_accepted_statements = opinion.get_accepted_statements().intersection(dbas_graph.statements)

# Add two arguments for each statement
for statement in dbas_graph.statements:
Expand Down
91 changes: 91 additions & 0 deletions dabasco/af/tests/test_af_import_wyner.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,97 @@ def test_discussion2_user3_strict_opinion(self):

self.assertTrue(af_reference.is_equivalent_to(af_result))

def test_discussion2_user99_weak_opinion(self):
discussion_id = 2
user_id = 99
assumptions_strict = False

dbas_discussion_json = {
"inferences": [
{"conclusion": 1, "id": 1, "is_supportive": True, "premises": [2]},
{"conclusion": 1, "id": 2, "is_supportive": False, "premises": [3]},
{"conclusion": 2, "id": 3, "is_supportive": False, "premises": [4]}
],
"nodes": [1, 2, 3, 4, 5],
"undercuts": [
{"conclusion": 2, "id": 4, "premises": [5]}
]
}
dbas_user_json = {
"accepted_statements_via_click": [3, 4, 99],
"marked_arguments": [],
"marked_statements": [],
"rejected_arguments": [],
"rejected_statements_via_click": [5, 999],
}

dbas_discussion = import_dbas_graph(discussion_id=discussion_id, graph_export=dbas_discussion_json)
dbas_user = import_dbas_user(discussion_id=discussion_id, user_id=user_id, user_export=dbas_user_json)
af_result = import_af_wyner(dbas_discussion, opinion=dbas_user, opinion_strict=assumptions_strict)

af_reference = AF(17)
arg_1 = af_result.get_argument_for_name(LITERAL_PREFIX_STATEMENT + '1')
arg_neg1 = af_result.get_argument_for_name(LITERAL_PREFIX_NOT + LITERAL_PREFIX_STATEMENT + '1')
arg_2 = af_result.get_argument_for_name(LITERAL_PREFIX_STATEMENT + '2')
arg_neg2 = af_result.get_argument_for_name(LITERAL_PREFIX_NOT + LITERAL_PREFIX_STATEMENT + '2')
arg_3 = af_result.get_argument_for_name(LITERAL_PREFIX_STATEMENT + '3')
arg_neg3 = af_result.get_argument_for_name(LITERAL_PREFIX_NOT + LITERAL_PREFIX_STATEMENT + '3')
arg_4 = af_result.get_argument_for_name(LITERAL_PREFIX_STATEMENT + '4')
arg_neg4 = af_result.get_argument_for_name(LITERAL_PREFIX_NOT + LITERAL_PREFIX_STATEMENT + '4')
arg_5 = af_result.get_argument_for_name(LITERAL_PREFIX_STATEMENT + '5')
arg_neg5 = af_result.get_argument_for_name(LITERAL_PREFIX_NOT + LITERAL_PREFIX_STATEMENT + '5')
arg_r1 = af_result.get_argument_for_name(LITERAL_PREFIX_INFERENCE_RULE + '1')
arg_r2 = af_result.get_argument_for_name(LITERAL_PREFIX_INFERENCE_RULE + '2')
arg_r3 = af_result.get_argument_for_name(LITERAL_PREFIX_INFERENCE_RULE + '3')
arg_r4 = af_result.get_argument_for_name(LITERAL_PREFIX_INFERENCE_RULE + '4')
arg_u3 = af_result.get_argument_for_name(DUMMY_LITERAL_NAME_OPINION + '_' + '3')
arg_u4 = af_result.get_argument_for_name(DUMMY_LITERAL_NAME_OPINION + '_' + '4')
arg_uneg5 = af_result.get_argument_for_name(DUMMY_LITERAL_NAME_OPINION + '_' + LITERAL_PREFIX_NOT + '5')

# Attacks between statement args
af_reference.set_attack(arg_1, arg_neg1, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg1, arg_1, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_2, arg_neg2, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg2, arg_2, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_3, arg_neg3, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg3, arg_3, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_4, arg_neg4, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg4, arg_4, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_5, arg_neg5, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg5, arg_5, AF.DEFINITE_ATTACK)

# Undermining attacks by negated premises
af_reference.set_attack(arg_neg2, arg_r1, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg3, arg_r2, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg4, arg_r3, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg5, arg_r4, AF.DEFINITE_ATTACK)

# Rebutting attacks between rules and negated conclusions
af_reference.set_attack(arg_r1, arg_neg1, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg1, arg_r1, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_r2, arg_1, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_1, arg_r2, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_r3, arg_2, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_2, arg_r3, AF.DEFINITE_ATTACK)

# Undercutting attacks
af_reference.set_attack(arg_r4, arg_r2, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_r2, arg_r4, AF.DEFINITE_ATTACK)

# Attacks between user opinion args and negated statements
af_reference.set_attack(arg_u3, arg_neg3, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg3, arg_u3, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_u4, arg_neg4, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_neg4, arg_u4, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_uneg5, arg_5, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_5, arg_uneg5, AF.DEFINITE_ATTACK)

# Rebutting attacks between rule arguments with conflicting conclusions
af_reference.set_attack(arg_r1, arg_r2, AF.DEFINITE_ATTACK)
af_reference.set_attack(arg_r2, arg_r1, AF.DEFINITE_ATTACK)

self.assertTrue(af_reference.is_equivalent_to(af_result))


if __name__ == '__main__':
unittest.main()
4 changes: 2 additions & 2 deletions dabasco/aspic/export_toast.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def export_toast(dbas_graph, opinion_type, opinion, assumptions_type, assumption
if opinion:
if opinion_type in [DABASCO_INPUT_KEYWORD_OPINION_WEAK, DABASCO_INPUT_KEYWORD_OPINION_STRONG]:
aspic_axioms.append(DUMMY_LITERAL_NAME_OPINION)
user_accepted_statements = opinion.get_accepted_statements()
user_rejected_statements = opinion.get_rejected_statements()
user_accepted_statements = opinion.get_accepted_statements().intersection(dbas_graph.statements)
user_rejected_statements = opinion.get_rejected_statements().intersection(dbas_graph.statements)
opinion_rule_names = []
if opinion_type == DABASCO_INPUT_KEYWORD_OPINION_STRICT:
for statement in user_accepted_statements:
Expand Down
60 changes: 60 additions & 0 deletions dabasco/aspic/tests/test_export_toast.py
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,66 @@ def test_discussion2_strict_user2_strong_assumptions_no_bias(self):
self.assertEqual(set(aspic_result["rulePrefs"]), reference_rule_prefs)
self.assertEqual(aspic_result["semantics"], semantics)

def test_discussion2_strong_user99_no_assumptions(self):
discussion_id = 2
user_id = 99
opinion_type = "strong"
assumptions_type = None
assumptions_bias = None
semantics = "preferred"

dbas_discussion_json = {
"inferences": [
{"conclusion": 1, "id": 1, "is_supportive": True, "premises": [2]},
{"conclusion": 1, "id": 2, "is_supportive": False, "premises": [3]},
{"conclusion": 2, "id": 3, "is_supportive": False, "premises": [4]}
],
"nodes": [1, 2, 3, 4, 5],
"undercuts": [
{"conclusion": 2, "id": 4, "premises": [5]}
]
}
dbas_user_json = {
"accepted_statements_via_click": [3, 4, 99],
"marked_arguments": [],
"marked_statements": [],
"rejected_arguments": [],
"rejected_statements_via_click": [5, 999],
}

dbas_discussion = import_dbas_graph(discussion_id=discussion_id, graph_export=dbas_discussion_json)
dbas_user = import_dbas_user(discussion_id=discussion_id, user_id=user_id, user_export=dbas_user_json)

aspic_result = export_toast(dbas_graph=dbas_discussion,
opinion_type=opinion_type,
opinion=dbas_user,
assumptions_type=assumptions_type,
assumptions_bias=assumptions_bias,
semantics=semantics)

reference_assumptions = set()
reference_axioms = {"opinion_dummy"}
reference_contrariness = set()
reference_kbPrefs = set()
reference_rules = {
"[ua3] opinion_dummy=>3",
"[ua4] opinion_dummy=>4",
"[ur5] opinion_dummy=>~5",
"[i1] 2=>1",
"[i2] 3=>~1",
"[i3] 4=>~2",
"[i4] 5=>~[i2]"
}
reference_rulePrefs = set()

self.assertEqual(set(aspic_result["assumptions"]), reference_assumptions)
self.assertEqual(set(aspic_result["axioms"]), reference_axioms)
self.assertEqual(set(aspic_result["contrariness"]), reference_contrariness)
self.assertEqual(set(aspic_result["kbPrefs"]), reference_kbPrefs)
self.assertEqual(set(aspic_result["rules"]), reference_rules)
self.assertEqual(set(aspic_result["rulePrefs"]), reference_rulePrefs)
self.assertEqual(aspic_result["semantics"], semantics)


if __name__ == '__main__':
unittest.main()

0 comments on commit baede64

Please sign in to comment.