diff --git a/benchmarks/singleshot/README.md b/benchmarks/singleshot/README.md new file mode 100644 index 00000000..7c6ed830 --- /dev/null +++ b/benchmarks/singleshot/README.md @@ -0,0 +1,17 @@ +# Singleshot benchmarking for OOASP + +In this directory is a collection of `.lp` files defining ooasp for the purposes of singleshot benchmarking, automated python script for running them and resulting outputs of the script. + +## Automated Script + +The benchmarking is meant to be run using the automated script `autorun.py`, which is to be run from the `singleshot_bench` directory. +The script works by automatically rewriting the `assumptions.lp` file and then using the Clingo python API to run solving and log the times. + +### Domain sizes + +The minimal domain sizes are calculated using a python script provided to team members. For now these should be considered the minimal solvable domain sizes. + +### Logging + +The script currently creates logs of found models in `results/models` and times per iteration in `results/times`. +Outdated `assumptions.lp` files are not logged by default, but this logging can be switch on by changing the `save` flag in `build_assumptions` function to `True`. \ No newline at end of file diff --git a/benchmarks/singleshot/autorun.py b/benchmarks/singleshot/autorun.py new file mode 100644 index 00000000..ef067efd --- /dev/null +++ b/benchmarks/singleshot/autorun.py @@ -0,0 +1,144 @@ +# Copyright (c) 2022-2024 Siemens AG Oesterreich +# SPDX-License-Identifier: MIT + +import os +import datetime + +from typing import List, Annotated + +from clingo import Control + +ELEMENT_NAMES = 'ABCD' +ELEMENT_TYPES = len(ELEMENT_NAMES) + +domain_sizes: Annotated[List[int], "Currently known minimal domain sizes calculated by count.py script"] = [ + 19, 33, 51, 65, 84, 98, 116, 130, 149, 163, 181, 195, 214, 228, 246, 260, 279, 293, 311, 325 + ] + +instances: Annotated[List[int], "Iteration identifications."] = [x+1 for x in range(20)] + + +def generate_ids(n: int) -> List[str]: + """ + Generates combinations of element definitions + with suitable IDs. + :param n: int, number of elements of each type (e.g. for iteration 4, n=4) + :return: list of fact representations strings + """ + + ids = [id+1 for id in range(ELEMENT_TYPES*n)] + assigned = [ids[i*n:i*n+n] for i in range(ELEMENT_TYPES)] + partial_config_facts = [] + + for element_index, object_ids in enumerate(assigned): + for id in object_ids: + partial_config_facts.append(f"user(ooasp_isa(element{ELEMENT_NAMES[element_index]},{id})).") + + return partial_config_facts + + +def rewrite_assumptions(content: List[str], save: bool = True) -> None: + """ + Rewrites the assumptions.lp file to the list of content passed. + If save is set to true, creates a legacy directory and saves a copy of existing assumptions to it. + :param content: list of configuration facts + :param save: if active, saves all the generated files iin the outdated instances directory + """ + + if os.path.isfile('instances/assumptions.lp'): + if save: + os.makedirs('instances/outdated', exist_ok=True) + new_file = f"instances/outdated/assumptions{len(content)}{str(datetime.datetime.now()).replace(' ', '_').replace('.', '-').replace(':', '-')}.lp" + os.rename('instances/assumptions.lp', new_file) + os.makedirs('instances', exist_ok=True) + with open('instances/assumptions.lp', 'w') as file: + print(" >>Rewriting assumptions.") + for t in content: + file.write(t+'\n') + + +def add_domain(size: int) -> None: + """ + Adds domain size constraints to the assumption file + :param size: size of the domain + """ + with open('instances/assumptions.lp', 'a') as file: + t = f'ooasp_domain(object,1..{size}).' + file.write(t) + + +def build_assumptions(n: int, save: bool = False) -> None: + """ + Builds the new assumptions file in its entirety. + :param n: number of iteration + :param save: flag to save old assumption files before rewriting them + """ + partial_config_facts = generate_ids(n) + rewrite_assumptions(partial_config_facts, save=save) + add_domain(domain_sizes[n-1] if len(domain_sizes) >= n else 100) # 100 is a placeholder value to avoid potential errors + + +def reset_solving() -> Control: + """ + Reinitialises the clingo control. + Returns the set up instance. + """ + ctl = Control(["--opt-mode=ignore", + "--warn=none"]) + ctl.load("singleshot.lp") + ctl.ground([("base", [])]) + return ctl + + +def log_model(model, out: bool=False) -> None: + """ + Creates a model directory (if it does not exist) + And logs resulting models into files + :param model: representation of the model + :param out: flag to turn on stdout prints of the model + """ + os.makedirs('results/models', exist_ok=True) + + global timestr + new_file = f"results/models/M{iteration}{timestr}.txt" + with open(new_file, 'w') as mfile: + mfile.write(str(model)) + if out: + print('MODEL:') + print(model) + + +def log_results(stats: str, iteration: int, out: bool = False) -> None: + """ + Creates a results directory (if it does not exist) + And logs times and results into text files. + :param stats: statistics to write into the file + :param iteration: identificator of the iteration + :param out: flag to activate stdout prints of the results + """ + os.makedirs('results/times', exist_ok=True) + global timestr + new_file = f"results/times/R{iteration}{timestr}.txt" + with open(new_file, 'w') as mfile: + mfile.write(stats) + if out: + print('RESULTS:') + print(stats) + + +def on_model(m): + """ + Helper function to control resulting model + """ + log_model(m) + + +if __name__ == "__main__": + global timestr + timestr = str(datetime.datetime.now()).replace(' ', '_').replace('.', '-').replace(':', '-') + for iteration in instances: + print(f">>Solving for:{iteration}") + build_assumptions(iteration) + ctl = reset_solving() + ctl.solve(on_model=on_model) + log_results(str(ctl.statistics['summary']['times']), iteration, out=True) diff --git a/benchmarks/singleshot/ooasp.lp b/benchmarks/singleshot/ooasp.lp new file mode 100644 index 00000000..7e7f6ed8 --- /dev/null +++ b/benchmarks/singleshot/ooasp.lp @@ -0,0 +1,28 @@ +% Copyright (c) 2022 Siemens AG Oesterreich +% SPDX-License-Identifier: MIT + +% External Substitutes +guess. +check_potential_cv. +check_permanent_cv. +% ------------ Base programs +#const config_name = default_config_name. +#const kb_name = default_kb_name. +ooasp_configuration(kb_name,config_name). +#include "ooasp_aux_kb.lp". % Auxiliary predicates for the KB + + +% ------------ Incremental programs +%#include "ooasp_user_input.lp". % User input with externals +#include "ooasp_aux_config.lp". % Auxiliay predicates fot the config +#include "ooasp_guess.lp". % Guess section +%#include "ooasp_guess_fclingo.lp". % Guess section +#include "ooasp_check.lp". % Check section +%#include "ooasp_check_fclingo.lp". % Check section +%#include "ooasp_check_user.lp". % Check section +%#include "ooasp_cautious_opt.lp". % Optimizations used for cautious reasoning + +%#include "ooasp_symmetry.lp". % Symmetry breaking constraints THIS BREAKS IT...for now (in original it is not replaced by the variable) + +:- user(ooasp_isa(C,new_object)), +not ooasp_isa(C,new_object). \ No newline at end of file diff --git a/benchmarks/singleshot/ooasp_aux_config.lp b/benchmarks/singleshot/ooasp_aux_config.lp new file mode 100644 index 00000000..e365989e --- /dev/null +++ b/benchmarks/singleshot/ooasp_aux_config.lp @@ -0,0 +1,70 @@ +% Copyright (c) 2022-2024 Siemens AG Oesterreich +% SPDX-License-Identifier: MIT + +% Transitive closure when a leaf class is selected via choice +ooasp_isa(LEAFCLASS,OBJECT) :- + ooasp_isa_leaf(LEAFCLASS,OBJECT). + +% Transitive closure +ooasp_isa(SUPER,OBJECT) :- + ooasp_isa(SUB,OBJECT), + ooasp_subclass(SUB,SUPER). + +% Generation of leafs +ooasp_isa_leaf(C,OBJECT) :- + ooasp_isa(C,OBJECT), + ooasp_leafclass(C). + +ooasp_isa_smallest(SUPER,OBJECT) :- + ooasp_isa(SUPER,OBJECT), + not ooasp_isa(SUB,OBJECT) :ooasp_subclass(SUB,SUPER). + +ooasp_assoc_gen(ASSOC,1,ID1,OBJECT) :- + ooasp_associated(ASSOC,ID1,OBJECT). + +ooasp_assoc_gen(ASSOC,1,OBJECT,ID2) :- + ooasp_associated(ASSOC,OBJECT,ID2). + +ooasp_assoc_gen(ASSOC,2,OBJECT,ID1) :- + ooasp_associated(ASSOC,ID1,OBJECT). + +ooasp_assoc_gen(ASSOC,2,ID2,OBJECT) :- + ooasp_associated(ASSOC,OBJECT,ID2). + +% Association specialization +ooasp_associated(ASSOC,OBJECT,ID2) :- + ooasp_associated(ASSOC_S,OBJECT,ID2), + ooasp_assoc_specialization(ASSOC_S,ASSOC), + ooasp_assoc(ASSOC,C1,_,_,C2,_,_), + ooasp_isa(C1,OBJECT), + ooasp_isa(C2,ID2). + +ooasp_associated(ASSOC,ID1,OBJECT) :- + ooasp_associated(ASSOC_S,ID1,OBJECT), + ooasp_assoc_specialization(ASSOC_S,ASSOC), + ooasp_assoc(ASSOC,C1,_,_,C2,_,_), + ooasp_isa(C1,ID1), + ooasp_isa(C2,OBJECT). + +ooasp_associated(ASSOC_S,OBJECT,ID2) :- + ooasp_associated(ASSOC,OBJECT,ID2), + ooasp_assoc_specialization(ASSOC_S,ASSOC), + ooasp_assoc(ASSOC_S,C1,_,_,C2,_,_), + ooasp_isa(C1,OBJECT), + ooasp_isa(C2,ID2). + +ooasp_associated(ASSOC_S,ID1,OBJECT) :- + ooasp_associated(ASSOC,ID1,OBJECT), + ooasp_assoc_specialization(ASSOC_S,ASSOC), + ooasp_assoc(ASSOC_S,C1,_,_,C2,_,_), + ooasp_isa(C1,ID1), + ooasp_isa(C2,OBJECT). + + +% Int attributes + +ooasp_attr_int(OBJECT, A, MIN, MAX):- + ooasp_isa(C,OBJECT), + ooasp_attr_minInclusive(C,A,MIN), + ooasp_attr_maxInclusive(C,A,MAX), + ooasp_attr(C,A,int). diff --git a/benchmarks/singleshot/ooasp_aux_kb.lp b/benchmarks/singleshot/ooasp_aux_kb.lp new file mode 100644 index 00000000..e8f5c08b --- /dev/null +++ b/benchmarks/singleshot/ooasp_aux_kb.lp @@ -0,0 +1,52 @@ +% Copyright (c) 2022-2024 Siemens AG Oesterreich +% SPDX-License-Identifier: MIT + +#program base. + +#const use_dl = false. + +% transitive closure +ooasp_subclass(SUB,SUPER2) :- + ooasp_subclass(SUB,SUPER1), + ooasp_subclass(SUPER1,SUPER2). + +ooasp_subclass_ref(C1,C2):-ooasp_subclass(C1,C2). +ooasp_subclass_ref(C,C):-ooasp_class(C). + + +% derive domain for boolean attributes +ooasp_attr_enum(C,N,"true") :- + ooasp_attr(C,N,"boolean"). +ooasp_attr_enum(C,N,"false") :- + ooasp_attr(C,N,"boolean"). + +% true, if attribute has domain +ooasp_attr_hasdomain(C,N) :- + ooasp_attr_enum(C,N,D). + +ooasp_attr_enum(C,N,MIN..MAX) :- + ooasp_attr(C,N,enumint), + ooasp_attr_minInclusive(C,N,MIN), + ooasp_attr_maxInclusive(C,N,MAX). + +ooasp_attr_fdom(C,N,MIN..MAX) :- + ooasp_attr(C,N,int), + ooasp_attr_minInclusive(C,N,MIN), + ooasp_attr_maxInclusive(C,N,MAX). + +% leafclasses are classes without subclasses +ooasp_leafclass(C) :- + ooasp_class(C), + not ooasp_subclass(_,C). + +ooasp_assoc_limit(ASSOC,min,1,C1,C2MIN,C2):- + ooasp_assoc(ASSOC,C1,C1MIN,C1MAX,C2,C2MIN,C2MAX). + +ooasp_assoc_limit(ASSOC,max,1,C1,C2MAX,C2):- + ooasp_assoc(ASSOC,C1,C1MIN,C1MAX,C2,C2MIN,C2MAX). + +ooasp_assoc_limit(ASSOC,min,2,C2,C1MIN,C1):- + ooasp_assoc(ASSOC,C1,C1MIN,C1MAX,C2,C2MIN,C2MAX). + +ooasp_assoc_limit(ASSOC,max,2,C2,C1MAX,C1):- + ooasp_assoc(ASSOC,C1,C1MIN,C1MAX,C2,C2MIN,C2MAX). diff --git a/benchmarks/singleshot/ooasp_cautious.opt.lp b/benchmarks/singleshot/ooasp_cautious.opt.lp new file mode 100644 index 00000000..5de6fbc0 --- /dev/null +++ b/benchmarks/singleshot/ooasp_cautious.opt.lp @@ -0,0 +1,5 @@ +% Copyright (c) 2022-2024 Siemens AG Oesterreich +% SPDX-License-Identifier: MIT + +% Used when getting inferences to minimize on lowerbound errors +:~ ooasp_cv(lowerbound,ID,_,(ASSOC,CMIN,N,C,OPT,OBJECT)). [CMIN-N@3,(ASSOC,ID)] diff --git a/benchmarks/singleshot/ooasp_check.lp b/benchmarks/singleshot/ooasp_check.lp new file mode 100644 index 00000000..fe3b234b --- /dev/null +++ b/benchmarks/singleshot/ooasp_check.lp @@ -0,0 +1,154 @@ +% Copyright (c) 2022-2024 Siemens AG Oesterreich +% SPDX-License-Identifier: MIT + +% Integrity constraints for constraint violations, activated based on the externals +:- ooasp_cv(CV,_,_,_), + not ooasp_potential_cv(CV), + check_permanent_cv. +:- ooasp_cv(CV,_,_,_), + ooasp_potential_cv(CV), + check_potential_cv. + +%======================================= +% Potential constraint violations +%======================================= + +ooasp_potential_cv(lowerbound). +ooasp_potential_cv(no_value). + +%======================================= +% Instances +%======================================= + +% ------ (USER INPUT) Cant be instance of two different leaf classes +ooasp_cv(notinstanceofsubclass,OBJECT,"Has two leaf classes {} and {}",(C1,C2)) :- + ooasp_isa_leaf(C1,OBJECT), + ooasp_isa_leaf(C2,OBJECT), + C1 CMAX. + %active(OBJECT). + + % SAFETY VIOLATIONS +lb_violation(lowerbound,ID1,"Lowerbound for {} is {} but has {} {}",(ASSOC,CMIN,N,C2,OPT)):- + ooasp_assoc_limit(ASSOC,min,OPT,C,CMIN,C2), + ooasp_isa(C,ID1), + #count { ID2:ooasp_assoc_gen(ASSOC,OPT,ID1,ID2) } = N, + N < CMIN. + %active(OBJECT). + +ooasp_cv(lowerbound,ID1,M,(ASSOC,CMIN,N,C,OPT)):- + lb_violation(lowerbound,ID1,M,(ASSOC,CMIN,N,C,OPT)), + not lb_violation(lowerbound,ID1,_,(SUBASSOC,_,_,_,_)):ooasp_assoc_specialization(SUBASSOC,ASSOC). + + +%--- Associations are only allowed to something instantiated + +ooasp_cv(no_instance_for_association,OBJECT,"Associated by {} to {} but not is not instantiated",(ASSOC,ID2)) :- + ooasp_associated(ASSOC,OBJECT,ID2), + not ooasp_isa(_,OBJECT). + +ooasp_cv(no_instance_for_association,OBJECT,"Associated by {} to {} but not instantiated",(ASSOC,ID1)) :- + ooasp_associated(ASSOC,ID1,OBJECT), + not ooasp_isa(_,OBJECT). + +ooasp_cv(no_instance_for_association,OBJECT,"Associated by {} to {} which is not instantiated",(ASSOC,ID2)) :- + ooasp_associated(ASSOC,OBJECT,ID2), + not ooasp_isa(_,ID2). + +ooasp_cv(no_instance_for_association,OBJECT,"Associated by {} to {} which is not instantiated",(ASSOC,ID1)) :- + ooasp_associated(ASSOC,ID1,OBJECT), + not ooasp_isa(_,ID1). + + +%--- (USER INPUT) Type of association + +ooasp_cv(wrongtypeinassoc,ID,"Associated by {} but is not of class {}",(ASSOC,C1)) :- + %active(OBJECT), + ooasp_associated(ASSOC,ID,_), + ooasp_assoc(ASSOC,C1,C1MIN,C1MAX,C2,C2MIN,C2MAX), + not ooasp_isa(C1,ID). + +ooasp_cv(wrongtypeinassoc,ID,"Associated by {} but is not of class {}",(ASSOC,C2)) :- + %active(OBJECT), + ooasp_associated(ASSOC,_,ID), + ooasp_assoc(ASSOC,C1,C1MIN,C1MAX,C2,C2MIN,C2MAX), + not ooasp_isa(C2,ID). + + +%======================================= +% Values +%======================================= + + +%--- Missing attribute value +ooasp_cv(no_value,OBJECT,"Missing value for {}",(A,)) :- + ooasp_attr(C,A,enumint), + ooasp_attr_enum(C,A,_), + ooasp_isa(C,OBJECT), + not ooasp_attr_value(A,OBJECT,_). + + +%======================================= +% Special Constraint violations +%======================================= + + +%--- Unique attributes (Enumeration) + +% The class C of the main object is in position 1 + +% The new object is of that class C +ooasp_cv(unique_attr, (OBJECT;ID1), "Attribute {} must be unique among all {}s associated by {} to {}",(ATTR,C,ASSOC,ID2,OBJECT )):- + ooasp_special_cv(unique,(ASSOC, C, ATTR)), + ooasp_assoc(ASSOC,C,_,_,_,_,_), + ooasp_associated(ASSOC,OBJECT,ID2), + ooasp_associated(ASSOC,ID1,ID2), + OBJECT>ID1, + ooasp_attr_value(ATTR,OBJECT,V), + ooasp_attr_value(ATTR,ID1,V). + +% The new object is of the other class +ooasp_cv(unique_attr, (ID3;ID1), "Attribute {} must be unique among all {}s associated by {} to {}",(ATTR,C,ASSOC,OBJECT)):- + ooasp_special_cv(unique,(ASSOC, C, ATTR)), + ooasp_assoc(ASSOC,C,_,_,_,_,_), + ooasp_associated(ASSOC,ID3,OBJECT), + ooasp_associated(ASSOC,ID1,OBJECT), + ID3>ID1, + ooasp_attr_value(ATTR,ID3,V), + ooasp_attr_value(ATTR,ID1,V). + +% The class C of the main object is in position 2 + +ooasp_cv(unique_attr, (OBJECT;ID1), "Attribute {} must be unique among all {}s associated by {} to {}",(ATTR,C,ASSOC,ID2,OBJECT )):- + ooasp_special_cv(unique,(ASSOC, C, ATTR)), + ooasp_assoc(ASSOC,_,_,_,C,_,_), + ooasp_associated(ASSOC,ID2,OBJECT), + ooasp_associated(ASSOC,ID2,ID1), + OBJECT>ID1, + ooasp_attr_value(ATTR,OBJECT,V), + ooasp_attr_value(ATTR,ID1,V). + +ooasp_cv(unique_attr, (ID3;ID1), "Attribute {} must be unique among all {}s associated by {} to {}",(ATTR,C,ASSOC,OBJECT )):- + ooasp_special_cv(unique,(ASSOC, C, ATTR)), + ooasp_assoc(ASSOC,_,_,_,C,_,_), + ooasp_associated(ASSOC,OBJECT,ID3), + ooasp_associated(ASSOC,OBJECT,ID1), + ID3>ID1, + ooasp_attr_value(ATTR,ID3,V), + ooasp_attr_value(ATTR,ID1,V). + + + diff --git a/benchmarks/singleshot/ooasp_check_user.lp b/benchmarks/singleshot/ooasp_check_user.lp new file mode 100644 index 00000000..40f451fb --- /dev/null +++ b/benchmarks/singleshot/ooasp_check_user.lp @@ -0,0 +1,45 @@ + +% ============================================================================== +% User input Values (General), when guessing values this should not be needed +% ============================================================================== + +% %--- (USER INPUT) Attribute value must belong to instance class +ooasp_cv(no_instance_for_attribute,OBJECT,"Attribute {} not of selected class",(A,)) :- + ooasp_attr(C1,A,T), + user(ooasp_attr_value(A,OBJECT,V)), + not ooasp_isa(C1,OBJECT). + +%--- (USER INPUT) Attribute value must belong to instance +ooasp_cv(no_instance_for_attribute,OBJECT,"Value for {} assigned but instanciated",(A,)) :- + user(ooasp_attr_value(A,OBJECT,V)), + not ooasp_isa(_,OBJECT). + +%--- (USER INPUT) Atribute value not from domain +ooasp_cv(value_not_domain,OBJECT,"Value {} for {} not from domain",(V,A)) :- + ooasp_attr(C,A,enumint), + ooasp_attr_enum(C,A,_), + ooasp_isa(C,OBJECT), + user(ooasp_attr_value(A,OBJECT,V)), + not ooasp_attr_enum(C,A,V). + +%--- (USER INPUT) Multiple values for a value +ooasp_cv(conflicting_values,OBJECT,"Multiple values for {}: {},{}",(A,V1,V2)) :- + ooasp_attr(C,A,T), + user(ooasp_attr_value(A,OBJECT,V1)), + user(ooasp_attr_value(A,OBJECT,V2)), + V1{}",(A,V,MAX)) :- + ooasp_attr(C,A,T), + ooasp_isa(C,OBJECT), + user(ooasp_attr_value(A,OBJECT,V)), + ooasp_attr_maxInclusive(C,A,MAX), + V>MAX. \ No newline at end of file diff --git a/benchmarks/singleshot/ooasp_guess.lp b/benchmarks/singleshot/ooasp_guess.lp new file mode 100644 index 00000000..5891a6c5 --- /dev/null +++ b/benchmarks/singleshot/ooasp_guess.lp @@ -0,0 +1,46 @@ +% Copyright (c) 2022-2024 Siemens AG Oesterreich +% SPDX-License-Identifier: MIT + +% If an object has a domain, then it could be instanciated +{ ooasp_isa_leaf(LEAFCLASS,OBJECT): + ooasp_leafclass(LEAFCLASS), + ooasp_subclass_ref(LEAFCLASS,C) } 1:- + ooasp_domain(C,OBJECT), + guess. + +% If is_a appears then it has to be instanciated as leaf +1{ ooasp_isa_leaf(LEAFCLASS,OBJECT): + ooasp_leafclass(LEAFCLASS), + ooasp_subclass_ref(LEAFCLASS,C) } 1:- + ooasp_isa(C,OBJECT), + guess. + +% % Associations from OBJECT +{ ooasp_associated(ASSOC,OBJECT,ID2) } :- + ooasp_assoc(ASSOC,C1,C1MIN,C1MAX,C2,C2MIN,C2MAX), + ooasp_isa(C1,OBJECT), + ID24. + +ooasp_cv(frame_must_be_within_range, F, "Frame position is outside of range {} ",(F,new_object)):- + ooasp_isa(rackSingle,new_object), + ooasp_associated(rack_frames,new_object,F), + ooasp_attr_value(frame_position,F,P), + P>4. + +% % moduleII requires moduleV +ooasp_cv(moduleII_requires_moduleV,F,"ModuleII requires moduleV in frame {}",(F,new_object)):- + active(new_object), + ooasp_isa(frame,F), + ooasp_isa(moduleII,M), + ooasp_associated(frame_modules,F,M), + not ooasp_isa(moduleV,M5): ooasp_associated(frame_modules,F,M5). \ No newline at end of file diff --git a/benchmarks/singleshot/racks/fb.lp b/benchmarks/singleshot/racks/fb.lp new file mode 100644 index 00000000..d3ee2380 --- /dev/null +++ b/benchmarks/singleshot/racks/fb.lp @@ -0,0 +1,75 @@ +% Copyright (c) 2022 Siemens AG Oesterreich +% SPDX-License-Identifier: MIT + +% EXAMPLE racks +% classes +ooasp_class(object). + +ooasp_class(rack). +ooasp_subclass(rack,object). + +ooasp_class(rackSingle). +ooasp_subclass(rackSingle,rack). + +ooasp_class(rackDouble). +ooasp_subclass(rackDouble,rack). + +ooasp_class(frame). +ooasp_subclass(frame,object). + +ooasp_class(element). +ooasp_class(elementA). +ooasp_class(elementB). +ooasp_class(elementC). +ooasp_class(elementD). +ooasp_subclass(element,object). +ooasp_subclass(elementA,element). +ooasp_subclass(elementB,element). +ooasp_subclass(elementC,element). +ooasp_subclass(elementD,element). + +ooasp_class(module). +ooasp_class(moduleI). +ooasp_class(moduleII). +ooasp_class(moduleIII). +ooasp_class(moduleIV). +ooasp_class(moduleV). +ooasp_subclass(module,object). +ooasp_subclass(moduleI,module). +ooasp_subclass(moduleII,module). +ooasp_subclass(moduleIII,module). +ooasp_subclass(moduleIV,module). +ooasp_subclass(moduleV,module). + +% associations +% -1 means * i.e. unrestricted + +ooasp_assoc(rack_frames,rack,1,1,frame,4,8). +ooasp_assoc(frame_modules,frame,1,1,module,0,5). +ooasp_assoc(element_modules,element,0,1,module,1,4). + + +ooasp_assoc(rack_framesS,rackSingle,0,1,frame,4,4). +ooasp_assoc(rack_framesD,rackDouble,0,1,frame,8,8). + +ooasp_assoc(element_modules1,elementA,1,1,moduleI,1,1). +ooasp_assoc(element_modules2,elementB,1,1,moduleII,2,2). +ooasp_assoc(element_modules3,elementC,1,1,moduleIII,3,3). +ooasp_assoc(element_modules4,elementD,1,1,moduleIV,4,4). + +ooasp_assoc_specialization(rack_framesS,rack_frames). +ooasp_assoc_specialization(rack_framesD,rack_frames). +ooasp_assoc_specialization(element_modules1,element_modules). +ooasp_assoc_specialization(element_modules2,element_modules). +ooasp_assoc_specialization(element_modules3,element_modules). +ooasp_assoc_specialization(element_modules4,element_modules). + + +ooasp_attr(frame,frame_position,enumint). +ooasp_attr_minInclusive(frame,frame_position,1). +ooasp_attr_maxInclusive(frame,frame_position,8). + + +ooasp_special_cv(unique, (rack_frames, frame, frame_position)). + +% ooasp_special_cv(requires, (frame_modules, moduleII, moduleV)). diff --git a/benchmarks/singleshot/singleshot.lp b/benchmarks/singleshot/singleshot.lp new file mode 100644 index 00000000..f3f2b11e --- /dev/null +++ b/benchmarks/singleshot/singleshot.lp @@ -0,0 +1,9 @@ +#include "ooasp.lp". +#include "ooasp_symmetry.lp". +#include "ooasp_user_input.lp". +#include "ooasp_check_user.lp". + +#include "instances/assumptions.lp". + +#include "racks/constraints.lp". +#include "racks/fb.lp".