Skip to content

Commit

Permalink
Merge pull request #10 from krr-up/nico/rename-profiles
Browse files Browse the repository at this point in the history
renamed COOM profiles
  • Loading branch information
nrueh authored Apr 15, 2024
2 parents 642f8c2 + bfefab2 commit 2f4af45
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 52 deletions.
16 changes: 0 additions & 16 deletions examples/tests/test_cases.coom

This file was deleted.

2 changes: 1 addition & 1 deletion src/coomsolver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
log = get_logger("main")

SOLVERS = ["clingo", "fclingo"]
COOM_PROFILES = ["kids", "city", "travel"]
COOM_PROFILES = ["core", "partonomy", "numeric", "all"]


def convert_instance(coom_file: str, output_dir: Optional[str] = None) -> str: # nocoverage
Expand Down
21 changes: 14 additions & 7 deletions src/coomsolver/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

import textwrap
from typing import Callable, Optional, Sequence
from typing import Callable, List, Optional, Sequence

from clingcon import ClingconTheory
from clingo import Control, Model, Symbol
Expand Down Expand Up @@ -40,7 +40,7 @@ class COOMApp(Application):
"""

_solver: str
_profile: str
_profile: List[str]
_output: str
_log_level: str
config: FclingoConfig
Expand All @@ -53,12 +53,19 @@ def __init__(self, log_level: str = "", solver: str = "", profile: str = "", out
Create application.
"""
self._solver = "clingo" if solver == "" else solver
self._profile = "travel" if profile == "" else profile
self._profile = self._parse_profile(profile)
self._output = "asp" if output == "" else output
self._log_level = "WARNING" if log_level == "" else log_level
self.config = FclingoConfig(MIN_INT, MAX_INT, Flag(False), Flag(False), DEF)
self._propagator = ClingconTheory()

def _parse_profile(self, profile: str) -> List[str]:
if profile in ("all", ""):
return ["core", "numeric", "partonomy"]
if profile == "core":
return ["core"]
return ["core", profile]

def parse_log_level(self, log_level: str) -> bool: # nocoverage
"""
Parse log.
Expand Down Expand Up @@ -135,16 +142,16 @@ def main(self, control: Control, files: Sequence[str]) -> None:
"""

input_files = list(files)
encoding = get_encoding(f"{self._solver}-{self._profile}.lp")
input_files.extend([encoding])
encodings = [get_encoding(f"{self._solver}-{p}.lp") for p in self._profile]
input_files.extend(encodings)

if self._solver == "clingo":
for f in input_files:
control.load(f)

control.ground()
control.solve()
elif self._solver == "fclingo": # nocoverage
elif self._solver == "fclingo":
self._propagator.register(control)
self._propagator.configure("max-int", str(self.config.max_int))
self._propagator.configure("min-int", str(self.config.min_int))
Expand All @@ -157,7 +164,7 @@ def main(self, control: Control, files: Sequence[str]) -> None:
pos = Position("<string>", 1, 1)
loc = Location(pos, pos)
for rule in hbt.rules_to_add:
bld.add(Rule(loc, rule[0], rule[1]))
bld.add(Rule(loc, rule[0], rule[1])) # nocoverage # Not sure when this is needed

control.add("base", [], THEORY)
control.ground([("base", [])])
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "clingo-city.lp".
% #include "clingo-part.lp".

{ val((Feature,(Instance,0)),V) : V = Min..Max }
:- feature(Context,Feature,"num",_,_), range(Context,Feature,Min,Max), instance(Instance,Context), not imply((Context,_),Feature,_).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "clingo-kids.lp".
% #include "clingo-core.lp".

% Always generate minimal number of objects
instance((Feature,(Instance,0..Min-1)),Structure) :- feature(Context,Feature,Structure,Min,_), structure(Structure), instance(Instance,Context).
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "fclingo-city.lp".
% #include "fclingo-part.lp".

% Assign a value to a numeric feature
&in{Min..Max} =: (Feature,(Instance,0)) :- feature(Context,Feature,"num",_,_), range(Context,Feature,Min,Max), instance(Instance,Context).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "fclingo-kids.lp".
% #include "fclingo-core.lp".

% Always generate minimal number of objects
instance((Feature,(Instance,0..Min-1)),Structure) :- feature(Context,Feature,Structure,Min,_), structure(Structure), instance(Instance,Context).
Expand Down
2 changes: 1 addition & 1 deletion src/coomsolver/utils/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def get(levels: list[tuple[str, int]], name: str) -> Optional[int]:
)
parser_solve.add_argument("--solver", "-s", type=str, help="Set solver", choices=SOLVERS, default="clingo")

