From 1a602429e86680d82a5ab8064386e66a1126cf36 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Sun, 20 Mar 2016 10:03:51 +0100 Subject: Prolog: add triggers for sum/len hints --- prolog/problems/lists_advanced/len_2/common.py | 40 ++++++++++++++++++++++++-- prolog/problems/lists_advanced/len_2/sl.py | 24 ++++++++++++++++ prolog/problems/lists_advanced/sum_2/common.py | 40 ++++++++++++++++++++++++-- prolog/problems/lists_advanced/sum_2/sl.py | 24 ++++++++++++++++ 4 files changed, 122 insertions(+), 6 deletions(-) (limited to 'prolog') diff --git a/prolog/problems/lists_advanced/len_2/common.py b/prolog/problems/lists_advanced/len_2/common.py index 501a4f8..6caea98 100644 --- a/prolog/problems/lists_advanced/len_2/common.py +++ b/prolog/problems/lists_advanced/len_2/common.py @@ -24,6 +24,12 @@ hint_type = { 'base_case': Hint('base_case'), 'recursive_case': Hint('recursive_case'), 'timeout': Hint('timeout'), + 'arbitrary_base_case': Hint('arbitrary_base_case'), + 'args_not_instantiated': Hint('arbitrary_base_case'), + '=_instead_of_is': Hint('=_instead_of_is'), + '+H_instead_of_+1': Hint('+H_instead_of_+1'), + 'forcing_result_onto_recursion': Hint('forcing_result_onto_recursion'), + 'same_var_on_both_sides_of_is': Hint('same_var_on_both_sides_of_is'), } test_cases = [ @@ -68,13 +74,41 @@ def hint(code, aux_code): return [{'id': 'eq_instead_of_equ_markup', 'start': m[0], 'end': m[1]} for m in marks] + \ [{'id': 'eq_instead_of_equ'}] + # target predicate seems to always be false + if not prolog.engine.ask_truthTO(engine_id, 'len(_, _)'): + return [{'id': 'predicate_always_false'}] + + # arbitrary base case: len([], _) + if prolog.engine.ask_truthTO(engine_id, 'len([], q), len([], child(Q, q))'): + return [{'id': 'arbitrary_base_case'}] + # missing/failed base case if not prolog.engine.ask_truthTO(engine_id, 'len([], 0)'): return [{'id': 'base_case'}] - # target predicate seems to always be false - if not prolog.engine.ask_truthTO(engine_id, 'len(_, _)'): - return [{'id': 'predicate_always_false'}] + # arguments not instantiated + reply, output = prolog.engine.ask(engine_id, 'len([a, b, c], Len)', timeout=1) + if reply.get('code') == 'instantiation_error': + return [{'id': 'args_not_instantiated'}] + + # = instead of is + if prolog.engine.ask_truthTO(engine_id, 'len([qa, qb, qc, qd], _+_)'): + return [{'id': '=_instead_of_is'}] + + # +H instead of +1 + if prolog.engine.ask_truthTO(engine_id, 'len([1, 3, 9, 27, 81], 121)'): + return [{'id': '+H_instead_of_+1'}] + + # forcing result onto recursion + if prolog.engine.ask_truthTO(engine_id, '''\ + asserta(len([9, 81], 2+1)), len([27, 9, 81], 2), retract(len([9, 81], 2+1)) + ; + asserta(len([9, 81], 1+2)), len([27, 9, 81], 2), retract(len([9, 81], 1+2))'''): + return [{'id': 'forcing_result_onto_recursion'}] + + # same var on both sides of is + if prolog.engine.ask_truth(engine_id, 'len([], 0), \+ len([a, b, c], _)'): + return [{'id': 'same_var_on_both_sides_of_is'}] # base case works, the recursive doesn't (but it doesn't timeout) # this may be left as the last, most generic hint diff --git a/prolog/problems/lists_advanced/len_2/sl.py b/prolog/problems/lists_advanced/len_2/sl.py index 82c9d4b..e13ac3d 100644 --- a/prolog/problems/lists_advanced/len_2/sl.py +++ b/prolog/problems/lists_advanced/len_2/sl.py @@ -41,5 +41,29 @@ da je X hkrati starš in sestra od Y ali kaj podobno z 'timeout': '''\

Je morda na delu potencialno neskončna rekurzija? Kako se bo ustavila?

Morda pa je kriv tudi manjkajoč, neustrezen ali preprosto nekompatibilen (s splošnim primerom) robni pogoj?

+''', + + 'arbitrary_base_case': '''\ +

arbitrary_base_case

+''', + + 'args_not_instantiated': '''\ +

args_not_instantiated

+''', + + '=_instead_of_is': '''\ +

=_instead_of_is

+''', + + '+H_instead_of_+1': '''\ +

+H_instead_of_+1

+''', + + 'forcing_result_onto_recursion': '''\ +

forcing_result_onto_recursion

+''', + + 'same_var_on_both_sides_of_is': '''\ +

same_var_on_both_sides_of_is

''', } diff --git a/prolog/problems/lists_advanced/sum_2/common.py b/prolog/problems/lists_advanced/sum_2/common.py index b3fa3bf..7d660d5 100644 --- a/prolog/problems/lists_advanced/sum_2/common.py +++ b/prolog/problems/lists_advanced/sum_2/common.py @@ -24,6 +24,12 @@ hint_type = { 'base_case': Hint('base_case'), 'recursive_case': Hint('recursive_case'), 'timeout': Hint('timeout'), + 'arbitrary_base_case': Hint('arbitrary_base_case'), + 'args_not_instantiated': Hint('arbitrary_base_case'), + '=_instead_of_is': Hint('=_instead_of_is'), + '+1_instead_of_+H': Hint('+1_instead_of_+H'), + 'forcing_result_onto_recursion': Hint('forcing_result_onto_recursion'), + 'same_var_on_both_sides_of_is': Hint('same_var_on_both_sides_of_is'), } test_cases = [ @@ -68,13 +74,41 @@ def hint(code, aux_code): return [{'id': 'eq_instead_of_equ_markup', 'start': m[0], 'end': m[1]} for m in marks] + \ [{'id': 'eq_instead_of_equ'}] + # target predicate seems to always be false + if not prolog.engine.ask_truthTO(engine_id, 'sum(_, _)'): + return [{'id': 'predicate_always_false'}] + + # arbitrary base case: len([], _) + if prolog.engine.ask_truthTO(engine_id, 'sum([], q), sum([], child(Q, q))'): + return [{'id': 'arbitrary_base_case'}] + # missing/failed base case if not prolog.engine.ask_truthTO(engine_id, 'sum([], 0)'): return [{'id': 'base_case'}] - # target predicate seems to always be false - if not prolog.engine.ask_truthTO(engine_id, 'sum(_, _)'): - return [{'id': 'predicate_always_false'}] + # arguments not instantiated + reply, output = prolog.engine.ask(engine_id, 'sum([8, 12, -3], Sum)', timeout=1) + if reply.get('code') == 'instantiation_error': + return [{'id': 'args_not_instantiated'}] + + # = instead of is + if prolog.engine.ask_truthTO(engine_id, 'sum([1, 3, 9, 27, 81], _+_)'): + return [{'id': '=_instead_of_is'}] + + # +H instead of +1 + if prolog.engine.ask_truthTO(engine_id, 'sum([1, 3, 9, 27, 81], 5)'): + return [{'id': '+H_instead_of_+1'}] + + # forcing result onto recursion + if prolog.engine.ask_truthTO(engine_id, '''\ + asserta(sum([9, 81], 90+27)), sum([27, 9, 81], 90), retract(sum([9, 81], 90+27)) + ; + asserta(sum([9, 81], 27+90)), sum([27, 9, 81], 90), retract(sum([9, 81], 27+90))'''): + return [{'id': 'forcing_result_onto_recursion'}] + + # same var on both sides of is + if prolog.engine.ask_truth(engine_id, 'sum([], 0), \+ sum([1, 3, 9], _)'): + return [{'id': 'same_var_on_both_sides_of_is'}] # base case works, the recursive doesn't (but it doesn't timeout) # this may be left as the last, most generic hint diff --git a/prolog/problems/lists_advanced/sum_2/sl.py b/prolog/problems/lists_advanced/sum_2/sl.py index f1094d3..a54c402 100644 --- a/prolog/problems/lists_advanced/sum_2/sl.py +++ b/prolog/problems/lists_advanced/sum_2/sl.py @@ -41,5 +41,29 @@ da je X hkrati starš in sestra od Y ali kaj podobno z 'timeout': '''\

Je morda na delu potencialno neskončna rekurzija? Kako se bo ustavila?

Morda pa je kriv tudi manjkajoč, neustrezen ali preprosto nekompatibilen (s splošnim primerom) robni pogoj?

+''', + + 'arbitrary_base_case': '''\ +

arbitrary_base_case

+''', + + 'args_not_instantiated': '''\ +

args_not_instantiated

+''', + + '=_instead_of_is': '''\ +

=_instead_of_is

+''', + + '+H_instead_of_+1': '''\ +

+H_instead_of_+1

+''', + + 'forcing_result_onto_recursion': '''\ +

forcing_result_onto_recursion

+''', + + 'same_var_on_both_sides_of_is': '''\ +

same_var_on_both_sides_of_is

''', } -- cgit v1.2.1