Skip to content

Commit

Permalink
Use yield to optimize opt_models.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBelcour committed Oct 14, 2019
1 parent f8c4cfb commit 2679d26
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
9 changes: 9 additions & 0 deletions clyngor/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,12 @@ def test_answer_set_to_str_complex():
print('NORMAL :', models)
answerset = models[0]
assert ' '.join(generate_answer_set_as_str(answerset, atom_end='.')) == asp

def test_with_opts():
ASP = r"""
1 { a; b }.
#minimize { 2,t:a; 2,t:b; 1,u:b; 2,v:b }.
"""
answer = solve(inline=ASP, options='--opt-mode=optN')
found = list(utils.opt_models_from_clyngor_answers(answer))
assert found == [frozenset({('a', ())})]
25 changes: 12 additions & 13 deletions clyngor/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ def wrapped(*args, **kwargs):
return wrapper


def opt_models_from_clyngor_answers(answers:iter, *, repeated_optimal:bool=True):
"""Return tuple of optimal models found by clingor.solve from answers.
def opt_models_from_clyngor_answers(answers:iter):
"""Return generator of optimal models found by clingor.solve from answers.
This function assumes that:
Expand All @@ -260,15 +260,14 @@ def opt_models_from_clyngor_answers(answers:iter, *, repeated_optimal:bool=True)
therefore there is no need to verify that a model B succeeding a model A
is better if they have different optimization value.
- that the first found optimal model will be given a second time, unless option repeated_optimal is set to False.
"""
current_opt, models = None, []
for model, opt in answers.with_optimization:
if opt != current_opt:
current_opt, models = opt, []
if not repeated_optimal: # the first optimal model will not be given again as last model
models.append(model)
else:
models.append(model)
return tuple(models)
first_seen = False
optimal_reached = False
for model, opt, optimum, answer_number in answers.with_answer_number:
if optimal_reached:
yield model
if answer_number == 1 and not first_seen:
first_seen = True
elif answer_number == 1:
optimal_reached = True
yield model

0 comments on commit 2679d26

Please sign in to comment.