parser_solve.add_argument("--profile", type=str, help="Set COOM profile", choices=COOM_PROFILES, default="travel")
parser_solve.add_argument("--profile", type=str, help="Set COOM profile", choices=COOM_PROFILES, default="all")
parser_solve.add_argument(
"--models", "-n", type=int, help="Compute at most <n> models (0 for all)", default=None, metavar="<n>"
)
Expand Down
92 changes: 74 additions & 18 deletions tests/test_solve.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
# pylint: disable=deprecated-method


class TestClingoKids(TestCase):
class TestClingoCore(TestCase):
"""
Test cases for the clingo kids bike encoding.
Test cases for the clingo COOM core encoding.
"""

def run_test(self, test: dict[str, Any]) -> None:
"""Runs a clintest test with the clingo kids bike encoding.
"""Runs a clintest test with the clingo COOM core encoding.
Args:
test (dict): The clintest test as a dictionary.
Expand All @@ -27,11 +27,11 @@ def run_test(self, test: dict[str, Any]) -> None:
"""
program = test.get("program", None)
files = test.get("files", None)
run_test(test["test"], files=files, program=program, ctl_args=["0"], solver="clingo", profile="kids")
run_test(test["test"], files=files, program=program, ctl_args=["0"], solver="clingo", profile="core")

def test_require(self) -> None:
"""
Test solving require constraints with the clingo kids bike encoding.
Test solving require constraints with the clingo COOM core encoding.
"""
self.run_test(TESTS["require_with_number"])
self.run_test(TESTS["require_with_number_ge"])
Expand All @@ -40,37 +40,37 @@ def test_require(self) -> None:

def test_condition(self) -> None:
"""
Test solving condition constraints with the clingo kids bike encoding.
Test solving condition constraints with the clingo COOM core encoding.
"""
self.run_test(TESTS["condition"])

def test_combinations(self) -> None:
"""
Test solving combinations constraints with the clingo kids bike encoding.
Test solving combinations constraints with the clingo COOM core encoding.
"""
self.run_test(TESTS["combination"])

def test_enumeration(self) -> None:
"""
Test solving enumeration features with the clingo kids bike encoding.
Test solving enumeration features with the clingo COOM core encoding.
"""
self.run_test(TESTS["enumeration"])
self.run_test(TESTS["bool_enumeration"])

def test_attribute(self) -> None:
"""
Test solving enumeration features with attributes with the clingo kids bike encoding.
Test solving enumeration features with attributes with the clingo COOM core encoding.
"""
self.run_test(TESTS["attribute"])


class TestFclingoKids(TestCase):
class TestFclingoCore(TestCase):
"""
Test cases for the fclingo kids bike encoding.
Test cases for the fclingo COOM core encoding.
"""

def run_test(self, test: dict[str, Any]) -> None:
"""Runs a clintest test with the fclingo kids bike encoding.
"""Runs a clintest test with the fclingo COOM core encoding.
Args:
test (dict): The clintest test as a dictionary.
Expand All @@ -82,11 +82,11 @@ def run_test(self, test: dict[str, Any]) -> None:
fclingo_test = test.get("ftest", test["test"])
program = test.get("program", None)
files = test.get("files", None)
run_test(fclingo_test, files=files, program=program, ctl_args=["0"], solver="fclingo", profile="kids")
run_test(fclingo_test, files=files, program=program, ctl_args=["0"], solver="fclingo", profile="core")

def test_require(self) -> None:
"""
Test solving require constraints with the fclingo kids bike encoding.
Test solving require constraints with the fclingo COOM core encoding.
"""
self.run_test(TESTS["require_with_number"])
self.run_test(TESTS["require_with_number_ge"])
Expand All @@ -95,25 +95,81 @@ def test_require(self) -> None:

def test_condition(self) -> None:
"""
Test solving condition constraints with the clingo kids bike encoding.
Test solving condition constraints with the clingo COOM core encoding.
"""
self.run_test(TESTS["condition"])

def test_combinations(self) -> None:
"""
Test solving combinations constraints with the clingo kids bike encoding.
Test solving combinations constraints with the clingo COOM core encoding.
"""
self.run_test(TESTS["combination"])

def test_enumeration(self) -> None:
"""
Test solving enumeration features with the clingo kids bike encoding.
Test solving enumeration features with the clingo COOM core encoding.
"""
self.run_test(TESTS["enumeration"])
self.run_test(TESTS["bool_enumeration"])

def test_attribute(self) -> None:
"""
Test solving enumeration features with attributes with the clingo kids bike encoding.
Test solving enumeration features with attributes with the clingo COOM core encoding.
"""
self.run_test(TESTS["attribute"])


class TestClingoPartonomy(TestCase):
"""
Test cases for the clingo COOM partonomy encoding.
"""

def run_test(self, test: dict[str, Any]) -> None:
"""Runs a clintest test with the clingo COOM partonomy encoding.
Args:
test (dict): The clintest test as a dictionary.
Should contain keys:
"test" (clintest.Test)
"files" (List[str] or "program" (str)
"""
program = test.get("program", None)
files = test.get("files", None)
run_test(test["test"], files=files, program=program, ctl_args=["0"], solver="clingo", profile="partonomy")

def test_structure(self) -> None:
"""
Test solving structure features with the clingo COOM partonomy encoding.
"""
self.run_test(TESTS["structure"])
self.run_test(TESTS["structure_optional"])
self.run_test(TESTS["structure_nested"])
self.run_test(TESTS["structure_nested_optional"])


class TestFclingoPartonomy(TestCase):
"""
Test cases for the fclingo COOM partonomy encoding.
"""

def run_test(self, test: dict[str, Any]) -> None:
"""Runs a clintest test with the fclingo COOM partonomy encoding.
Args:
test (dict): The clintest test as a dictionary.
Should contain keys:
"test" (clintest.Test)
"files" (List[str] or "program" (str)
"""
program = test.get("program", None)
files = test.get("files", None)
run_test(test["test"], files=files, program=program, ctl_args=["0"], solver="fclingo", profile="partonomy")

def test_structure(self) -> None:
"""
Test solving structure features with the fclingo COOM partonomy encoding.
"""
self.run_test(TESTS["structure"])
self.run_test(TESTS["structure_optional"])
self.run_test(TESTS["structure_nested"])
self.run_test(TESTS["structure_nested_optional"])
68 changes: 63 additions & 5 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@
},
"enumeration": {
"test": AndTest(
Assert(Any(), Contains('val((color,((),0)),"Red")')),
Assert(Any(), Contains('val((color,((),0)),"Green")')),
Assert(Any(), Contains('val((color,((),0)),"Blue")')),
Assert(Exact(1), Contains('val((color,((),0)),"Red")')),
Assert(Exact(1), Contains('val((color,((),0)),"Green")')),
Assert(Exact(1), Contains('val((color,((),0)),"Blue")')),
Assert(Exact(3), True_()),
),
"program": """
Expand All @@ -82,8 +82,8 @@
},
"bool_enumeration": {
"test": AndTest(
Assert(Any(), Contains('val((boolean,((),0)),"True")')),
Assert(Any(), Contains('val((boolean,((),0)),"False")')),
Assert(Exact(1), Contains('val((boolean,((),0)),"True")')),
Assert(Exact(1), Contains('val((boolean,((),0)),"False")')),
Assert(Exact(2), True_()),
),
"program": """
Expand All @@ -105,4 +105,62 @@
option("Wheel", "W14").
attr_value("Wheel","W14",size,14).""",
},
"structure": {
"test": AndTest(
Assert(Exact(1), Contains('instance((wheel,((),0)),"Wheel")')),
Assert(Exact(1), True_()),
),
"program": """
structure(":root").
feature(":root",wheel,"Wheel",1,1).
structure("Wheel").""",
},
"structure_optional": {
"test": AndTest(
Assert(Exact(1), Contains('instance((basket,((),0)),"Basket")')),
Assert(Exact(2), True_()),
),
"program": """
structure(":root").
feature(":root",basket,"Basket",0,1).
structure("Basket").""",
},
"structure_nested": {
"test": AndTest(
Assert(
Exact(1),
SupersetOf({'instance((carrier,((),0)),"Carrier")', 'instance((bag,((carrier,((),0)),0)),"Bag")'}),
),
Assert(Exact(1), True_()),
),
"program": """
structure(":root").
feature(":root",carrier,"Carrier",1,1).
structure("Carrier").
feature("Carrier",bag,"Bag",1,1).
structure("Bag").""",
},
"structure_nested_optional": {
"test": AndTest(
Assert(Exact(3), Contains('instance((carrier,((),0)),"Carrier")')),
Assert(Exact(2), Contains('instance((bag,((carrier,((),0)),0)),"Bag")')),
Assert(
Exact(1),
SupersetOf(
{
'instance((carrier,((),0)),"Carrier")',
'instance((bag,((carrier,((),0)),0)),"Bag")',
'instance((bag,((carrier,((),0)),1)),"Bag")',
}
),
),
Assert(Exact(4), True_()),
),
"program": """
structure(":root").
feature(":root",carrier,"Carrier",0,1).
structure("Carrier").
feature("Carrier",bag,"Bag",0,2).
structure("Bag").""",
},
}

0 comments on commit 2f4af45

Please sign in to comment.