mccs-1.1/sources/abstract_combiner.h0000600017777601777760000000216511574427503017442 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: abstract_combiner.h */ /* Abstract class for combiners */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __ABSTRACT_COMBINER_H #define __ABSTRACT_COMBINER_H #include #include // An anstract combiner class abstract_combiner { public: // Called to know the number of columns required by the combiner virtual int column_allocation(int first_rank) { return first_rank; } // Method in charge of the combiner objective generation virtual int objective_generation() { return 0; } // Method in charge of the combiner constraint generation virtual int constraint_generation() { return 0; } // Tells whether this combiner allows problem reductions or not virtual bool can_reduce() { return true; } // Called to let the combiner initializes itself virtual void initialize(CUDFproblem *problem, abstract_solver *solver) { }; // Combiner destructor virtual ~abstract_combiner() { }; }; #endif mccs-1.1/sources/abstract_criteria.h0000600017777601777760000000406011574427503017442 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: abstract_criteria.h */ /* Abstract class for criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _ABSTRACT_CRITERIA_H_ #define _ABSTRACT_CRITERIA_H_ #include #include #include // Abstract criteria class class abstract_criteria { public: // Method called to allocate some variables (columns) to the criteria virtual int set_variable_range(int first_free_var) { return 0; } // Method called to add the criteria to the current objective virtual int add_criteria_to_objective(CUDFcoefficient lambda) { return 0; }; // Method called to add the criteria to the constraints virtual int add_criteria_to_constraint(CUDFcoefficient lambda) { return 0; }; // Method called to add criteria related constraints virtual int add_constraints() { return 0; }; // Gives the range of the criteria objective virtual CUDFcoefficient bound_range() { return 0; }; // Gives the upper bound of the criteria objective virtual CUDFcoefficient upper_bound() { return 0; }; // Gives the lower bound of the criteria objective virtual CUDFcoefficient lower_bound() { return 0; }; // Does this criteria allows problem reduction ? virtual bool can_reduce(CUDFcoefficient lambda) { return true; } // Method called to let the criteria initializes itself virtual void initialize(CUDFproblem *problem, abstract_solver *solver) { }; // Method called to initialize criteria variables virtual void initialize_intvars() { }; // Method called to let the criteria checks some properties availability virtual void check_property(CUDFproblem *problem) { }; // Criteria destructor virtual ~abstract_criteria() { }; }; // Type for a list of criteria typedef vector CriteriaList; typedef CriteriaList::iterator CriteriaListIterator; // Shall we optimize variable usage or not extern bool criteria_opt_var; #endif mccs-1.1/sources/abstract_solver.h0000600017777601777760000001151611574427503017156 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: abstract_solver.h */ /* Abstract class for solvers */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // Solver abstraction // all implemented solvers are implemented through a concrete class that inherits and implements an abstract solver. #ifndef _ABSTRACT_SOLVER_H #define _ABSTRACT_SOLVER_H #include #include // provide an abstraction of the underlying solvers class abstract_solver { public: // ****************************************************************** // solver initialisation method (called at the beginning of constraint generation) virtual int init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars) { return 0; }; // ****************************************************************** // does the solver has the capability to handle integer variables virtual bool has_intvars() { return false; }; // set variable type to int and its range to [lower, upper] (must be used before end_objectives) virtual int set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper) { return 0; } // ****************************************************************** // called before objective definitions virtual int begin_objectives(void) { return 0; }; // get the current coefficient value of the objective function for parameter package virtual CUDFcoefficient get_obj_coeff(CUDFVersionedPackage *package) { return 0; }; // get the current coefficient value of the objective function for variable rank virtual CUDFcoefficient get_obj_coeff(int rank) { return 0; }; // set objective coefficient value according to a package virtual int set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { return 0; }; // set objective coefficient value according to a rank (column number) virtual int set_obj_coeff(int rank, CUDFcoefficient value) { return 0; }; // called before defining a new objective virtual int new_objective(void) { return 0; }; // called to add a new objective virtual int add_objective(void) { return 0; }; // called at the end of objective definitions virtual int end_objectives(void) { return 0; }; // ****************************************************************** // constraint generation // called before the definition of any constraint virtual int begin_add_constraints(void) { return 0; }; // called before the definition of a new constraint virtual int new_constraint(void) { return 0; }; // get current constraint coefficient according to a package virtual CUDFcoefficient get_constraint_coeff(CUDFVersionedPackage *package) { return 0; }; // get current constraint coefficient according to a rank virtual CUDFcoefficient get_constraint_coeff(int rank) { return 0; }; // set constraint coefficient of a package virtual int set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { return 0; }; // set constraint coefficient of a rank (i.e. column number) virtual int set_constraint_coeff(int rank, CUDFcoefficient value) { return 0; }; // define the constraint as greater or equal to a bound (called once all constraints coefficients have been defined) virtual int add_constraint_geq(CUDFcoefficient bound) { return 0; }; // define the constraint as less or equal to a bound (called once all constraints coefficients have been defined) virtual int add_constraint_leq(CUDFcoefficient bound) { return 0; }; // define the constraint as equal to a bound (called once all constraints coefficients have been defined) virtual int add_constraint_eq(CUDFcoefficient bound) { return 0; }; // called once all constraints have been defined virtual int end_add_constraints(void) { return 0; }; // ****************************************************************** // write the internal representation of the problem to a file virtual int writelp(char *filename) { return 0; }; // ****************************************************************** // solve the problem (must return a value > 0 if a solution has been found) virtual int solve() { return 0; }; // ****************************************************************** // initialisation of the solutions (called before reading them) virtual int init_solutions() { return 0; }; // get the objective value at the end of solving virtual CUDFcoefficient objective_value() { return 0; }; // get the status of a package in the final configuration virtual CUDFcoefficient get_solution(CUDFVersionedPackage *package) { return 0; }; virtual CUDFcoefficient get_solution(int k) { return 0; }; // ****************************************************************** // abstract solver destructor virtual ~abstract_solver() {}; }; #endif mccs-1.1/sources/agregate_combiner.c0000600017777601777760000001064611574427503017414 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: agregate_combiner.c */ /* Implementation of the agregate combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include // Compute the number of columns required to handle the agregate int agregate_combiner::column_allocation(int first_rank) { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); return first_rank; } // Generate the objective function int agregate_combiner::objective_generation() { // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); solver->new_objective(); add_criteria_to_objective(1); solver->add_objective(); return 0; } // Ask to criteria to generate their own constraints int agregate_combiner::constraint_generation() { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Combiner initialization void agregate_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } // Compute the number of required columns when the combiner is used as a criteria int agregate_combiner::set_variable_range(int first_free_var) { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_free_var = (*crit)->set_variable_range(first_free_var); return first_free_var; } // Add the combiner as a criteria to the curent objective function int agregate_combiner::add_criteria_to_objective(CUDFcoefficient lambda) { for (CriteriaList::iterator crit = criteria->begin(); crit != criteria->end(); ++crit) (*crit)->add_criteria_to_objective(lambda_crit*lambda); return 0; } // Add the combiner objective as a constraint int agregate_combiner::add_criteria_to_constraint(CUDFcoefficient lambda) { for (CriteriaList::iterator crit = criteria->begin(); crit != criteria->end(); ++crit) (*crit)->add_criteria_to_constraint(lambda_crit*lambda); return 0; } // Add the required constraints (from the criteria set) int agregate_combiner::add_constraints() { return constraint_generation(); } // Compute the range of the combiner/criteria CUDFcoefficient agregate_combiner::bound_range() { CUDFcoefficient range = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) range += CUDFabs(lambda_crit) * (*crit)->bound_range(); return range; } // Compute the upper bound of the combiner/criteria CUDFcoefficient agregate_combiner::upper_bound() { CUDFcoefficient ub = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) if (lambda_crit >= 0) ub += lambda_crit * (*crit)->upper_bound(); else ub += lambda_crit * (*crit)->lower_bound(); return ub; } // Compute the lower bound of the combiner/criteria CUDFcoefficient agregate_combiner::lower_bound() { CUDFcoefficient lb = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) if (lambda_crit >= 0) lb += lambda_crit * (*crit)->lower_bound(); else lb += lambda_crit * (*crit)->upper_bound(); return lb; } // Does the combiner/criteria allows problem reduction bool agregate_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(lambda_crit); return result; } // Does the combiner/criteria allows problem reduction (taking into account lambda multiplier) bool agregate_combiner::can_reduce(CUDFcoefficient lambda) { bool result = true; CUDFcoefficient l = lambda * lambda_crit; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(l); return result; } // Initialize integer variables (from criteria set) void agregate_combiner::initialize_intvars() { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize_intvars(); } mccs-1.1/sources/agregate_combiner.h0000600017777601777760000000366211574427503017421 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: agregate_combiner.h */ /* a concrete class for an agregate combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __AGREGATE_COMBINER_H #define __AGREGATE_COMBINER_H #include // Concrete class to agregate a set of criteria i.e. handle it as sum \lambda_i c_i // Note: such an agregate could be seen either as a combiner or a criteria class agregate_combiner: public abstract_combiner, public abstract_criteria { public: CriteriaList *criteria; // set of criteria to agregate abstract_solver *solver; // used solver // ******************************************************** // Seen as a combiner int column_allocation(int first_rank); int objective_generation(); int constraint_generation(); // ******************************************************** // Seen as a criteria int set_variable_range(int first_free_var); int add_criteria_to_objective(CUDFcoefficient lambda); int add_criteria_to_constraint(CUDFcoefficient lambda); int add_constraints(); // computing combiner/criteria ranges/bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // does this combiner/criteria allows problem reduction bool can_reduce(); bool can_reduce(CUDFcoefficient lambda); // initialization void initialize(CUDFproblem *problem, abstract_solver *solver); void initialize_intvars(); // lambda coefficient for the current combiner/criteria CUDFcoefficient lambda_crit ; // agregate combiner creation agregate_combiner(CriteriaList *criteria) { this->lambda_crit = 1; this->criteria = criteria; }; agregate_combiner(CriteriaList *criteria, CUDFcoefficient lambda_crit) { this->criteria = criteria; this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/changed_criteria.c0000600017777601777760000001133711574427503017230 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: changed_criteria.c */ /* Implementation of the changed criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include // Criteria initialization void changed_criteria::initialize(CUDFproblem *problem, abstract_solver *solver) { this->problem = problem; this->solver = solver; range = ub = lb = 0; for (CUDFVirtualPackageListIterator ivpkg = problem->all_virtual_packages->begin(); ivpkg != problem->all_virtual_packages->end(); ivpkg++) { int size = (*ivpkg)->all_versions.size(); if (size > 0) { all_versioned_virtual_packages.push_back((*ivpkg)); if (size == 1) { CUDFVersionedPackage *pkg = *((*ivpkg)->all_versions.begin()); if (pkg->installed) { if (criteria_opt_var) lb--; else range++; } else ub++; } else range++; } } } // Computing the number of columns required to handle the criteria int changed_criteria::set_variable_range(int first_free_var) { this->first_free_var = first_free_var; return first_free_var + range; } // Add the criteria to the current objective function int changed_criteria::add_criteria_to_objective(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = all_versioned_virtual_packages.begin(); ivpkg != all_versioned_virtual_packages.end(); ivpkg++) if ((*ivpkg)->all_versions.size() == 1) { CUDFVersionedPackage *pkg = *((*ivpkg)->all_versions.begin()); if (pkg->installed) { if (criteria_opt_var) solver->set_obj_coeff(pkg, - lambda_crit * lambda + solver->get_obj_coeff(pkg)); else solver->set_obj_coeff(ivpkg_rank++, lambda_crit * lambda); } else solver->set_obj_coeff(pkg, lambda_crit * lambda + solver->get_obj_coeff(pkg)); } else solver->set_obj_coeff(ivpkg_rank++, lambda_crit * lambda); return 0; } // Add the criteria to the constraint set int changed_criteria::add_criteria_to_constraint(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = all_versioned_virtual_packages.begin(); ivpkg != all_versioned_virtual_packages.end(); ivpkg++) if ((*ivpkg)->all_versions.size() == 1) { CUDFVersionedPackage *pkg = *((*ivpkg)->all_versions.begin()); if (pkg->installed) { if (criteria_opt_var) solver->set_constraint_coeff(pkg, - lambda_crit * lambda + solver->get_obj_coeff(pkg)); else solver->set_constraint_coeff(ivpkg_rank++, lambda_crit * lambda); } else solver->set_constraint_coeff(pkg, lambda_crit * lambda + solver->get_constraint_coeff(pkg)); } else solver->set_constraint_coeff(ivpkg_rank++, lambda_crit * lambda); return 0; } // Add the constraints required by the criteria int changed_criteria::add_constraints() { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = all_versioned_virtual_packages.begin(); ivpkg != all_versioned_virtual_packages.end(); ivpkg++) { int m = 0, n = (*ivpkg)->all_versions.size(); solver->new_constraint(); if (n == 1) { if (! criteria_opt_var) { CUDFVersionedPackage *pkg = *((*ivpkg)->all_versions.begin()); if (pkg->installed) { solver->set_constraint_coeff(pkg->rank, +1); solver->set_constraint_coeff(ivpkg_rank++, +1); solver->add_constraint_eq(1); } } } else { for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) if ((*vers_pkg)->installed) { solver->set_constraint_coeff((*vers_pkg)->rank, -1); m++; } else solver->set_constraint_coeff((*vers_pkg)->rank, +1); solver->set_constraint_coeff(ivpkg_rank, -1); solver->add_constraint_geq(-m); solver->new_constraint(); for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) if ((*vers_pkg)->installed) solver->set_constraint_coeff((*vers_pkg)->rank, -1); else solver->set_constraint_coeff((*vers_pkg)->rank, +1); solver->set_constraint_coeff(ivpkg_rank, -n); solver->add_constraint_leq(-m); ivpkg_rank++; } } return 0; } // Compute the criteria range CUDFcoefficient changed_criteria::bound_range() { return CUDFabs(lambda_crit) * (ub - lb); } // Compute the criteria upper bound CUDFcoefficient changed_criteria::upper_bound() { if (lambda_crit >= 0) return lambda_crit * ub; else return lambda_crit * lb; } // Compute the criteria lower bound CUDFcoefficient changed_criteria::lower_bound() { if (lambda_crit >= 0) return lambda_crit * lb; else return lambda_crit * ub; } mccs-1.1/sources/changed_criteria.h0000600017777601777760000000377511574427503017244 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: changed_criteria.h */ /* Concrete class for the changed criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _CHANGED_CRITERIA_H_ #define _CHANGED_CRITERIA_H_ #include // A concrete class for the changed criteria // i.e. number of virtual packages whose set of // installed/uninstalled versions has changed // between the initial configuration and the final one class changed_criteria: public abstract_criteria { public: CUDFproblem *problem; // a pointer to the problem abstract_solver *solver; // a pointer to the solver // list of all virtual packages which have a version CUDFVirtualPackageList all_versioned_virtual_packages; // lower and upper bound and range of the criteria CUDFcoefficient ub, lb; int range; // column of the first variable used by the criteria int first_free_var; // Allocate some columns for the criteria int set_variable_range(int first_free_var); // Add the criteria to the objective int add_criteria_to_objective(CUDFcoefficient lambda); // Add the criteria to the constraint set int add_criteria_to_constraint(CUDFcoefficient lambda); // Add constraints required by the criteria int add_constraints(); // Compute the criteria range, upper and lower bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // Does the criteria allows problem reductions bool can_reduce(CUDFcoefficient lambda) { return ((lambda >= 0) && (lambda_crit >= 0)); } // Criteria initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lambda multiplier for the criteria CUDFcoefficient lambda_crit ; // Criteria initialization changed_criteria() { this->lambda_crit = +1; }; changed_criteria(CUDFcoefficient lambda_crit) { this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/combiner.h0000600017777601777760000000126211574427503015554 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: combiner.h */ /* gather all combiner related include files */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __COMBINER_H #define __COMBINER_h #include #include #include #include #include #include #include #include #include #include #include #endif mccs-1.1/sources/constraint_generation.c0000600017777601777760000005642311574427503020361 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: constraint_generation.c */ /* constraint generation for cudf problems */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // translate a CUDF problem in a MILP problem #include bool generate_desagregate_constraints = true; bool generate_agregate_constraints = false; int new_var = 0; // set of requested upgrades vector upgrades; // check if pkg belongs to a list of providers bool is_in_provl(const CUDFVersionedPackage *pkg, CUDFProviderList *provl) { for (CUDFVersionedPackageListIterator ipkg = provl->begin(); ipkg != provl->end(); ipkg++) if ((*ipkg) == pkg) return true; return false; } // check if pkg belongs to a list of removed packages bool is_in_remove(const CUDFVersionedPackage *pkg, CUDFVersionedPackageList *remove_set) { for (CUDFVersionedPackageListIterator ipkg = remove_set->begin(); ipkg != remove_set->end(); ipkg++) if ((*ipkg) == pkg) return true; return false; } // check if pkg, version belongs to a sublist of providers bool is_in_versioned_providers(const CUDFVersionedPackage *pkg, const CUDFVersion version, const CUDFVersionedProviderListIterator vpbegin, const CUDFVersionedProviderListIterator vpend) { CUDFVersionedProviderListIterator ivp = vpbegin; while (ivp != vpend) { if (ivp->first != version) for (CUDFProviderListIterator kpkg = ivp->second.begin(); kpkg != ivp->second.end(); kpkg++) if ((*kpkg) == pkg) return true; ivp++; } return false; } // preprocess an upgrade request to insure that only one version can be installed int preprocess_upgrade(CUDFproblem *problem) { if (problem->upgrade != (CUDFVpkgList *)NULL) { int firstvarrank = problem->all_packages->size(); for (CUDFVpkgListIterator ipkgop = problem->upgrade->begin(); ipkgop != problem->upgrade->end(); ipkgop++) { int nb_new_var = 0; CUDFVersionedPackageList remove_set; CUDFVersionedProviderList upgrade_set; CUDFVirtualPackage *vpackage = (*ipkgop)->virtual_package; CUDFVersion highest_version = vpackage->highest_installed_provider_version; CUDFVersionedPackageSetIterator iverpkg = vpackage->all_versions.begin(); CUDFVersionedPackageSetIterator iverpkgend = vpackage->all_versions.end(); CUDFVersionedProviderListIterator iprov = vpackage->versioned_providers.begin(); CUDFVersionedProviderListIterator iprovend = vpackage->versioned_providers.end(); if (vpackage->highest_installed != (CUDFVersionedPackage *)NULL) if (vpackage->highest_installed->version > highest_version) highest_version = vpackage->highest_installed->version; // even if not installed, it seems that we have to upgrade ... // If nothing is installed ... it cannot be upgraded ... // if (highest_version == 0) continue; // Remove all the "all versions" providers for (CUDFProviderListIterator jprov = vpackage->providers.begin(); jprov != vpackage->providers.end(); jprov++) remove_set.push_back(*jprov); // Remove all packages with version lower than hver for (; (iverpkg != iverpkgend) && ((*iverpkg)->version < highest_version); iverpkg++) remove_set.push_back(*iverpkg); // The same for versioned providers for (; (iprov != iprovend) && (iprov->first < highest_version); iprov++) for (CUDFProviderListIterator kpkg = iprov->second.begin(); kpkg != iprov->second.end(); kpkg++) remove_set.push_back(*kpkg); // Upgrade highest_version version packages ... this does not seems to be right ... // the highest installed version package has also to go through the filters /* { CUDFProviderList hverpkgs; if ((iverpkg != vpackage->all_versions.end()) && ((*iverpkg)->version == highest_version) && (! is_in_remove(*iverpkg, &remove_set)) && (! is_in_versioned_providers(*iverpkg, (*iverpkg)->version, iprov, iprovend))) { hverpkgs.push_back(*iverpkg); iverpkg++; } if ((iprov != iprovend) && (iprov->first == highest_version)) { for (CUDFProviderListIterator kpkg = iprov->second.begin(); kpkg != iprov->second.end(); kpkg++) if (! is_in_versioned_providers(*kpkg, iprov->first, iprov, iprovend)) if (! is_in_provl(*kpkg, &hverpkgs)) hverpkgs.push_back(*kpkg); iprov++; } if (hverpkgs.size() > 0) { upgrade_set.insert(CUDFVersionedProviderList::value_type(highest_version, hverpkgs)); if (hverpkgs.size() > 1) nb_new_var++; } } */ a_compptr comp = get_comparator((*ipkgop)->op); while ((iverpkg != iverpkgend) || (iprov != iprovend)) { CUDFProviderList provl; CUDFVersion version = 0; if (iverpkg != iverpkgend) version = (*iverpkg)->version; if ((iprov != iprovend) && (version < iprov->first)) version = iprov->first; if ((iverpkg != iverpkgend) && ((*iverpkg)->version == version)) { if (comp(version, (*ipkgop)->version)) { if (! is_in_remove(*iverpkg, &remove_set)) { if (is_in_versioned_providers(*iverpkg, (*iverpkg)->version, iprov, iprovend)) remove_set.push_back(*iverpkg); else provl.push_back(*iverpkg); } } else if (! is_in_remove(*iverpkg, &remove_set)) remove_set.push_back(*iverpkg); iverpkg++; } if ((iprov != iprovend) && (iprov->first == version)) { if (comp(version, (*ipkgop)->version)) { for (CUDFProviderListIterator kpkg = iprov->second.begin(); kpkg != iprov->second.end(); kpkg++) if (! is_in_remove(*kpkg, &remove_set)) { if (is_in_versioned_providers(*kpkg, iprov->first, iprov, iprovend) || ((*kpkg)->virtual_package == vpackage)) remove_set.push_back(*kpkg); else if (! is_in_provl(*kpkg, &provl)) provl.push_back(*kpkg); } } else { for (CUDFProviderListIterator kpkg = iprov->second.begin(); kpkg != iprov->second.end(); kpkg++) if (! is_in_remove(*kpkg, &remove_set)) remove_set.push_back(*kpkg); } iprov++; } if (provl.size() > 0) { upgrade_set.insert(CUDFVersionedProviderList::value_type(version, provl)); if (provl.size() > 1) nb_new_var++; } } // if ((remove_set.size() != 0) || (upgrade_set.size() != 0)) { if (upgrade_set.size() != 0) { upgrades.push_back(an_upgrade_set(nb_new_var, firstvarrank, remove_set, upgrade_set)); new_var += nb_new_var; firstvarrank += nb_new_var; } else { // We need somethin to upgrade to ... printf("Cannot upgrade to %s.\n", vpackage->name); return -1; } } } return 0; } // Generate MILP objective function(s) and constraints for a given solver // and a given criteria combination int generate_constraints(CUDFproblem *problem, abstract_solver &solver, abstract_combiner &combiner) { int nb_packages = problem->all_packages->size(); int nb_vpackages = problem->all_virtual_packages->size(); int nb_vars; vector keep_package_handled(nb_vpackages, false); CUDFVirtualPackageList installed_vpkgs_mv; CUDFVirtualPackageList installed_vpkgs_uv; if (nb_packages == 0) { // we lack a problem then ... fprintf(stderr, "generate_constraints: no declared package !\n"); exit(-1); } //---------------------------------------------------------------------------------------------------- // Objective function if (preprocess_upgrade(problem) != 0) return -1; // Trying to upgrade non existent package nb_vars = nb_packages + new_var; nb_vars = combiner.column_allocation(nb_vars); solver.init_solver(problem->all_packages, nb_vars - nb_packages); solver.begin_objectives(); combiner.objective_generation(); solver.end_objectives(); //---------------------------------------------------------------------------------------------------- // Constraints generation solver.begin_add_constraints(); combiner.constraint_generation(); // Install if (problem->install != (CUDFVpkgList *)NULL) { for (CUDFVpkgListIterator ipkgop = problem->install->begin(); ipkgop != problem->install->end(); ipkgop++) { CUDFVirtualPackage *vpackage = (*ipkgop)->virtual_package; a_compptr comp = get_comparator((*ipkgop)->op); bool has_pkg = false; solver.new_constraint(); if (vpackage->all_versions.size() > 0) // Install P = install one version of P for (CUDFVersionedPackageSetIterator ipkg = vpackage->all_versions.begin(); ipkg != vpackage->all_versions.end(); ipkg++) if (use_pkg(*ipkg) && (comp((*ipkg)->version, (*ipkgop)->version))) { has_pkg = true; solver.set_constraint_coeff(*ipkg, +1); } if (vpackage->providers.size() > 0) // or install one of the providers of P for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if (use_pkg(*jpkg) && (solver.get_constraint_coeff(*jpkg) == 0)) { has_pkg = true; solver.set_constraint_coeff(*jpkg, +1); } // or install one of the providers with the right version for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (comp(jpkg->first, (*ipkgop)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if (use_pkg(*kpkg) && (solver.get_constraint_coeff(*kpkg) == 0)) { has_pkg = true; solver.set_constraint_coeff(*kpkg, +1); } if (has_pkg) solver.add_constraint_geq(+1); else return -1; // Cannot install this pkg } } // Remove if (problem->remove != (CUDFVpkgList *)NULL) { for (CUDFVpkgListIterator ipkgop = problem->remove->begin(); ipkgop != problem->remove->end(); ipkgop++) { CUDFVirtualPackage *vpackage = (*ipkgop)->virtual_package; a_compptr comp = get_comparator((*ipkgop)->op); bool has_pkg = false; if (generate_agregate_constraints) { solver.new_constraint(); if (vpackage->all_versions.size() > 0) // Remove all the versions of the package for (CUDFVersionedPackageSetIterator ipkg = vpackage->all_versions.begin(); ipkg != vpackage->all_versions.end(); ipkg++) if (use_pkg(*ipkg) && (comp((*ipkg)->version, ((*ipkgop)->version)))) { has_pkg = true; solver.set_constraint_coeff(*ipkg, +1); } if (vpackage->providers.size() > 0) // as well as all the providers for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if (use_pkg(*jpkg) && (solver.get_constraint_coeff(*jpkg) == 0)) { has_pkg = true; solver.set_constraint_coeff(*jpkg, +1); } // as well as all the versioned providers with the right version for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (comp(jpkg->first, (*ipkgop)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if (use_pkg(*kpkg) && (solver.get_constraint_coeff(*kpkg) == 0)) { has_pkg = true; solver.set_constraint_coeff(*kpkg, +1); } if (has_pkg) solver.add_constraint_eq(0); } if (generate_desagregate_constraints) { if (vpackage->all_versions.size() > 0) // Remove all the versions of the package for (CUDFVersionedPackageSetIterator ipkg = vpackage->all_versions.begin(); ipkg != vpackage->all_versions.end(); ipkg++) if (use_pkg(*ipkg) && (comp((*ipkg)->version, ((*ipkgop)->version)))) { solver.new_constraint(); solver.set_constraint_coeff(*ipkg, +1); solver.add_constraint_eq(0); } if (vpackage->providers.size() > 0) // as well as all the providers for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if (use_pkg(*jpkg)) { solver.new_constraint(); solver.set_constraint_coeff(*jpkg, +1); solver.add_constraint_eq(0); } // as well as all the versioned providers with the right version for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (comp(jpkg->first, (*ipkgop)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if (use_pkg(*kpkg)) { solver.new_constraint(); solver.set_constraint_coeff(*kpkg, +1); solver.add_constraint_eq(0); } } } } // Upgrade : There can be only one VERSION of (already_installed with higher version, + accepted by criteria and > higher version) installed, // all other removed // WARNING: Providers not handled here ... if (upgrades.size() > 0) { for (vector::iterator iup = upgrades.begin(); iup != upgrades.end(); iup++) { // Remove packages belonging to upgrades remove set if (generate_agregate_constraints) { solver.new_constraint(); for (CUDFVersionedPackageListIterator ipkg = (*iup).remove_set.begin(); ipkg != (*iup).remove_set.end(); ipkg++) { if (solver.get_constraint_coeff(*ipkg) == 0) solver.set_constraint_coeff(*ipkg, +1); //printf("upgrade => remove %s\n", (*ipkg)->name); } solver.add_constraint_eq(0); } if (generate_desagregate_constraints) { for (CUDFVersionedPackageListIterator ipkg = (*iup).remove_set.begin(); ipkg != (*iup).remove_set.end(); ipkg++) { solver.new_constraint(); solver.set_constraint_coeff(*ipkg, +1); solver.add_constraint_eq(0); } } // Force the installation of the upgraded packages int var_rank = (*iup).first_var_rank; bool has_mvp = false; solver.new_constraint(); for (CUDFVersionedProviderListIterator ivpl = (*iup).upgrade_set.begin(); ivpl != (*iup).upgrade_set.end(); ivpl++) if (ivpl->second.size() == 1) solver.set_constraint_coeff(ivpl->second.front(), +1); else { has_mvp = true; solver.set_constraint_coeff(var_rank++, +1); } solver.add_constraint_eq(1); if (has_mvp) { int var_rank = (*iup).first_var_rank; int size; for (CUDFVersionedProviderListIterator ivpl = (*iup).upgrade_set.begin(); ivpl != (*iup).upgrade_set.end(); ivpl++) if ((size = ivpl->second.size()) > 1) { solver.new_constraint(); for (CUDFProviderListIterator kpkg = ivpl->second.begin(); kpkg != ivpl->second.end(); kpkg++) solver.set_constraint_coeff(*kpkg, +1); solver.set_constraint_coeff(var_rank, -1); solver.add_constraint_geq(0); solver.new_constraint(); for (CUDFProviderListIterator kpkg = ivpl->second.begin(); kpkg != ivpl->second.end(); kpkg++) solver.set_constraint_coeff(*kpkg, -1); solver.set_constraint_coeff(var_rank, size); solver.add_constraint_geq(0); var_rank++; } } } } // Handling packages constraints if (problem->all_packages->size() > 0) for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) { // Depends if ((*ipkg)->depends != (CUDFVpkgFormula *)NULL) { // Conjunction of dependencies for (CUDFVpkgFormulaIterator anddeps = (*ipkg)->depends->begin(); anddeps != (*ipkg)->depends->end(); anddeps++) { bool self_depend = false; bool has_coeff = false; solver.new_constraint(); // Disjunction of dependencies for (CUDFVpkgListIterator ordeps = (*anddeps)->begin(); ordeps != (*anddeps)->end(); ordeps++) { CUDFVirtualPackage *vpackage = (*ordeps)->virtual_package; a_compptr comp = get_comparator((*ordeps)->op); // It depends from all the right versions of the package if (vpackage->all_versions.size() > 0) { for (CUDFVersionedPackageSetIterator jpkg = vpackage->all_versions.begin(); jpkg != vpackage->all_versions.end(); jpkg++) if (comp((*jpkg)->version, (*ordeps)->version)) { if ((*jpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; has_coeff = false; break; } else if (use_pkg(*jpkg)) { has_coeff = true; solver.set_constraint_coeff(*jpkg, +1); } } } // as well as from all the providers if ((! self_depend) && (vpackage->providers.size() > 0)) { for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if ((*jpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; has_coeff = false; break; } else if (use_pkg(*jpkg)) { has_coeff = true; solver.set_constraint_coeff(*jpkg, +1); } } // as well as from all the versioned providers with the right version if (! self_depend) for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (self_depend) break; else if (comp(jpkg->first, (*ordeps)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if ((*kpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; has_coeff = false; break; } else if (use_pkg(*kpkg)) { has_coeff = true; solver.set_constraint_coeff(*kpkg, +1); } } if (has_coeff) { solver.set_constraint_coeff(*ipkg, -1); solver.add_constraint_geq(0); } else if (!self_depend) { // The package depends on a not available package => force it to 0 solver.set_constraint_coeff(*ipkg, 1); solver.add_constraint_eq(0); } } } // Conflicts if ((*ipkg)->conflicts != (CUDFVpkgList *)NULL) { if (generate_agregate_constraints) { int nb_coeff = 0; solver.new_constraint(); for (CUDFVpkgListIterator ipkgop = (*ipkg)->conflicts->begin(); ipkgop != (*ipkg)->conflicts->end(); ipkgop++) { CUDFVirtualPackage *vpackage = (*ipkgop)->virtual_package; a_compptr comp = get_comparator((*ipkgop)->op); if (vpackage->all_versions.size() > 0) { // It conflicts with all the right versions of the package for (CUDFVersionedPackageSetIterator jpkg = vpackage->all_versions.begin(); jpkg != vpackage->all_versions.end(); jpkg++) if (use_pkg(*jpkg) && ((*jpkg) != (*ipkg)) && (comp((*jpkg)->version, (*ipkgop)->version))&& (solver.get_constraint_coeff(*jpkg) == 0)) { solver.set_constraint_coeff(*jpkg, -1); nb_coeff++; } } // as well as with all the providers if (vpackage->providers.size() > 0) { for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if (use_pkg(*jpkg) && ((*jpkg) != (*ipkg)) && (solver.get_constraint_coeff(*jpkg) == 0)) { solver.set_constraint_coeff(*jpkg, -1); nb_coeff++; } } // as well as with all the versioned providers with the right version for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (comp(jpkg->first, (*ipkgop)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if (use_pkg(*kpkg) && ((*kpkg) != (*ipkg)) && (solver.get_constraint_coeff(*kpkg) == 0)) { solver.set_constraint_coeff(*kpkg, -1); nb_coeff++; } } if (nb_coeff > 0) { solver.set_constraint_coeff(*ipkg, -nb_coeff); solver.add_constraint_geq(-nb_coeff); } } if (generate_desagregate_constraints) { for (CUDFVpkgListIterator ipkgop = (*ipkg)->conflicts->begin(); ipkgop != (*ipkg)->conflicts->end(); ipkgop++) { CUDFVirtualPackage *vpackage = (*ipkgop)->virtual_package; a_compptr comp = get_comparator((*ipkgop)->op); if (vpackage->all_versions.size() > 0) { // It conflicts with all the right versions of the package for (CUDFVersionedPackageSetIterator jpkg = vpackage->all_versions.begin(); jpkg != vpackage->all_versions.end(); jpkg++) if (use_pkg(*jpkg) && ((*jpkg) != (*ipkg)) && (comp((*jpkg)->version, (*ipkgop)->version))) { solver.new_constraint(); solver.set_constraint_coeff(*jpkg, 1); solver.set_constraint_coeff(*ipkg, 1); solver.add_constraint_leq(1); } } // as well as with all the providers if (vpackage->providers.size() > 0) { for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if (use_pkg(*jpkg) && ((*jpkg) != (*ipkg))) { solver.new_constraint(); solver.set_constraint_coeff(*jpkg, 1); solver.set_constraint_coeff(*ipkg, 1); solver.add_constraint_leq(1); } } // as well as with all the versioned providers with the right version for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (comp(jpkg->first, (*ipkgop)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if (use_pkg(*kpkg) && ((*kpkg) != (*ipkg))) { solver.new_constraint(); solver.set_constraint_coeff(*kpkg, 1); solver.set_constraint_coeff(*ipkg, 1); solver.add_constraint_leq(1); } } } } // Keep (if and only if installed) if ((*ipkg)->installed) switch((*ipkg)->keep) { case keep_none: break; case keep_feature: // Preserve all the provided features if ((*ipkg)->provides != (CUDFVpkgList *)NULL) { for (CUDFVpkgListIterator ipkgop = (*ipkg)->provides->begin(); ipkgop != (*ipkg)->provides->end(); ipkgop++) { CUDFVirtualPackage *vpackage = (*ipkgop)->virtual_package; a_compptr comp = get_comparator((*ipkgop)->op); bool has_coeff = false; solver.new_constraint(); if (vpackage->all_versions.size() > 0) for (CUDFVersionedPackageSetIterator jpkg = vpackage->all_versions.begin(); jpkg != vpackage->all_versions.end(); jpkg++) if (use_pkg(*jpkg) && (comp((*jpkg)->version, (*ipkgop)->version))) { has_coeff = true; solver.set_constraint_coeff(*jpkg, +1); } if (vpackage->providers.size() > 0) for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if (use_pkg(*jpkg) && (solver.get_constraint_coeff(*jpkg) == 0)) { has_coeff = true; solver.set_constraint_coeff(*jpkg, +1); } for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (comp(jpkg->first, (*ipkgop)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if (use_pkg(*kpkg) && (solver.get_constraint_coeff(*kpkg) == 0)) { has_coeff = true; solver.set_constraint_coeff(*kpkg, +1); } if (has_coeff) solver.add_constraint_geq(+1); } } break; case keep_package: // Preserve at least one version of the package if (((*ipkg)->virtual_package->all_versions.size() > 0) && (! keep_package_handled[(*ipkg)->virtual_package->rank+1])) { CUDFVirtualPackage *vpackage = (*ipkg)->virtual_package; bool has_coeff = false; solver.new_constraint(); if (vpackage->all_versions.size() > 0) // Should not make sense for (CUDFVersionedPackageSetIterator jpkg = vpackage->all_versions.begin(); jpkg != vpackage->all_versions.end(); jpkg++) if (use_pkg(*jpkg)) { has_coeff = true; solver.set_constraint_coeff(*jpkg, +1); } solver.add_constraint_geq(+1); keep_package_handled[(*ipkg)->virtual_package->rank+1] = true; } break; case keep_version: // Preserve the current version solver.new_constraint(); solver.set_constraint_coeff(*ipkg, +1); solver.add_constraint_eq(+1); break; } } solver.end_add_constraints(); return 0; } mccs-1.1/sources/constraint_generation.h0000600017777601777760000000435311574427503020361 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: constraint_generation.h */ /* constraint generation for cudf problems */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // #ifndef _CONSTRAINT_GENERATION_H_ #define _CONSTRAINT_GENERATION_H_ #include #include #include #include #include extern bool generate_desagregate_constraints; extern bool generate_agregate_constraints; // class used to manage set of upgrade requests class an_upgrade_set { public: int nb_new_var; int first_var_rank; CUDFVersionedPackageList remove_set; CUDFVersionedProviderList upgrade_set; an_upgrade_set(int nbv, int fvr, CUDFVersionedPackageList rs, CUDFVersionedProviderList us) { nb_new_var = nbv; first_var_rank = fvr; remove_set = rs; upgrade_set = us; } }; extern int new_var; // set of requested upgrades extern vector upgrades; // constructor for int valued properties extern bool is_in_provl(const CUDFVersionedPackage *pkg, CUDFProviderList *provl); // check if pkg belongs to a list of removed packages extern bool is_in_remove(const CUDFVersionedPackage *pkg, CUDFVersionedPackageList *remove_set); // check if pkg, version belongs to a sublist of providers extern bool is_in_versioned_providers(const CUDFVersionedPackage *pkg, const CUDFVersion version, const CUDFVersionedProviderListIterator vpbegin, const CUDFVersionedProviderListIterator vpend); // preprocess an upgrade request to insure version unicity extern int preprocess_upgrade(); // available criteria #define CRIT_DEFAULT 1 #define CRIT_CONSERVATIVE 2 #define CRIT_FRESHER 3 #define CRIT_SFRESHER 4 #define CRIT_FFRESHER 5 #define CRIT_TFRESHER 5 #define CRIT_PARANOID 6 #define CRIT_TRENDY 7 #define CRIT_TRENDY2 8 #define CRIT_LEXPARANOID 9 #define CRIT_LEXTRENDY 10 #define CRIT_LEXTRENDY2 11 // main function for constraint generation (translate a CUDF problem into MILP problem for a given solver and a given criteria) extern int generate_constraints(CUDFproblem *problem, abstract_solver &solver, abstract_combiner &combiner); #endif mccs-1.1/sources/count_criteria.c0000600017777601777760000001143111574427503016762 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: count_criteria.c */ /* Implementation of the count criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // Count a property quantity #include // Check property availability void count_criteria::check_property(CUDFproblem *problem) { CUDFPropertiesIterator prop = problem->properties->find(string(property_name)); has_property = false; if (prop == problem->properties->end()) printf("WARNING: cannot find \"%s\" property definition: criteria count not used.\n", property_name); else switch ((*prop).second->type_id) { case pt_int: case pt_nat: case pt_posint: has_property = true; break; default: printf("WARNING: Property \"%s\" has wrong type: type must be an int, a nat or a posint. Criteria count not used.\n", property_name); } } // Criteria initialization void count_criteria::initialize(CUDFproblem *problem, abstract_solver *solver) { this->problem = problem; this->solver = solver; ub = lb = 0; if (has_property) { CUDFPropertiesIterator prop = problem->properties->find(string(property_name)); default_value = 0; if ((*prop).second->default_value != ((CUDFPropertyValue *)NULL)) switch ((*prop).second->default_value->property->type_id) { case pt_int: case pt_nat: case pt_posint: default_value = lambda_crit * (*prop).second->default_value->intval; break; default: break; } if (verbosity > 2) printf("count criteria default value for %s = "CUDFflags"\n", property_name, default_value); for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) { if (onlynew && (*ipkg)->installed) continue; bool got_property = false; for (CUDFPropertyValueListIterator propval = (*ipkg)->properties.begin(); propval != (*ipkg)->properties.end(); propval++) if ((*propval)->property == (*prop).second) { CUDFcoefficient value = lambda_crit * (*propval)->intval; if (value < 0) lb += value; else ub += value; got_property = true; break; } if (! got_property) { if (default_value < 0) lb += default_value; else ub += default_value; } } } } // Computing the number of columns required to handle the criteria int count_criteria::set_variable_range(int first_free_var) { return first_free_var; } // Add the criteria to the current objective function int count_criteria::add_criteria_to_objective(CUDFcoefficient lambda) { if (has_property) { CUDFPropertiesIterator prop = problem->properties->find(string(property_name)); for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) { if (onlynew && (*ipkg)->installed) continue; bool got_property = false; for (CUDFPropertyValueListIterator propval = (*ipkg)->properties.begin(); propval != (*ipkg)->properties.end(); propval++) if ((*propval)->property == (*prop).second) { CUDFcoefficient value = lambda_crit * (*propval)->intval; solver->set_obj_coeff(*ipkg, lambda * value + solver->get_obj_coeff(*ipkg)); got_property = true; break; } if ((! got_property) && (default_value != 0)) solver->set_obj_coeff(*ipkg, lambda * default_value + solver->get_obj_coeff(*ipkg)); } } return 0; } // Add the criteria to the constraint set int count_criteria::add_criteria_to_constraint(CUDFcoefficient lambda) { if (has_property) { CUDFPropertiesIterator prop = problem->properties->find(string(property_name)); for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) { if (onlynew && (*ipkg)->installed) continue; bool got_property = false; for (CUDFPropertyValueListIterator propval = (*ipkg)->properties.begin(); propval != (*ipkg)->properties.end(); propval++) if ((*propval)->property == (*prop).second) { CUDFcoefficient value = lambda_crit * (*propval)->intval; solver->set_constraint_coeff(*ipkg, lambda * value + solver->get_constraint_coeff(*ipkg)); got_property = true; break; } if ((! got_property) && (default_value != 0)) solver->set_constraint_coeff(*ipkg, lambda * default_value + solver->get_constraint_coeff(*ipkg)); } } return 0; } // Add the constraints required by the criteria int count_criteria::add_constraints() { return 0; } // Compute the criteria range CUDFcoefficient count_criteria::bound_range() { return (ub - lb); } // Compute the criteria upper bound CUDFcoefficient count_criteria::upper_bound() { return ub; } // Compute the criteria lower bound CUDFcoefficient count_criteria::lower_bound() { return lb; } mccs-1.1/sources/count_criteria.h0000600017777601777760000000457311574427503017000 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: count_criteria.h */ /* Concrete class for the count criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // Count a property quantity #ifndef _COUNT_CRITERIA_H_ #define _COUNT_CRITERIA_H_ #include // A concrete class for the count criteria // i.e. a criteria that count the value of a property // of installed virtual packages class count_criteria: public abstract_criteria { public: CUDFproblem *problem; // a pointer to the problem abstract_solver *solver; // a pointer to the solver char *property_name; // name of the property bool has_property; // is the property available ? // list of all versioned packages which have the property CUDFVersionedPackageList *versioned_pkg_with_property; CUDFcoefficient default_value; // default property value // lower and upper bound of the criteria CUDFcoefficient lb, ub; // Allocate some columns for the criteria int set_variable_range(int first_free_var); // Add the criteria to the objective int add_criteria_to_objective(CUDFcoefficient lambda); // Add the criteria to the constraint set int add_criteria_to_constraint(CUDFcoefficient lambda); // Add constraints required by the criteria int add_constraints(); // Compute the criteria range, upper and lower bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // Does the criteria allows problem reductions bool can_reduce(CUDFcoefficient lambda) { return ((lambda >= 0) && (lambda_crit >= 0)); } // Criteria initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // Check property void check_property(CUDFproblem *problem); // lambda multiplier for the criteria CUDFcoefficient lambda_crit ; // True iff reduced to newly installed versioned packages bool onlynew; // Criteria initialization count_criteria(char *property_name) { this->property_name = property_name; this->lambda_crit = +1; }; // Criteria initialization count_criteria(char *property_name, bool onlynew, CUDFcoefficient lambda_crit) { this->property_name = property_name; this->lambda_crit = lambda_crit; this->onlynew = onlynew; }; }; #endif mccs-1.1/sources/cplex_solver.c0000600017777601777760000003143211616262132016450 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cplex_solver.c */ /* Interface to the CPLEX solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #define OUTPUT_MODEL 1 #define USEXNAME 0 // solver creation abstract_solver *new_cplex_solver() { return new cplex_solver(); } // solver initialisation // requires the list of versioned packages and the total amount of variables (including additional ones) int cplex_solver::init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars) { int status; nb_packages = all_versioned_packages->size(); this->all_versioned_packages = all_versioned_packages; // Coefficient initialization initialize_coeffs(nb_packages + other_vars); /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); if ( env == NULL ) { char errmsg[1024]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); exit(-1); } /* Enhance EPGAP to handle big values correctly */ status = CPXsetdblparam (env, CPX_PARAM_EPGAP, 0.0); if ( status ) { fprintf (stderr, "Failure to set EPGAP, error %d.\n", status); exit(-1); } /* Limit the number of thread to 1 */ status = CPXsetintparam (env, CPX_PARAM_THREADS, 1); if ( status ) { fprintf (stderr, "Failure to set thread limit to 1, error %d.\n", status); exit(-1); } if (verbosity > 1) { /* Turn on output to the screen */ status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); exit(-1); } if (verbosity > 2) { /* MIP node log display information */ status = CPXsetintparam (env, CPX_PARAM_MIPDISPLAY, 5); if ( status ) { fprintf (stderr, "Failure to turn off presolve, error %d.\n", status); exit(-1); } } } /* Create the problem. */ lp = CPXcreateprob (env, &status, "lpex1"); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPX_PARAM_SCRIND causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); exit(-1); } first_objective = 0; lb = (double *)malloc(nb_vars*sizeof(double)); ub = (double *)malloc(nb_vars*sizeof(double)); vartype = (char *)malloc(nb_vars*sizeof(char)); varname = (char **)malloc(nb_vars*sizeof(char *)); if ((lb == (double *)NULL) || (ub == (double *)NULL) || (vartype == (char *)NULL) || (varname == (char **)NULL)) { fprintf(stderr, "cplex_solver: initialization: not enough memory.\n"); exit(-1); } // Set package variable names int i = 0; for (CUDFVersionedPackageListIterator ipkg = all_versioned_packages->begin(); ipkg != all_versioned_packages->end(); ipkg++) { lb[i] = 0; ub[i] = 1; vartype[i] = 'B'; if (USEXNAME) { char *name; char buffer[20]; sprintf(buffer, "x%d", i); if ((name = (char *)malloc(strlen(buffer)+1)) == (char *)NULL) { fprintf(stderr, "CUDF error: can not alloc memory for variable name in cplex_solver::end_objective.\n"); exit(-1); } strcpy(name, buffer); varname[(*ipkg)->rank] = name; } else varname[(*ipkg)->rank] = (*ipkg)->versioned_name; i++; } // Set additional variable names for (i = nb_packages; i < nb_vars; i++) { char *name; char buffer[20]; sprintf(buffer, "x%d", i); if ((name = (char *)malloc(strlen(buffer)+1)) == (char *)NULL) { fprintf(stderr, "CUDF error: can not alloc memory for variable name in cplex_solver::end_objective.\n"); exit(-1); } strcpy(name, buffer); lb[i] = 0; ub[i] = 1; vartype[i] = 'B'; varname[i] = name; } return 0; } // cplex can handle integer variables bool cplex_solver::has_intvars() { return true; } // set integer variable range (must be used before end_objective) int cplex_solver::set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper) { lb[rank] = lower; ub[rank] = upper; vartype[rank] = 'I'; return 0; }; // Just write the lp problem in a file int cplex_solver::writelp(char *filename) { return CPXwriteprob (env, lp, filename, NULL); } // solve the current problem int cplex_solver::solve() { int nb_objectives = objectives.size(); int mipstat, status; // Presolving the problem if (CPXpresolve(env, lp, CPX_ALG_NONE)) return 0; // Solve the objectives in a lexical order for (int i = first_objective; i < nb_objectives; i++) { // Solve the mip problem if (CPXmipopt (env, lp)) return 0; // Get solution status if ((mipstat = CPXgetstat(env, lp)) == CPXMIP_OPTIMAL) { if (i < nb_objectives - 1) { // Get next non empty objective // (must be done here to avoid conflicting method calls int previ = i, nexti, nexti_nb_coeffs = 0; for (; i < nb_objectives - 1; i++) { nexti = i + 1; nexti_nb_coeffs = objectives[nexti]->nb_coeffs; if (nexti_nb_coeffs > 0) break; } if (nexti_nb_coeffs > 0) { // there is one more objective to solve // Set objective constraint value to objval int index[1]; double values[1]; index[0] = previ; values[0] = objective_value(); if (verbosity > 0) printf(">>>> Objective value %d = %f\n", previ, values[0]); { int status, begin[2]; double rhs[1]; begin[0] = 0; rhs[0] = values[0]; //ub; int n = objectives[previ]->nb_coeffs; begin[1] = n - 1; status = CPXaddrows(env, lp, 0, 1, n, rhs, "E", begin, objectives[previ]->sindex, objectives[previ]->coefficients, NULL, NULL); if (status) { fprintf(stderr, "cplex_solver: end_objective: cannot add %d objective as constraint.\n", i); exit(-1); } } // Set the new objective value reset_coeffs(); // Set previous objective coefficients to zero for (int k = 0; k < objectives[previ]->nb_coeffs; k++) set_coeff(objectives[previ]->sindex[k], 0); // Set next objective coefficients to their actual values for (int k = 0; k < nexti_nb_coeffs; k++) set_coeff(objectives[nexti]->sindex[k], objectives[nexti]->coefficients[k]); // Do set the next objective status = CPXchgobj(env, lp, nb_coeffs, sindex, coefficients); if ( status ) { fprintf (stderr,"Cannot change objective value. Exiting...\n"); exit(-1); } // Output model to file (when requested) if (OUTPUT_MODEL) { char buffer[1024]; sprintf(buffer, "cplexpbs%d.lp", i); CPXwriteprob (env, lp, buffer, NULL); } } else return 1; } else return 1; } else { if (verbosity > 2) fprintf(stderr, "CPLEX solution status = %d\n", mipstat); return 0; } } return 0; } // return the objective value CUDFcoefficient cplex_solver::objective_value() { double objval; int status = CPXgetobjval (env, lp, &objval); if (status) { fprintf (stderr,"No MIP objective value available. Exiting...\n"); exit(-1); } // printf("Objective value = % 24.24e\n", objval); return (CUDFcoefficient)nearbyint(objval); } // solution initialisation int cplex_solver::init_solutions() { int status; int cur_numcols = CPXgetnumcols (env, lp); if (solution != (double *)NULL) free(solution); if ((solution = (double *)malloc(nb_vars*sizeof(double))) == (double *)NULL) { fprintf (stderr, "cplex_solver: init_solutions: cannot get enough memory to store solutions.\n"); exit(-1); } status = CPXgetx (env, lp, solution, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "cplex_solver: init_solutions: failed to get solutions.\n"); exit(-1); } return 0; } // get the computed status of a package (0 = uninstalled, 1 = installed) CUDFcoefficient cplex_solver::get_solution(CUDFVersionedPackage *package) { return (CUDFcoefficient)nearbyint(solution[package->rank]); } CUDFcoefficient cplex_solver::get_solution(int k) { return (CUDFcoefficient)nearbyint(solution[k]); } // initialize the objective function int cplex_solver::begin_objectives(void) { // Set Problem as a minimization problem CPXchgobjsen (env, lp, CPX_MIN); return 0; } // return the objective function coefficient of a package CUDFcoefficient cplex_solver::get_obj_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // return the objective function coefficient of a rank CUDFcoefficient cplex_solver::get_obj_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set the objective function coefficient of a package int cplex_solver::set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set the objective function coefficient of a ranked variable int cplex_solver::set_obj_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; }; // initialize an additional objective function int cplex_solver::new_objective(void) { reset_coeffs(); return 0; } // add an additional objective function int cplex_solver::add_objective(void) { push_obj(); return 0; } // ends up objective function construction int cplex_solver::end_objectives(void) { if (objectives.size() > 0) { int status = 0, nb_coeffs = 0; // Set the first objective as the actual objective for (int k = 0; k < nb_vars; k++) coefficients[k] = 0; for (; first_objective < (int)objectives.size(); first_objective++) if ((nb_coeffs = objectives[first_objective]->nb_coeffs) > 0) break; if (nb_coeffs > 0) for (int k = 0; k < nb_coeffs; k++) coefficients[objectives[first_objective]->sindex[k]] = objectives[first_objective]->coefficients[k]; else if (first_objective == (int)objectives.size()) first_objective--; // So that we solve at least one pbs status = CPXnewcols (env, lp, nb_vars, coefficients, lb, ub, vartype, varname); if (status) { fprintf(stderr, "cplex_solver: end_objective: cannot create objective function.\n"); exit(-1); } } return 0; } // initialize constraint declaration int cplex_solver::begin_add_constraints(void) { return 0; } // begin the declaration of a new constraint int cplex_solver::new_constraint(void) { reset_coeffs(); return 0; } // return the coefficient value of a package CUDFcoefficient cplex_solver::get_constraint_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // return the coefficient value of a package CUDFcoefficient cplex_solver::get_constraint_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set the coeffcient value of a package int cplex_solver::set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set the coefficient value of a ranked variable int cplex_solver::set_constraint_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // add constraint under construction as a greater or equal constraint int cplex_solver::add_constraint_geq(CUDFcoefficient bound) { if (nb_coeffs > 0) { int status, begin[2]; double rhs[1]; begin[0] = 0; begin[1] = nb_coeffs; rhs[0] = bound; status = CPXaddrows(env, lp, 0, 1, nb_coeffs, rhs, "G", begin, sindex, coefficients, NULL, NULL); if (status) { fprintf(stderr, "cplex_solver: add_constraint_geq: cannot create geq constraint.\n"); exit(-1); } } return 0; } // add constraint under construction as a less or equal constraint int cplex_solver::add_constraint_leq(CUDFcoefficient bound) { if (nb_coeffs > 0) { int status, begin[2]; double rhs[1]; begin[0] = 0; begin[1] = nb_coeffs; rhs[0] = bound; status = CPXaddrows(env, lp, 0, 1, nb_coeffs, rhs, "L", begin, sindex, coefficients, NULL, NULL); if (status) { fprintf(stderr, "cplex_solver: add_constraint_leq: cannot create leq constraint.\n"); exit(-1); } } return 0; } // add constraint under construction as an equal constraint int cplex_solver::add_constraint_eq(CUDFcoefficient bound) { if (nb_coeffs > 0) { int status, begin[2]; double rhs[1]; begin[0] = 0; begin[1] = nb_coeffs; rhs[0] = bound; status = CPXaddrows(env, lp, 0, 1, nb_coeffs, rhs, "E", begin, sindex, coefficients, NULL, NULL); if (status) { fprintf(stderr, "cplex_solver: add_constraint_eq: cannot create eq constraint.\n"); exit(-1); } } return 0; } // ends up constraint declaration int cplex_solver::end_add_constraints(void) { if (OUTPUT_MODEL) CPXwriteprob (env, lp, "cplexpbs.lp", NULL); return 0; } mccs-1.1/sources/cplex_solver.h0000600017777601777760000000734211574427503016470 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cplex_solver.h */ /* Concrete class for the cplex solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // concrete class which implements an interface to CPLEX solver #ifndef _CPLEX_SOLVER_H #define _CPLEX_SOLVER_H #include #include #include class cplex_solver: public abstract_solver, public scoeff_solver { public: // Solver initialization int init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars); // Does the solver use integer variables bool has_intvars(); // Allocate some columns for integer variables int set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper); // Init the objective function definitions int begin_objectives(void); // Get current objective coefficient of package CUDFcoefficient get_obj_coeff(CUDFVersionedPackage *package); // Get current objective coefficient of a column CUDFcoefficient get_obj_coeff(int rank); // Set current objective coefficient of package int set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current objective coefficient of column int set_obj_coeff(int rank, CUDFcoefficient value); // Begin the definition of a new objective int new_objective(void); // Add current objective to the set of objectives int add_objective(void); // End objective definitions int end_objectives(void); // Init constraint definitions int begin_add_constraints(void); // Begin the definition of a new constraint int new_constraint(void); // Get current constraint coefficient of a package CUDFcoefficient get_constraint_coeff(CUDFVersionedPackage *package); // Get current constraint coefficient of a column CUDFcoefficient get_constraint_coeff(int rank); // Set current constraint coefficient of a package int set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current constraint coefficient of a column int set_constraint_coeff(int rank, CUDFcoefficient value); // Add current constraint as a more or equal constraint int add_constraint_geq(CUDFcoefficient bound); // Add current constraint as a less or equal constraint int add_constraint_leq(CUDFcoefficient bound); // Add current constraint as a equality constraint int add_constraint_eq(CUDFcoefficient bound); // End constraint definitions int end_add_constraints(void); // Write the lp on a file int writelp(char *filename); // Solve the problem int solve(); // Get the objective value (final one) CUDFcoefficient objective_value(); // Init solutions (required before calling get_solution) int init_solutions(); // Get the solution for a package CUDFcoefficient get_solution(CUDFVersionedPackage *package); // Get the solution for a column CUDFcoefficient get_solution(int k); // variables only for internal use (should be private) CPXENVptr env; // cplex environment CPXLPptr lp; // cplex linear program CUDFVersionedPackageList *all_versioned_packages; // a pointer to the list of versioned packages int nb_packages; // number of packages int first_objective; double *cplex_coeff; // cplex coefficients are doubles ... double *lb; // array of lower bounds double *ub; // array of upper bounds char *vartype; // array of variable types char **varname; // array of variable names // Store the solutions double *solution; // solver creation cplex_solver(void) { all_versioned_packages = (CUDFVersionedPackageList *)NULL; solution = (double *)NULL; } }; #endif mccs-1.1/sources/criteria.h0000600017777601777760000000127511577461600015563 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: criteria.h */ /* gather all criteria related include files */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _CRITERIA_H_ #define _CRITERIA_H_ #include #include #include #include #include #include #include #include #include #include #include #include #endif mccs-1.1/sources/cudf.c0000600017777601777760000007405211613556176014704 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cud.c */ /* main of the cudf solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #include #include #include #include #include #include // underlying solver declaration // allows using solvers withour having to include the whole solver classes extern abstract_solver *new_lp_solver(char *lpsolver); extern abstract_solver *new_pblib_solver(char *pbsolver); //extern abstract_solver *new_ampl_solver(char *amplsolver); #ifdef USECPLEX extern abstract_solver *new_cplex_solver(); #endif #ifdef USEGUROBI extern abstract_solver *new_gurobi_solver(); #endif #ifdef USELPSOLVE extern abstract_solver *new_lpsolve_solver(); #endif #ifdef USEGLPK extern abstract_solver *new_glpk_solver(bool use_exact); #endif bool criteria_opt_var = false; // print cudf help void print_help() { fprintf(stderr, "This software is distributed under a modified BSD licence (see LICENCE file) and was\n" "partially supported by the European Community's 7th Framework Programme (FP7/2007-2013),\n" "MANCOOSI project, grant agreement n. 214898.\n"); fprintf(stderr, "Usual call: mccs -i -o [{, }*] ?\n"); fprintf(stderr, "file options:\n"); fprintf(stderr, " -i : set the input file to (by default attempt to read on stdin)\n"); fprintf(stderr, " -o : set the output file to (by default write on stdout)\n"); fprintf(stderr, "solver options:\n"); #ifdef USECPLEX fprintf(stderr, " -cplex: use IBM ILOG Cplex solver\n"); #endif #ifdef USEGUROBI fprintf(stderr, " -gurobi: use Gurobi solver\n"); #endif #ifdef USELPSOLVE fprintf(stderr, " -lpsolve: use lpsolve solver\n"); #endif #ifdef USEGLPK fprintf(stderr, " -glpk: use glpk solver\n"); #endif fprintf(stderr, " -lp : use lp (cplex format) solver (tested with scip and cbc)\n"); fprintf(stderr, " -pblib : use pseudo boolean solver \n"); fprintf(stderr, " -nosolve: do not solve the problem (for debug purpose)\n"); fprintf(stderr, "constraint generation options:\n"); fprintf(stderr, " -noreduce: do not reduce the initial problem\n"); fprintf(stderr, " -only-agregate-constraints: generate only agregate constraints\n"); fprintf(stderr, " -only-desagregate-constraints: generate only deagregate constraints (default)\n"); fprintf(stderr, " -all-constraints: generate all kind of constraints (insure redundancy)\n"); fprintf(stderr, "combining criteria:\n"); fprintf(stderr, " -lexicographic[{,}*]\n"); fprintf(stderr, " with ::= {+,-}leximax[{,}*] |\n"); fprintf(stderr, " {+,-}leximin[{,}*] |\n"); fprintf(stderr, " \n"); fprintf(stderr, " with ::= {+,-}agregate[{,}*]{[lambda]}? |\n"); fprintf(stderr, " {+,-}lexagregate[{,}*]{[lambda]}? |\n"); fprintf(stderr, " \n"); fprintf(stderr, " with ::= {+,-}removed{[lambda]}? | # number of removed packages \n"); fprintf(stderr, " {+,-}changed{[lambda]}? | # number of package with a modified version\n"); fprintf(stderr, " {+,-}notuptodate{[lambda]}? | # number of no uptodate packages\n"); fprintf(stderr, " {+,-}new{[lambda]}? | # number of newly installed packages\n"); fprintf(stderr, " {+,-}nunsat[,]{[lambda]}? | # number of unsatisfied dijunct in property (must be a vpkgformula)\n"); fprintf(stderr, " where is a property name of type vpkgformula\n"); fprintf(stderr, " and is a boolean (true or false) telling whether providers have to be taken into account\n"); fprintf(stderr, " {+,-}count[,]{[lambda]}? # count the property quantity (must be an int, posint or nat) \n"); fprintf(stderr, " where is a property name of type int, nat or posint\n"); fprintf(stderr, " and is a boolean (true or false) telling whether count applies only on newly installed packages\n"); fprintf(stderr, " {+,-}unaligned[]{[lambda]}? # count the number of unaligned packages \n"); fprintf(stderr, " where is either packages, pairs, clusters or changes\n"); fprintf(stderr, " eg.: -lexicographic[-removed,-notuptodate,-nunsat[recommends:,true],-new]\n"); fprintf(stderr, " eg.: -lexicographic[-lexagregate[-removed,-notuptodate],-lexagregate[-nunsat[recommends:,true],-new]]\n"); fprintf(stderr, " WARNING: spaces can not be used within a criteria combination.\n"); fprintf(stderr, "criteria combination shortcuts:\n"); fprintf(stderr, " -lex[{,}*] equivalent to -lexicographic[{,}*]\n"); fprintf(stderr, " -lexagregate[{,}*] equivalent to -lex[-lexagregate[{,}*]]\n"); fprintf(stderr, " -lexsemiagregate[{,}*] equivalent to \n"); fprintf(stderr, " -lex[-lexagregate[,],-lexagregate[,],...]\n"); fprintf(stderr, " -agregate[{,}*] equivalent to -lex[-agregate[{,}*]]\n"); fprintf(stderr, " -leximax[{,}*] equivalent to -lex[-leximax[{,}*]]\n"); fprintf(stderr, " -leximin[{,}*] equivalent to -lex[-lexmin[{,}*]]\n"); fprintf(stderr, " -lexleximax[{,}*] equivalent to -lex[,-leximax[{,}*]]\n"); fprintf(stderr, " -lexleximin[{,}*] equivalent to -lex[,-leximin[{,}*]]\n"); fprintf(stderr, " eg.: -agregate[-removed[100],-notuptodate[50],-nunsat[recommends:,true][10],-new]\n"); fprintf(stderr, "other options:\n"); fprintf(stderr, " -fo: full solution output\n"); fprintf(stderr, " -v: set verbosity level to n\n"); fprintf(stderr, " -h: print this help\n"); } // Basic user defined criteria option handling int get_criteria_options(char *crit_descr, unsigned int &pos, vector< pair *> *opts) { if (crit_descr[pos] == '[') { int nb_read = 0; unsigned int start = ++pos; for (; pos < strlen(crit_descr); pos++) switch(crit_descr[pos]) { case '[': crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: criteria options: found '[' within criteria options: %s.\n", crit_descr); exit(-1); break; case ']': { unsigned int length = pos - start; if (length == 0) { crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: criteria options: found empty criteria option: %s.\n", crit_descr); exit(-1); } opts->push_back(new pair(start, length)); nb_read++; pos++; // ignore ending ']' return nb_read; } break; case ',': { unsigned int length = pos - start; if (length == 0) { crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: criteria options: found empty criteria option: %s.\n", crit_descr); exit(-1); } opts->push_back(new pair(start, length)); nb_read++; start = ++pos; } break; } fprintf(stderr, "ERROR: criteria options: criteria options ended without an ending ']': %s.\n", crit_descr); exit(-1); } return 0; } // Get user defined weight for a criteria CUDFcoefficient get_criteria_lambda(char *crit_descr, unsigned int &pos, char sign) { CUDFcoefficient lambda = 1; vector< pair *> opts; int n = get_criteria_options(crit_descr, pos, &opts); if (n == 1) { unsigned int start = opts[0]->first; unsigned int length = opts[0]->second; for (unsigned int i = 0; i < length; i++) if ((crit_descr[start+i] < '0') || (crit_descr[start+i] > '9')) { crit_descr[start+i+1] = '\0'; fprintf(stderr, "ERROR: criteria options: a lambda value must be an integer int: %s\n", crit_descr); exit(-1); } if (sscanf(crit_descr+start, CUDFflags, &lambda) != 1) { crit_descr[start+length+1] = '\0'; fprintf(stderr, "ERROR: criteria options: a lambda value is espected here: %s\n", crit_descr); exit(-1); } } else if (n > 1) { crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: criteria options: a lambda value is espected here: %s\n", crit_descr); exit(-1); } if (sign == '+') lambda *= -1; return lambda; } // Get property name from a user defined criteria char *get_criteria_property_name(char *crit_descr, unsigned int &pos) { vector< pair *> opts; char *property = (char *)NULL; int n = get_criteria_options(crit_descr, pos, &opts); if (n == 1) { unsigned int start = opts[0]->first; unsigned int length = opts[0]->second; if (crit_descr[start+length-1] != ':') { crit_descr[start+length] = '\0'; fprintf(stderr, "ERROR: criteria options: a property name must end with a ':': %s\n", crit_descr); exit(-1); } if ((property = (char *)malloc((length+1)*sizeof(char))) == (char *)NULL) { fprintf(stderr, "ERROR: criteria options: not enough memory to store property name.\n"); exit(-1); } strncpy(property, crit_descr+start, length); property[length] = '\0'; } else { crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: criteria options: a property name is required here: %s\n", crit_descr); exit(-1); } return property; } // Get unaligned criteria parameters int get_unaligned_criteria_params(char *crit_descr, unsigned int &pos) { vector< pair *> opts; int alignment = 0; int n = get_criteria_options(crit_descr, pos, &opts); if (n == 1) { unsigned int start = opts[0]->first; unsigned int length = opts[0]->second; if (strncmp("packages", crit_descr+start, length) == 0) alignment = ALIGNED_PACKAGES; else if (strncmp("pairs", crit_descr+start, length) == 0) alignment = ALIGNED_PAIRS; else if (strncmp("clusters", crit_descr+start, length) == 0) alignment = ALIGNED_CLUSTERS; else if (strncmp("changes", crit_descr+start, length) == 0) alignment = ALIGNED_CHANGES; } else { crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: unaligned criteria options: either packages, pairs, clusters or changes required here: %s\n", crit_descr); exit(-1); } return alignment; } // Get name and boolean options from user defined criteria char *get_criteria_property_name_and_bool(char *crit_descr, unsigned int &pos, bool &value) { vector< pair *> opts; char *property = (char *)NULL; int n = get_criteria_options(crit_descr, pos, &opts); if (n == 2) { unsigned int start = opts[0]->first; unsigned int length = opts[0]->second; if (crit_descr[start+length-1] != ':') { crit_descr[start+length] = '\0'; fprintf(stderr, "ERROR: criteria options: a property name must end with a ':': %s\n", crit_descr); exit(-1); } if ((property = (char *)malloc((length+1)*sizeof(char))) == (char *)NULL) { fprintf(stderr, "ERROR: criteria options: not enough memory to store property name.\n"); exit(-1); } strncpy(property, crit_descr+start, length); property[length] = '\0'; start = opts[1]->first; length = opts[1]->second; if ((length == 4) && (crit_descr[start+0] == 't') && (crit_descr[start+1] == 'r') && (crit_descr[start+2] == 'u') && (crit_descr[start+3] == 'e')) value = true; else if ((length == 5) && (crit_descr[start+0] == 'f') && (crit_descr[start+1] == 'a') && (crit_descr[start+2] == 'l') && (crit_descr[start+3] == 's') && (crit_descr[start+4] == 'e')) value = false; else { crit_descr[start+length] = '\0'; fprintf(stderr, "ERROR: criteria options: a boolean is required here (either 'true' or 'false'): %s\n", crit_descr); exit(-1); } } else { crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: criteria options: a property name and a booleen are required here: %s\n", crit_descr); exit(-1); } return property; } unaligned_criteria *unalignedc = (unaligned_criteria *)NULL; // temp // Process a user defined criteria CriteriaList *process_criteria(char *crit_descr, unsigned int &pos, bool first_level, vector *criteria_with_property) { CriteriaList *criteria = new CriteriaList(); if (crit_descr[pos] == '[') { for (pos += 1; pos < strlen(crit_descr) && crit_descr[pos] != ']';) { unsigned int sign, crit_name, crit_name_length; // check for criteria sense switch (crit_descr[pos]) { case '+': case '-': sign = pos++; crit_name = pos; break; default: fprintf(stderr, "ERROR: criteria options: a criteria description must begin with a sign which gives its sense (- = min, + = max): %s\n", crit_descr+pos); exit(-1); break; } // look for end of criteria name for (; pos < strlen(crit_descr); pos++) { char c = crit_descr[pos]; if ((c == ',') || (c == '[') || (c == ']')) break; } crit_name_length = pos - crit_name; // handle criteria if (strncmp(crit_descr+crit_name, "removed", crit_name_length) == 0) { criteria->push_back(new removed_criteria(get_criteria_lambda(crit_descr, pos, crit_descr[sign]))); } else if (strncmp(crit_descr+crit_name, "changed", crit_name_length) == 0) { criteria->push_back(new changed_criteria(get_criteria_lambda(crit_descr, pos, crit_descr[sign]))); } else if (strncmp(crit_descr+crit_name, "new", crit_name_length) == 0) { criteria->push_back(new new_criteria(get_criteria_lambda(crit_descr, pos, crit_descr[sign]))); } else if (strncmp(crit_descr+crit_name, "notuptodate", crit_name_length) == 0) { criteria->push_back(new notuptodate_criteria(get_criteria_lambda(crit_descr, pos, crit_descr[sign]))); } else if (strncmp(crit_descr+crit_name, "nunsat", crit_name_length) == 0) { bool with_providers = true; char *property_name = get_criteria_property_name_and_bool(crit_descr, pos, with_providers); if (property_name != (char *)NULL) { abstract_criteria *crit = new nunsat_criteria(property_name, with_providers, get_criteria_lambda(crit_descr, pos, crit_descr[sign])); criteria_with_property->push_back(crit); criteria->push_back(crit); } } else if (strncmp(crit_descr+crit_name, "count", crit_name_length) == 0) { bool onlynew = false; char *property_name = get_criteria_property_name_and_bool(crit_descr, pos, onlynew); if (property_name != (char *)NULL) { abstract_criteria *crit = new count_criteria(property_name, onlynew, get_criteria_lambda(crit_descr, pos, crit_descr[sign])); criteria_with_property->push_back(crit); criteria->push_back(crit); } } else if (strncmp(crit_descr+crit_name, "unaligned", crit_name_length) == 0) { int alignment = get_unaligned_criteria_params(crit_descr, pos); if (alignment > 0) { abstract_criteria *crit = unalignedc = new unaligned_criteria(alignment, (char *)"source:", (char *)"sourceversion:", (char *)"number:", get_criteria_lambda(crit_descr, pos, crit_descr[sign])); criteria->push_back(crit); criteria_with_property->push_back(crit); } } else if (strncmp(crit_descr+crit_name, "agregate", crit_name_length) == 0) { criteria->push_back(new agregate_combiner(process_criteria(crit_descr, pos, false, criteria_with_property), get_criteria_lambda(crit_descr, pos, crit_descr[sign]))); } else if (strncmp(crit_descr+crit_name, "lexagregate", crit_name_length) == 0) { criteria->push_back(new lexagregate_combiner(process_criteria(crit_descr, pos, false, criteria_with_property), get_criteria_lambda(crit_descr, pos, crit_descr[sign]))); } else if (strncmp(crit_descr+crit_name, "leximax", crit_name_length) == 0) { if (crit_descr[sign] == '-') criteria->push_back(new leximax_combiner(process_criteria(crit_descr, pos, false, criteria_with_property))); else criteria->push_back(new leximin_combiner(process_criteria(crit_descr, pos, false, criteria_with_property))); } else if (strncmp(crit_descr+crit_name, "leximin", crit_name_length) == 0) { if (crit_descr[sign] == '-') criteria->push_back(new leximin_combiner(process_criteria(crit_descr, pos, false, criteria_with_property))); else criteria->push_back(new leximax_combiner(process_criteria(crit_descr, pos, false, criteria_with_property))); } else { crit_descr[pos] = '\0'; fprintf(stderr, "ERROR: criteria options: this is not a criteria: %s\n", crit_descr+crit_name); exit(-1); } if (crit_descr[pos] == ',') pos++; // skip comma } } else { fprintf(stderr, "ERROR: criteria options: a criteria list must begin with a '[': %s\n", crit_descr+pos); exit(-1); } pos++; return criteria; } // Handling user criteria definitions CriteriaList *get_criteria(char *crit_descr, bool first_level, vector *criteria_with_property) { unsigned int pos = 0; return process_criteria(crit_descr, pos, first_level, criteria_with_property); } // main CUDF function int main(int argc, char *argv[]) { FILE *output_file = (FILE *)NULL; FILE *output_installed = (FILE *)NULL; FILE *output_removed = (FILE *)NULL; abstract_solver *solver = (abstract_solver *)NULL; abstract_combiner *combiner = (abstract_combiner *)NULL; bool nosolve = false; bool got_input = false; bool fulloutput = false; CUDFproblem *problem; vector criteria_with_property; // parameter handling if (argc > 1) for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-i") == 0) { i++; if (i < argc) { FILE *input_file = (FILE *)NULL; if ((input_file = fopen(argv[i], "r")) == (FILE *)NULL) { fprintf(stderr, "ERROR: cannot open file %s as input file.\n", argv[i]); exit(-1); } else { got_input = true; switch (parse_cudf(input_file)) { case 0: break; case 1: fprintf(stderr, "ERROR: invalid input in problem.\n"); exit(-1); case 2: fprintf(stderr, "ERROR: parser memory issue.\n"); exit(-1); } fclose(input_file); } } } else if (strcmp(argv[i], "-o") == 0) { i++; if (i < argc) { if ((output_file = fopen(argv[i], "w")) == (FILE *)NULL) { fprintf(stderr, "ERROR: cannot open file %s as ouput file.\n", argv[i]); exit(-1); } } } else if (strcmp(argv[i], "-fo") == 0) { fulloutput = true; } else if (strncmp(argv[i], "-v", 2) == 0) { sscanf(argv[i]+2, "%u", &verbosity); } else if (strcmp(argv[i], "-only-agregate-constraints") == 0) { generate_agregate_constraints = true; generate_desagregate_constraints = false; } else if (strcmp(argv[i], "-only-desagregate-constraints") == 0) { generate_agregate_constraints = false; generate_desagregate_constraints = true; } else if (strcmp(argv[i], "-all-constraints") == 0) { generate_agregate_constraints = true; generate_desagregate_constraints = true; } else if (strcmp(argv[i], "-cov") == 0) { criteria_opt_var = true; } else if (strcmp(argv[i], "-noreduce") == 0) { use_reduced = false; } else if (strncmp(argv[i], "-lex[", 5) == 0) { CriteriaList *criteria = get_criteria(argv[i]+4, true, &criteria_with_property); if (criteria->size() > 0) combiner = new lexicographic_combiner(criteria); else { fprintf(stderr, "ERROR: -lex option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-lexicographic[", 15) == 0) { CriteriaList *criteria = get_criteria(argv[i]+14, true, &criteria_with_property); if (criteria->size() > 0) combiner = new lexicographic_combiner(criteria); else { fprintf(stderr, "ERROR: -lexicographic option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-agregate[", 10) == 0) { CriteriaList *criteria = get_criteria(argv[i]+9, false, &criteria_with_property); if (criteria->size() > 0) combiner = new agregate_combiner(criteria); else { fprintf(stderr, "ERROR: -agregate option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-lexagregate[", 13) == 0) { CriteriaList *criteria = get_criteria(argv[i]+12, false, &criteria_with_property); if (criteria->size() > 0) combiner = new lexagregate_combiner(criteria); else { fprintf(stderr, "ERROR: -lexagregate option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-lexsemiagregate[", 17) == 0) { CriteriaList *criteria = get_criteria(argv[i]+16, false, &criteria_with_property); if (criteria->size() > 0) combiner = new lexsemiagregate_combiner(criteria); else { fprintf(stderr, "ERROR: -lexsemiagregate option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-leximax[", 9) == 0) { CriteriaList *criteria = get_criteria(argv[i]+8, false, &criteria_with_property); if (criteria->size() > 0) combiner = new leximax_combiner(criteria); else { fprintf(stderr, "ERROR: -leximax option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-leximin[", 9) == 0) { CriteriaList *criteria = get_criteria(argv[i]+8, false, &criteria_with_property); if (criteria->size() > 0) combiner = new leximin_combiner(criteria); else { fprintf(stderr, "ERROR: -leximin option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-lexleximax[", 12) == 0) { CriteriaList *criteria = get_criteria(argv[i]+11, false, &criteria_with_property); if (criteria->size() > 0) combiner = new lexleximax_combiner(criteria); else { fprintf(stderr, "ERROR: -lexleximax option requires a list of criteria.\n"); exit(-1); } } else if (strncmp(argv[i], "-lexleximin[", 12) == 0) { CriteriaList *criteria = get_criteria(argv[i]+11, false, &criteria_with_property); if (criteria->size() > 0) combiner = new lexleximin_combiner(criteria); else { fprintf(stderr, "ERROR: -lexleximin option requires a list of criteria.\n"); exit(-1); } } else if (strcmp(argv[i], "-h") == 0) { print_help(); exit(-1); } else if (strcmp(argv[i], "-nosolve") == 0) { nosolve = true; } else if (strcmp(argv[i], "-lp") == 0) { if (++i < argc) { struct stat sts; if (stat(argv[i], &sts) == -1 && errno == ENOENT) { fprintf(stderr, "ERROR: -lp option require a lp solver: -lp and %s does not exist.\n", argv[i]); exit(-1); } else solver = new_lp_solver(argv[i]); } else { fprintf(stderr, "ERROR: -lp option require a lp solver: -lp \n"); exit(-1); } } else if (strcmp(argv[i], "-pblib") == 0) { if (++i < argc) { struct stat sts; if (stat(argv[i], &sts) == -1 && errno == ENOENT) { fprintf(stderr, "ERROR: -pblib option require a PB solver: -pblib and %s does not exist.\n", argv[i]); exit(-1); } else solver = new_pblib_solver(argv[i]); } else { fprintf(stderr, "ERROR: -pblib option require a PB solver: -pblib \n"); exit(-1); } #ifdef USECPLEX } else if (strcmp(argv[i], "-cplex") == 0) { solver = new_cplex_solver(); #endif #ifdef USEGUROBI } else if (strcmp(argv[i], "-gurobi") == 0) { solver = new_gurobi_solver(); #endif #ifdef USELPSOLVE } else if (strcmp(argv[i], "-lpsolve") == 0) { solver = new_lpsolve_solver(); #endif #ifdef USEGLPK } else if (strcmp(argv[i], "-glpk") == 0) { solver = new_glpk_solver(false); #endif } else { fprintf(stderr, "ERROR: unrecognized option %s\n", argv[i]); exit(-1); } } // if (input_file == (FILE *)NULL) input_file = stdin; if (output_file == (FILE *)NULL) output_file = stdout; // if no input file defined, then use stdin if (! got_input) { switch (parse_cudf(stdin)) { case 0: break; case 1: fprintf(stderr, "ERROR: invalid input in problem.\n"); exit(-1); case 2: fprintf(stderr, "ERROR: parser memory issue.\n"); exit(-1); } } // if whished, print out the read problem if (verbosity > 2) { fprintf(stdout, "================================================================\n"); if (properties.size() > 0) { fprintf(stdout, "preamble:\n"); print_properties(stdout, &properties); fprintf(stdout, "\n"); } fprintf(stdout, "# %d versioned packages:\n\n", (int)all_packages.size()); for (CUDFVersionedPackageListIterator ipkg = all_packages.begin(); ipkg != all_packages.end(); ipkg++) print_versioned_package(stdout, *ipkg, false); print_problem(stdout, the_problem); fprintf(stdout, "================================================================\n"); fprintf(stdout, "%d virtual packages:\n\n", (int)all_virtual_packages.size()); for (CUDFVirtualPackageListIterator vpkg = all_virtual_packages.begin(); vpkg != all_virtual_packages.end(); vpkg++) print_virtual_package(stdout, *vpkg); fprintf(stdout, "================================================================\n"); } // choose the solver if (solver == (abstract_solver *)NULL) #ifdef USECPLEX solver = new_cplex_solver(); #else #ifdef USEGLPK solver = new_glpk_solver(false); #else #ifdef USELPSOLVE solver = new_lpsolve_solver(); #else { fprintf(stderr, "ERROR: no solver defined\n"); exit(-1); } #endif #endif #endif // check criteria properties for (vector::iterator icrit = criteria_with_property.begin(); icrit != criteria_with_property.end(); icrit++) (*icrit)->check_property(the_problem); // default combiner if (combiner == (abstract_combiner *)NULL) { CriteriaList *criteria = new CriteriaList(); criteria->push_back(new removed_criteria()); combiner = new lexicographic_combiner(criteria); } // reduce the problem (if use_reduced is true) if (combiner->can_reduce()) { if (verbosity > 0) fprintf(stdout, "Can reduce graph.\n"); } else { use_reduced = false; if (verbosity > 0) fprintf(stdout, "Can NOT reduce graph.\n"); } problem = compute_reduced_CUDF(the_problem); // combiner initialization combiner->initialize(problem, solver); // temp if ((verbosity > 2) && (unalignedc == (unaligned_criteria *)NULL)) { unalignedc = new unaligned_criteria(ALIGNED_CHANGES, (char *)"source:", (char *)"sourceversion:", (char *)"number:", 1); unalignedc->check_property(the_problem); unalignedc->initialize(problem, solver); } // generate the constraints, solve the problem and print out the solutions if ((problem->all_packages->size() > 0) && (generate_constraints(problem, *solver, *combiner) == 0) && (! nosolve) && (solver->solve())) { solver->init_solutions(); double obj = solver->objective_value(); if (verbosity > 2) { fprintf(stdout, "================================================================\n"); printf("Objective value: %f\n", obj); for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) printf("%s = "CUDFflags"\n", (*ipkg)->versioned_name, solver->get_solution(*ipkg)); fprintf(stdout, "================================================================\n"); fprintf(output_file, "\n"); } if (verbosity > 2) { output_installed = fopen("installed.txt", "w"); output_removed = fopen("removed.txt", "w"); } if (properties.size() > 0) { fprintf(output_file, "\npreamble: \n"); print_properties(output_file, problem->properties); fprintf(output_file, "\n\n"); } // printing out CUDF solution int nb_installed = 0; int nb_removed = 0; int nb_newinstalled = 0; for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) { if (solver->get_solution(*ipkg)) { nb_installed++; if (! (*ipkg)->installed) { nb_newinstalled++; if (output_installed != (FILE *)NULL) print_versioned_package_as_installed(output_installed, (*ipkg), true); } print_versioned_package_as_installed(output_file, (*ipkg), true); } else { if (fulloutput) print_versioned_package_with_install(output_file, (*ipkg), 0, true); if ((*ipkg)->installed) { nb_removed++; if (output_removed != (FILE *)NULL) print_versioned_package(output_removed, (*ipkg), true); } } } if ((verbosity > 2) && (unalignedc != (unaligned_criteria *)NULL)) unalignedc->display_struct(); // temp if (verbosity > 2) { fclose(output_installed); fclose(output_removed); } // print out additional informations fprintf(output_file, "# problem = %zu packages (%zu virtual packages), %zu installed packages.\n", all_packages.size(), all_virtual_packages.size(), installed_packages.size()); fprintf(output_file, "# request = %zu install, %zu remove, %zu upgrade.\n", (problem->install == (CUDFVpkgList *)NULL)?0:problem->install->size(), (problem->remove == (CUDFVpkgList *)NULL)?0:problem->remove->size(), (problem->upgrade == (CUDFVpkgList *)NULL)?0:problem->upgrade->size()); fprintf(output_file, "# solution = %d installed packages, %d new installed, %d has been removed.\n", nb_installed, nb_newinstalled, nb_removed); fprintf(output_file, "# objective value = %f.\n", obj); if (verbosity > 0) printf(">>>> Objective value = %f.\n", obj); } else { if (verbosity > 0) fprintf(stdout, "================================================================\n"); fprintf(stdout, "No solution found.\n"); fprintf(output_file, "FAIL\n"); fprintf(output_file, "No solution found.\n"); } exit(0); } mccs-1.1/sources/cudf_reductions.c0000600017777601777760000001436311574427503017137 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf_reduction.c */ /* Implementation of problem reductions */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include bool use_reduced = true; // should we reduce the problem vector process_properties; // set of property to process // Add the virtual package of a vpkglist to the reduced problem void add_vpkgs_from_vpkglist(list &lvpkg, CUDFVpkgList *vpkglist) { for (CUDFVpkgListIterator ivpkg = vpkglist->begin(); ivpkg != vpkglist->end(); ivpkg++) { CUDFVirtualPackage *vpkg = (*ivpkg)->virtual_package; if ((vpkg != (CUDFVirtualPackage *)NULL) && (! vpkg->in_reduced)) lvpkg.push_back(vpkg); } } // Process a vpkgformula (from a depends) adding the related virtual packages to the new problem void add_vpkgs_from_vpkgformula(list &lvpkg, CUDFVpkgFormula *vpkgf) { for (CUDFVpkgFormulaIterator anddeps = vpkgf->begin(); anddeps != vpkgf->end(); anddeps++) add_vpkgs_from_vpkglist(lvpkg, *anddeps); } // Add a package to the reduced problem void process_package(CUDFproblem *new_pb, list &lvpkg, CUDFVersionedPackage *pkg) { if (! pkg->in_reduced) { pkg->in_reduced = true; new_pb->all_packages->push_back(pkg); if (pkg->installed) new_pb->installed_packages->push_back(pkg); else new_pb->uninstalled_packages->push_back(pkg); if (! pkg->virtual_package->in_reduced) lvpkg.push_back(pkg->virtual_package); if (pkg->depends != (CUDFVpkgFormula *)NULL) add_vpkgs_from_vpkgformula(lvpkg, pkg->depends); // process properties for (vector::iterator prop = process_properties.begin(); prop != process_properties.end(); prop++) for (CUDFPropertyValueListIterator propval = pkg->properties.begin(); propval != pkg->properties.end(); propval++) if ((*propval)->property == (*prop)->second) switch((*prop)->second->type_id) { case pt_vpkg: case pt_veqpkg: { CUDFVirtualPackage *vpkg = (*propval)->vpkg->virtual_package; if (! vpkg->in_reduced) lvpkg.push_back(vpkg); } break; case pt_vpkglist: case pt_veqpkglist: add_vpkgs_from_vpkglist(lvpkg, (*propval)->vpkglist); break; case pt_vpkgformula: add_vpkgs_from_vpkgformula(lvpkg, (*propval)->vpkgformula); break; default: break; } } } // process the virtual package vpkg adding its packages to the reduced problem void process_vpackage(CUDFproblem *new_pb, list &lvpkg, CUDFVirtualPackage *vpkg) { if (! vpkg->in_reduced) { vpkg->in_reduced = true; new_pb->all_virtual_packages->push_back(vpkg); if (vpkg->all_versions.size() > 0) // all versions for (CUDFVersionedPackageSetIterator ipkg = vpkg->all_versions.begin(); ipkg != vpkg->all_versions.end(); ipkg++) process_package(new_pb, lvpkg, (*ipkg)); if (vpkg->providers.size() > 0) // providers for (CUDFProviderListIterator ipkg = vpkg->providers.begin(); ipkg != vpkg->providers.end(); ipkg++) process_package(new_pb, lvpkg, (*ipkg)); if (vpkg->versioned_providers.size() > 0) // versioned providers for (CUDFVersionedProviderListIterator ipkg = vpkg->versioned_providers.begin(); ipkg != vpkg->versioned_providers.end(); ipkg++) for (CUDFProviderListIterator kpkg = ipkg->second.begin(); kpkg != ipkg->second.end(); kpkg++) process_package(new_pb, lvpkg, (*kpkg)); } } // Do compute a reduced version of the problem // iff use_reduced is true ... CUDFproblem *compute_reduced_CUDF(CUDFproblem *problem) { list lvpkg; CUDFproblem *new_pb = problem; if (verbosity > 0) printf("Initial size: %Zu packages (%Zu installed, %Zu uninstalled), %Zu virtual packages\n", new_pb->all_packages->size(), new_pb->installed_packages->size(), new_pb->uninstalled_packages->size(), new_pb->all_virtual_packages->size()); if (use_reduced) { new_pb = new CUDFproblem(); new_pb->properties = problem->properties; new_pb->all_packages = new CUDFVersionedPackageList(); new_pb->installed_packages = new CUDFVersionedPackageList();; new_pb->uninstalled_packages = new CUDFVersionedPackageList();; new_pb->all_virtual_packages = new CUDFVirtualPackageList(); new_pb->install = problem->install; new_pb->remove = problem->remove; new_pb->upgrade = problem->upgrade; // process all virtual packages of installed versioned packages for (CUDFVersionedPackageListIterator ipkg = problem->installed_packages->begin(); ipkg != problem->installed_packages->end(); ipkg++) process_vpackage(new_pb, lvpkg, (*ipkg)->virtual_package); // add virtual packages from install request if (problem->install != (CUDFVpkgList *)NULL) add_vpkgs_from_vpkglist(lvpkg, problem->install); // add virtual packages from upgrade request if (problem->upgrade != (CUDFVpkgList *)NULL) add_vpkgs_from_vpkglist(lvpkg, problem->upgrade); // add virtual packages from remove request (the remove might act only on a subset of the version ...) // the problem only arise when the related packages are not installed in the initial configuration if (problem->remove != (CUDFVpkgList *)NULL) add_vpkgs_from_vpkglist(lvpkg, problem->remove); // process pending virtual packages for (list::iterator ivpkg = lvpkg.begin(); ivpkg != lvpkg.end(); ivpkg++) process_vpackage(new_pb, lvpkg, (*ivpkg)); if (verbosity > 0) printf("Final size: %Zu packages (%Zu installed, %Zu uninstalled), %Zu virtual packages\n", new_pb->all_packages->size(), new_pb->installed_packages->size(), new_pb->uninstalled_packages->size(), new_pb->all_virtual_packages->size()); // Recompute ranks { int rank = 0; for (CUDFVersionedPackageListIterator ipkg = new_pb->all_packages->begin(); ipkg != new_pb->all_packages->end(); ipkg++, rank++) (*ipkg)->rank = rank; rank = 0; for (CUDFVirtualPackageListIterator ivpkg = new_pb->all_virtual_packages->begin(); ivpkg != new_pb->all_virtual_packages->end(); ivpkg++, rank++) (*ivpkg)->rank = rank; } } return new_pb; } mccs-1.1/sources/cudf_reductions.h0000600017777601777760000000232011574427503017132 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf_reduction.h */ /* Interface for problem reduction */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // Problem reduction consists in computing a subproblem // which will provide the same solution set than the initial problem. // It can be done if and only if criteria will not imply the installation // of uninstalled package that are not either involved in the request // of link to the installed package dependencies #ifndef __CUDF_REDUCTIONS #define __CUDF_REDUCTIONS #include extern bool use_reduced; // should we reduce the problem extern vector process_properties; // set of property to process // Do reduce the problem extern CUDFproblem *compute_reduced_CUDF(CUDFproblem *problem); // boolean function to test whether or not a package or a virtual package belongs to the reduced problem inline bool use_pkg(CUDFVersionedPackage *pkg) { return ((! use_reduced) || (pkg->in_reduced)); } inline bool use_vpkg(CUDFVirtualPackage *vpkg) { return ((! use_reduced) || (vpkg->in_reduced)); } #endif mccs-1.1/sources/cudf_types.h0000600017777601777760000000125611574427503016126 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf_types.h */ /* Common types to handle CUDF problems */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // Defines common types for cudf handling #ifndef _CUDF_TYPES__ #define _CUDF_TYPES_ typedef long long int CUDFcoefficient; // type of coefficients #define CUDFabs llabs // absolute value of a coefficient #define CUDFflags "%lld" // flags to print a coefficient #define CUDFflagsplus "%+lld" // flags to print a coefficient with its sign #endif mccs-1.1/sources/glpk_solver.c0000600017777601777760000001762611574427503016313 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: glpk_solver.c */ /* Interface to the GLPK solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #define OUTPUT_MODEL 0 // external function for solver creation abstract_solver *new_glpk_solver(bool use_exact) { return new glpk_solver(use_exact); } // solver initialisation int glpk_solver::init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars) { nb_packages = all_versioned_packages->size(); // Coefficient initialization initialize_coeffs(nb_packages + other_vars); this->all_versioned_packages = all_versioned_packages; lp = glp_create_prob(); glp_add_cols(lp, nb_vars); if ((lb = (CUDFcoefficient *)malloc((nb_vars+1)*sizeof(CUDFcoefficient))) == (CUDFcoefficient *)NULL) { fprintf(stderr, "glpk_solver: init_solver: not enough memory for lb.\n"); exit(-1); } if ((ub = (CUDFcoefficient *)malloc((nb_vars+1)*sizeof(CUDFcoefficient))) == (CUDFcoefficient *)NULL) { fprintf(stderr, "glpk_solver: init_solver: not enough memory for ub.\n"); exit(-1); } for (int i = 0; i <= nb_vars; i++) { lb[i] = 0; ub[i] = 1; } return 0; } // Does the solver provides integer variables bool glpk_solver::has_intvars() { return true; } // Set range of an integer variable int glpk_solver::set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper) { lb[rank+1] = lower; ub[rank+1] = upper; return 0; } // write the problem into a file int glpk_solver::writelp(char *filename) { glp_write_lp(lp, NULL, filename); return 0; } // solve the current lp problem int glpk_solver::solve() { int status = 0, nb_objectives = objectives.size(); glp_iocp mip_params; glp_init_iocp(&mip_params); mip_params.gmi_cuts = GLP_ON; mip_params.mir_cuts = GLP_ON; mip_params.cov_cuts = GLP_ON; mip_params.clq_cuts = GLP_ON; mip_params.presolve = GLP_ON; mip_params.binarize = GLP_ON; for (int k = 0; k < nb_objectives; k++) { glp_cpx_basis(lp); if (status == 0) status = glp_intopt(lp, &mip_params); if (k + 1 < nb_objectives) { // Get objective value CUDFcoefficient objval = objective_value(); if (verbosity > 0) printf(">>> Objective %d value : "CUDFflags"\n", k, objval); // Reset objective i coefficients for (int i = 1; i < objectives[k]->nb_coeffs + 1; i++) glp_set_obj_coef(lp, objectives[k]->sindex[i], 0); // Set objective i+1 as the actual objective function for (int i = 1; i < objectives[k+1]->nb_coeffs + 1; i++) glp_set_obj_coef(lp, objectives[k+1]->sindex[i], objectives[k+1]->coefficients[i]); // Add objective i = objval constraint int irow = glp_add_rows(lp, 1); glp_set_row_bnds(lp, irow, GLP_FX, objval, objval); glp_set_mat_row(lp, irow, objectives[k]->nb_coeffs, objectives[k]->sindex, objectives[k]->coefficients); if (OUTPUT_MODEL) glp_write_lp(lp, NULL, "glpkpbs1.lp"); } } if (status == 0) return 1; else return 0; } // get objective function value CUDFcoefficient glpk_solver::objective_value() { return (CUDFcoefficient)nearbyint(glp_mip_obj_val(lp)); } // solution initialisation int glpk_solver::init_solutions() { return 0; } // return the status of a package within the final configuration CUDFcoefficient glpk_solver::get_solution(CUDFVersionedPackage *package) { return (CUDFcoefficient)nearbyint(glp_mip_col_val(lp, package->rank+1)); } // initialize objective function int glpk_solver::begin_objectives(void) { glp_set_obj_dir(lp, GLP_MIN); // Problem is minimization return 0; } // return the package coefficient of the objective function CUDFcoefficient glpk_solver::get_obj_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // return the package coefficient of the objective function CUDFcoefficient glpk_solver::get_obj_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set package coefficient to a value int glpk_solver::set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set column coefficient to a value int glpk_solver::set_obj_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // initialize an additional objective function int glpk_solver::new_objective(void) { reset_coeffs(); return 0; } // add an additional objective function int glpk_solver::add_objective(void) { push_obj(); return 0; } // finalize the objective function int glpk_solver::end_objectives(void) { int i = 1; for (CUDFVersionedPackageListIterator ipkg = all_versioned_packages->begin(); ipkg != all_versioned_packages->end(); ipkg++) { glp_set_col_bnds(lp, i, GLP_DB, 0, 1); // Set bounds to [0, 1] glp_set_col_name(lp, i, (*ipkg)->versioned_name); // Set the colunm name glp_set_col_kind(lp, i, GLP_BV); // It is a binary variable ... i++; } for (i = nb_packages+1; i <= nb_vars; i++) { char *name; char buffer[20]; sprintf(buffer, "x%d", i); if ((name = (char *)malloc(strlen(buffer)+1)) == (char *)NULL) { fprintf(stderr, "CUDF error: can not alloc memory for variable name in glpk_solver::end_objective.\n"); exit(-1); } strcpy(name, buffer); if ((lb[i] == 0) && (ub[i] == 1)) { glp_set_col_bnds(lp, i, GLP_DB, 0, 1); // Set bounds to [0, 1] glp_set_col_name(lp, i, name); // Set the colunm name glp_set_col_kind(lp, i, GLP_BV); // It is a binary variable ... } else { glp_set_col_bnds(lp, i, GLP_DB, lb[i], ub[i]); // Set bounds to [0, 1] glp_set_col_name(lp, i, name); // Set the colunm name glp_set_col_kind(lp, i, GLP_IV); // It is an integer variable ... } } // Set objective 0 as the actual objective function for (int k = 1; k < objectives[0]->nb_coeffs + 1; k++) glp_set_obj_coef(lp, objectives[0]->sindex[k], objectives[0]->coefficients[k]); return 0; } // initialize constraints int glpk_solver::begin_add_constraints(void) { return 0; } // begin a new constraint int glpk_solver::new_constraint(void) { reset_coeffs(); return 0; } // get the package coefficient of the current constraint CUDFcoefficient glpk_solver::get_constraint_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // get the package coefficient of the current constraint CUDFcoefficient glpk_solver::get_constraint_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set package coefficient of the current constraint int glpk_solver::set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set column coefficient of the current constraint int glpk_solver::set_constraint_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // add current constraint as a greater or equal constraint int glpk_solver::add_constraint_geq(CUDFcoefficient bound) { if (nb_coeffs > 0 ) { int irow = glp_add_rows(lp, 1); glp_set_row_bnds(lp, irow, GLP_LO, bound, 0); glp_set_mat_row(lp, irow, nb_coeffs, sindex, coefficients); } return 0; } // add current constraint as a less or equal constraint int glpk_solver::add_constraint_leq(CUDFcoefficient bound) { if (nb_coeffs > 0 ) { int irow = glp_add_rows(lp, 1); glp_set_row_bnds(lp, irow, GLP_UP, 0, bound); glp_set_mat_row(lp, irow, nb_coeffs, sindex, coefficients); } return 0; } // add current constraint as an equality constraint int glpk_solver::add_constraint_eq(CUDFcoefficient bound) { if (nb_coeffs > 0 ) { int irow = glp_add_rows(lp, 1); glp_set_row_bnds(lp, irow, GLP_FX, bound, bound); glp_set_mat_row(lp, irow, nb_coeffs, sindex, coefficients); } return 0; } // finalize constraints int glpk_solver::end_add_constraints(void) { if (OUTPUT_MODEL) glp_write_lp(lp, NULL, "glpkpbs.lp"); return 0; } mccs-1.1/sources/glpk_solver.h0000600017777601777760000000651611574427503016314 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: glpk_solver.h */ /* Concrete class for the GLPK solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // concrete class which implements an interface to GLPK solver #ifndef _GLPK_SOLVER_H #define _GLPK_SOLVER_H #include #include #include class glpk_solver: public abstract_solver, public scoeff_solver { public: // Solver initialization int init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars); // Does the solver use integer variables bool has_intvars(); // Allocate some columns for integer variables int set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper); // Write the lp on a file int writelp(char *filename); // Solve the problem int solve(); // Get the objective value (final one) CUDFcoefficient objective_value(); // Init solutions (required before calling get_solution) int init_solutions(); // Get the solution for a package CUDFcoefficient get_solution(CUDFVersionedPackage *package); // Init the objective function definitions int begin_objectives(void); // Get current objective coefficient of package CUDFcoefficient get_obj_coeff(CUDFVersionedPackage *package); // Get current objective coefficient of a column CUDFcoefficient get_obj_coeff(int rank); // Set current objective coefficient of package int set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current objective coefficient of column int set_obj_coeff(int rank, CUDFcoefficient value); // Begin the definition of a new objective int new_objective(void); // Add current objective to the set of objectives int add_objective(void); // End objective definitions int end_objectives(void); // Init constraint definitions int begin_add_constraints(void); // Begin the definition of a new constraint int new_constraint(void); // Get current constraint coefficient of a package CUDFcoefficient get_constraint_coeff(CUDFVersionedPackage *package); // Get current constraint coefficient of a column CUDFcoefficient get_constraint_coeff(int rank); // Set current constraint coefficient of a package int set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current constraint coefficient of a column int set_constraint_coeff(int rank, CUDFcoefficient value); // Add current constraint as a more or equal constraint int add_constraint_geq(CUDFcoefficient bound); // Add current constraint as a less or equal constraint int add_constraint_leq(CUDFcoefficient bound); // Add current constraint as a equality constraint int add_constraint_eq(CUDFcoefficient bound); // End constraint definitions int end_add_constraints(void); glp_prob *lp; // internal solver representation CUDFVersionedPackageList *all_versioned_packages; // list of all versioned packages int nb_packages; // number of packages CUDFcoefficient *lb, *ub; // arrays of lower and upper bounds // solver creation glpk_solver(bool use_exact) { lp = (glp_prob *)NULL; all_versioned_packages = (CUDFVersionedPackageList *)NULL; lb = ub = (CUDFcoefficient *)NULL; } }; #endif mccs-1.1/sources/gurobi_solver.c0000600017777601777760000002473611574427503016645 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: gurobi_solver.c */ /* Interface to the Gurobi solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #define OUTPUT_MODEL 1 // solver creation abstract_solver *new_gurobi_solver() { return new gurobi_solver(); } // solver initialisation // requires the list of versioned packages and the total amount of variables (including additional ones) int gurobi_solver::init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars) { int status; nb_packages = all_versioned_packages->size(); this->all_versioned_packages = all_versioned_packages; // Coefficient initialization initialize_coeffs(nb_packages + other_vars); /* Initialize the gurobi environment */ status = GRBloadenv(&env, NULL); // NULL => no file log if (status || (env == (GRBenv *)NULL)) { fprintf (stderr, "Could not create Gurobi environment.\n"); exit(-1); } // Limit display according to verbosity if (verbosity < 2) status = GRBsetintparam(env, "OutputFlag", 0); /* Set MIP gap to zero */ status = GRBsetdblparam(env, "MIPGap", 0.0); /* Create Gurobi model */ status = GRBnewmodel(env, &model, "mip1", 0, NULL, NULL, NULL, NULL, NULL); if (status || (model == (GRBmodel *)NULL)) { fprintf (stderr, "Could not create Gurobi model.\n"); exit(-1); } /* Other data initialization */ first_objective = 0; lb = (double *)malloc(nb_vars*sizeof(double)); ub = (double *)malloc(nb_vars*sizeof(double)); vartype = (char *)malloc(nb_vars*sizeof(char)); varname = (char **)malloc(nb_vars*sizeof(char *)); if ((lb == (double *)NULL) || (ub == (double *)NULL) || (vartype == (char *)NULL) || (varname == (char **)NULL)) { fprintf(stderr, "gurobi_solver: initialization: not enough memory.\n"); exit(-1); } // Set package variable names int i = 0; for (CUDFVersionedPackageListIterator ipkg = all_versioned_packages->begin(); ipkg != all_versioned_packages->end(); ipkg++) { lb[i] = 0; ub[i] = 1; vartype[i] = GRB_BINARY; varname[(*ipkg)->rank] = (*ipkg)->versioned_name; i++; } // Set additional variable names for (i = nb_packages; i < nb_vars; i++) { char *name; char buffer[20]; sprintf(buffer, "x%d", i); if ((name = (char *)malloc(strlen(buffer)+1)) == (char *)NULL) { fprintf(stderr, "CUDF error: can not alloc memory for variable name in glpk_solver::end_objective.\n"); exit(-1); } strcpy(name, buffer); lb[i] = 0; ub[i] = 1; vartype[i] = GRB_BINARY; varname[i] = name; } return 0; } // cplex can handle integer variables bool gurobi_solver::has_intvars() { return true; } // set integer variable range (must be used before end_objective) int gurobi_solver::set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper) { lb[rank] = lower; ub[rank] = upper; vartype[rank] = GRB_INTEGER; return 0; }; // Just write the lp problem in a file int gurobi_solver::writelp(char *filename) { return 0; } // solve the current problem int gurobi_solver::solve() { int nb_objectives = objectives.size(); int mipstat, status; // Solve the objectives in a lexical order for (int i = first_objective; i < nb_objectives; i++) { // Solve the mip problem if (GRBoptimize(model)) return 0; // Get solution status status = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &mipstat); if (status) { exit(-1); } if (mipstat == GRB_OPTIMAL) { if (i < nb_objectives - 1) { // Get next non empty objective // (must be done here to avoid conflicting method calls int previ = i, nexti, nexti_nb_coeffs = 0; for (; i < nb_objectives - 1; i++) { nexti = i + 1; nexti_nb_coeffs = objectives[nexti]->nb_coeffs; if (nexti_nb_coeffs > 0) break; } if (nexti_nb_coeffs > 0) { // there is one more objective to solve // Set objective constraint value to objval double objval = objective_value(); if (verbosity > 0) printf(">>>> Objective value %d = %f\n", previ, objval); if (GRBaddconstr(model, objectives[previ]->nb_coeffs, objectives[previ]->sindex, objectives[previ]->coefficients, GRB_EQUAL, objval, NULL)) { fprintf(stderr, "gurobi_solver: end_objective: cannot add %d objective as constraint.\n", i); exit(-1); } // Set the new objective value reset_coeffs(); // Set previous objective coefficients to zero for (int k = 0; k < objectives[previ]->nb_coeffs; k++) GRBsetdblattrelement(model, "Obj", objectives[previ]->sindex[k], 0); // Set next objective coefficients to their actual values for (int k = 0; k < nexti_nb_coeffs; k++) GRBsetdblattrelement(model, "Obj", objectives[nexti]->sindex[k], objectives[nexti]->coefficients[k]); // Output model to file (when requested) if (OUTPUT_MODEL) { } } else return 1; } else return 1; } else { fprintf(stderr, "CPLEX solution status = %d\n", mipstat); return 0; } } return 0; } // return the objective value CUDFcoefficient gurobi_solver::objective_value() { double objval; int status = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &objval); if (status) { fprintf (stderr,"No MIP objective value available. Exiting...\n"); exit(-1); } // printf("Objective value = % 24.24e\n", objval); return (CUDFcoefficient)nearbyint(objval); } // solution initialisation int gurobi_solver::init_solutions() { int status; if (solution != (double *)NULL) free(solution); if ((solution = (double *)malloc(nb_vars*sizeof(double))) == (double *)NULL) { fprintf (stderr, "gurobi_solver: init_solutions: cannot get enough memory to store solutions.\n"); exit(-1); } status = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, nb_vars, solution); if ( status ) { fprintf (stderr, "gurobi_solver: init_solutions: failed to get solutions.\n"); exit(-1); } return 0; } // get the computed status of a package (0 = uninstalled, 1 = installed) CUDFcoefficient gurobi_solver::get_solution(CUDFVersionedPackage *package) { return (CUDFcoefficient)nearbyint(solution[package->rank]); } CUDFcoefficient gurobi_solver::get_solution(int k) { return (CUDFcoefficient)nearbyint(solution[k]); } // initialize the objective function int gurobi_solver::begin_objectives(void) { return 0; } // return the objective function coefficient of a package CUDFcoefficient gurobi_solver::get_obj_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // return the objective function coefficient of a rank CUDFcoefficient gurobi_solver::get_obj_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set the objective function coefficient of a package int gurobi_solver::set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set the objective function coefficient of a ranked variable int gurobi_solver::set_obj_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; }; // initialize an additional objective function int gurobi_solver::new_objective(void) { reset_coeffs(); return 0; } // add an additional objective function int gurobi_solver::add_objective(void) { push_obj(); return 0; } // ends up objective function construction int gurobi_solver::end_objectives(void) { if (objectives.size() > 0) { int status = 0, nb_coeffs = 0; // Set the first objective as the actual objective for (int k = 0; k < nb_vars; k++) coefficients[k] = 0; for (; first_objective < (int)objectives.size(); first_objective++) if ((nb_coeffs = objectives[first_objective]->nb_coeffs) > 0) break; if (nb_coeffs > 0) for (int k = 0; k < nb_coeffs; k++) coefficients[objectives[first_objective]->sindex[k]] = objectives[first_objective]->coefficients[k]; else if (first_objective == (int)objectives.size()) first_objective--; // So that we solve at least one pbs status = GRBaddvars(model, nb_vars, 0, NULL, NULL, NULL, coefficients, lb, ub, vartype, varname); if (status) { fprintf(stderr, "gurobi_solver: end_objective: cannot create objective function.\n"); exit(-1); } status = GRBupdatemodel(model); if (status) { fprintf(stderr, "gurobi_solver: end_objective: cannot update model with variables.\n"); exit(-1); } } return 0; } // initialize constraint declaration int gurobi_solver::begin_add_constraints(void) { return 0; } // begin the declaration of a new constraint int gurobi_solver::new_constraint(void) { reset_coeffs(); return 0; } // return the coefficient value of a package CUDFcoefficient gurobi_solver::get_constraint_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // return the coefficient value of a package CUDFcoefficient gurobi_solver::get_constraint_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set the coeffcient value of a package int gurobi_solver::set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set the coefficient value of a ranked variable int gurobi_solver::set_constraint_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // add constraint under construction as a greater or equal constraint int gurobi_solver::add_constraint_geq(CUDFcoefficient bound) { if (nb_coeffs > 0) { if (GRBaddconstr(model, nb_coeffs, sindex, coefficients, GRB_GREATER_EQUAL, bound, NULL)) { fprintf(stderr, "gurobi_solver: add_constraint_geq: cannot create geq constraint.\n"); exit(-1); } } return 0; } // add constraint under construction as a less or equal constraint int gurobi_solver::add_constraint_leq(CUDFcoefficient bound) { if (nb_coeffs > 0) { if (GRBaddconstr(model, nb_coeffs, sindex, coefficients, GRB_LESS_EQUAL, bound, NULL)) { fprintf(stderr, "gurobi_solver: add_constraint_geq: cannot create geq constraint.\n"); exit(-1); } } return 0; } // add constraint under construction as an equal constraint int gurobi_solver::add_constraint_eq(CUDFcoefficient bound) { if (nb_coeffs > 0) { if (GRBaddconstr(model, nb_coeffs, sindex, coefficients, GRB_EQUAL, bound, NULL)) { fprintf(stderr, "gurobi_solver: add_constraint_geq: cannot create geq constraint.\n"); exit(-1); } } return 0; } // ends up constraint declaration int gurobi_solver::end_add_constraints(void) { return 0; } mccs-1.1/sources/gurobi_solver.h0000600017777601777760000000756711574427503016655 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: gurobi_solver.h */ /* Concrete class for the Gurobi solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // concrete class which implements an interface to GUROBI solver #ifndef _GUROBI_SOLVER_H #define _GUROBI_SOLVER_H #include #include #include #include extern "C" { // required, otherwise it failed #include } class gurobi_solver: public abstract_solver, public scoeff_solver { public: // Solver initialization int init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars); // Does the solver use integer variables bool has_intvars(); // Allocate some columns for integer variables int set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper); // Init the objective function definitions int begin_objectives(void); // Get current objective coefficient of package CUDFcoefficient get_obj_coeff(CUDFVersionedPackage *package); // Get current objective coefficient of a column CUDFcoefficient get_obj_coeff(int rank); // Set current objective coefficient of package int set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current objective coefficient of column int set_obj_coeff(int rank, CUDFcoefficient value); // Begin the definition of a new objective int new_objective(void); // Add current objective to the set of objectives int add_objective(void); // End objective definitions int end_objectives(void); // Init constraint definitions int begin_add_constraints(void); // Begin the definition of a new constraint int new_constraint(void); // Get current constraint coefficient of a package CUDFcoefficient get_constraint_coeff(CUDFVersionedPackage *package); // Get current constraint coefficient of a column CUDFcoefficient get_constraint_coeff(int rank); // Set current constraint coefficient of a package int set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current constraint coefficient of a column int set_constraint_coeff(int rank, CUDFcoefficient value); // Add current constraint as a more or equal constraint int add_constraint_geq(CUDFcoefficient bound); // Add current constraint as a less or equal constraint int add_constraint_leq(CUDFcoefficient bound); // Add current constraint as a equality constraint int add_constraint_eq(CUDFcoefficient bound); // End constraint definitions int end_add_constraints(void); // Write the lp on a file int writelp(char *filename); // Solve the problem int solve(); // Get the objective value (final one) CUDFcoefficient objective_value(); // Init solutions (required before calling get_solution) int init_solutions(); // Get the solution for a package CUDFcoefficient get_solution(CUDFVersionedPackage *package); // Get the solution for a column CUDFcoefficient get_solution(int k); // variables only for internal use (should be private) GRBenv *env; // gurobi environment GRBmodel *model; // gurobi model CUDFVersionedPackageList *all_versioned_packages; // a pointer to the list of versioned packages int nb_packages; // number of packages int first_objective; double *gurobi_coeff; // cplex coefficients are doubles ... double *lb; // array of lower bounds double *ub; // array of upper bounds char *vartype; // array of variable types char **varname; // array of variable names // Store the solutions double *solution; // solver creation gurobi_solver(void) { all_versioned_packages = (CUDFVersionedPackageList *)NULL; solution = (double *)NULL; env = (GRBenv *)NULL; model = (GRBmodel *)NULL; } }; #endif mccs-1.1/sources/lexagregate_combiner.c0000600017777601777760000001207311574427503020121 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexagregate_combiner.c */ /* Implementation of the lexagregate combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include // Compute the number of columns required to handle the combiner int lexagregate_combiner::column_allocation(int first_rank) { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); return first_rank; } // Generate the objective function int lexagregate_combiner::objective_generation() { // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); solver->new_objective(); add_criteria_to_objective(1); solver->add_objective(); return 0; } // Ask to criteria to generate their own constraints int lexagregate_combiner::constraint_generation() { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Combiner initialization void lexagregate_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } // Compute the number of required columns when the combiner is used as a criteria int lexagregate_combiner::set_variable_range(int first_free_var) { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_free_var = (*crit)->set_variable_range(first_free_var); return first_free_var; } // Add the combiner to the curent objective function int lexagregate_combiner::add_criteria_to_objective(CUDFcoefficient lambda) { CUDFcoefficient lambda_comb = lambda*lambda_crit; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) { (*crit)->add_criteria_to_objective(lambda_comb); { CUDFcoefficient brange = (*crit)->bound_range(); if (brange != 0) lambda_comb *= brange; } } return 0; } // Add the combiner objective as a constraint int lexagregate_combiner::add_criteria_to_constraint(CUDFcoefficient lambda) { CUDFcoefficient lambda_comb = lambda*lambda_crit; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) { (*crit)->add_criteria_to_constraint(lambda_comb); { CUDFcoefficient brange = (*crit)->bound_range(); if (brange != 0) lambda_comb *= brange; } } return 0; } // Add the required constraints (from the criteria set) int lexagregate_combiner::add_constraints() { return constraint_generation(); } // Compute the range of the combiner/criteria CUDFcoefficient lexagregate_combiner::bound_range() { CUDFcoefficient range = 0; CUDFcoefficient lambda = +1; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) { CUDFcoefficient prev_lambda = lambda; lambda = (*crit)->bound_range(); range += CUDFabs(lambda_crit) * lambda * prev_lambda; } return range; } // Compute the upper bound of the combiner/criteria CUDFcoefficient lexagregate_combiner::upper_bound() { CUDFcoefficient ub = 0; CUDFcoefficient lambda = +1; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) { if (lambda_crit >= 0) ub += lambda_crit * lambda * (*crit)->upper_bound(); else ub += lambda_crit * lambda * (*crit)->lower_bound(); lambda = (*crit)->bound_range(); } return ub; } // Compute the lower bound of the combiner/criteria CUDFcoefficient lexagregate_combiner::lower_bound() { CUDFcoefficient lb = 0; CUDFcoefficient lambda = +1; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) { if (lambda_crit >= 0) lb += lambda_crit * lambda * (*crit)->lower_bound(); else lb += lambda_crit * lambda * (*crit)->upper_bound(); lambda = (*crit)->bound_range(); } return lb; } // Does the combiner/criteria allows problem reduction bool lexagregate_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(lambda_crit); return result; } // Does the combiner/criteria allows problem reduction (taking into account lambda multiplier) bool lexagregate_combiner::can_reduce(CUDFcoefficient lambda) { bool result = true; CUDFcoefficient l = lambda * lambda_crit; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(l); return result; } // Initialize integer variables void lexagregate_combiner::initialize_intvars() { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize_intvars(); } mccs-1.1/sources/lexagregate_combiner.h0000600017777601777760000000376211574427503020133 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexagregate_combiner.h */ /* a concrete class for a lexicographic order agregate */ /* combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __LEXAGREGATE_COMBINER_H #define __LEXAGREGATE_COMBINER_H #include // Concrete class to agregate a set of criteria i.e. handle it as sum \lambda_i c_i // Note: such an agregate could be seen either as a combiner or a criteria class lexagregate_combiner: public abstract_combiner, public abstract_criteria { public: CriteriaList *criteria; // set of criteria abstract_solver *solver; // used solver // ******************************************************** // Seen as a combiner int column_allocation(int first_rank); int objective_generation(); int constraint_generation(); // ******************************************************** // Seen as a criteria int set_variable_range(int first_free_var); int add_criteria_to_objective(CUDFcoefficient lambda); int add_criteria_to_constraint(CUDFcoefficient lambda); int add_constraints(); // computing combiner/criteria ranges/bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // does this combiner/criteria allows problem reduction bool can_reduce(); bool can_reduce(CUDFcoefficient lambda); // initialization void initialize(CUDFproblem *problem, abstract_solver *solver); void initialize_intvars(); // lambda coefficient for the current combiner/criteria CUDFcoefficient lambda_crit ; // lexagregate combiner creation lexagregate_combiner(CriteriaList *criteria) { this->lambda_crit = 1; this->criteria = criteria; }; lexagregate_combiner(CriteriaList *criteria, CUDFcoefficient lambda_crit) { this->criteria = criteria; this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/lexicographic_combiner.c0000600017777601777760000000357511574427503020461 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexicographic_combiner.c */ /* Implementation of the lexicographic combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include // Compute the number of columns required to handle the combiner int lexicographic_combiner::column_allocation(int first_rank) { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); return first_rank; } // Generate the objective function int lexicographic_combiner::objective_generation() { // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) { solver->new_objective(); (*crit)->add_criteria_to_objective(+1); solver->add_objective(); } return 0; } // Ask to criteria to generate their own constraints int lexicographic_combiner::constraint_generation() { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Does the combiner/criteria allows problem reduction bool lexicographic_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(+1); return result; } // Combiner initialization void lexicographic_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } mccs-1.1/sources/lexicographic_combiner.h0000600017777601777760000000177311574427503020464 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexicographic_combiner.h */ /* a concrete class for a lexicographic combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __LEXICOGRAPHIC_COMBINER_H #define __LEXICOGRAPHIC_COMBINER_H #include // A concrete class which evaluates its criteria in a lexicographic order class lexicographic_combiner: public abstract_combiner { public: CriteriaList *criteria; // set of criteria abstract_solver *solver; // used solver int column_allocation(int first_rank); int objective_generation(); int constraint_generation(); // does this combiner allows problem reduction bool can_reduce(); // initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lexicographic combiner creation lexicographic_combiner(CriteriaList *criteria) { this->criteria = criteria; }; }; #endif mccs-1.1/sources/leximax_combiner.c0000600017777601777760000001612711574427503017304 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: leximax_combiner.c */ /* Implementation of the leximax combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #include // Compute the number of columns required to handle the combiner int leximax_combiner::column_allocation(int first_rank) { // Number of criteria n = criteria->size(); // First, let each criteria get some room for they own purpose for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); // Need n variables to store criteria values ui_n = first_rank; first_rank += n; // Need n variables to store the yi i.e. actual objective values yi_n = first_rank; first_rank += n; // Need n*n variables to store the lambdaij values lambdaij_nn = first_rank; first_rank += n*n; return first_rank; } // Generate the objective function int leximax_combiner::objective_generation() { int ui; CUDFcoefficient min_y = MAXLONG, max_y = MINLONG, min_ui, max_ui; // Declare criteria values as integer ui = ui_n; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) { min_ui = (*crit)->lower_bound(); max_ui = (*crit)->upper_bound(); solver->set_intvar_range(ui++, min_ui, max_ui); if (max_y < max_ui) max_y = max_ui; if (min_y > min_ui) min_y = min_ui; } max_lambda = max_y - min_y; // Need n variables to store the yi i.e. actual objective values for (int i = 0; i < n; i++) solver->set_intvar_range(yi_n+i, min_y, max_y); // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); // We want to minimise each yi for (int i = 0; i < n; i++) { solver->new_objective(); solver->set_obj_coeff(yi_n + i, +1); solver->add_objective(); } return 0; } // Ask to criteria to generate their own constraints int leximax_combiner::constraint_generation() { // Generate the AtLeast constraints for (int i = 0; i < n; i++) { // add ui <= yj + lmax * lij i.e. yi - uj + lmax * lij >= 0 for (int j = 0; j < n; j++) { solver->new_constraint(); solver->set_constraint_coeff(yi_n+i, +1); solver->set_constraint_coeff(ui_n+j, -1); solver->set_constraint_coeff(lambdaij_nn+i*n+j, +max_lambda); solver->add_constraint_geq(0); } // add \sigma_{i = 1}^{n} lij <= n - k where k = n - i + 1 i.e. <= i - 1 solver->new_constraint(); for (int j = 0; j < n; j++) solver->set_constraint_coeff(lambdaij_nn+i*n+j, +1); solver->add_constraint_leq(i); } // Add each criteria as a new constraint int ui = ui_n; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) { solver->new_constraint(); (*crit)->add_criteria_to_constraint(1); solver->set_constraint_coeff(ui++, -1); solver->add_constraint_eq(0); } // Let each criteria generates his own constraints for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Combiner initialization void leximax_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { if (! solver->has_intvars()) { fprintf(stderr, "leximax_combiner: initialize: leximax combiner requires integer variables.\n"); exit(-1); } this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } // Compute the number of required columns when the combiner is used as a criteria int leximax_combiner::set_variable_range(int first_free_var) { return column_allocation(first_free_var); } // Initialize integer variables void leximax_combiner::initialize_intvars() { int ui; CUDFcoefficient min_y = MAXLONG, max_y = MINLONG, min_ui, max_ui; // Declare criteria values as integer ui = ui_n; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) { min_ui = (*crit)->lower_bound(); max_ui = (*crit)->upper_bound(); solver->set_intvar_range(ui++, min_ui, max_ui); if (max_y < max_ui) max_y = max_ui; if (min_y > min_ui) min_y = min_ui; } max_lambda = max_y - min_y; // Need n variables to store the yi i.e. actual objective values for (int i = 0; i < n; i++) solver->set_intvar_range(yi_n+i, min_y, max_y); // Initialize criteria intvars for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize_intvars(); } // Add the combiner as a criteria to the curent objective function int leximax_combiner::add_criteria_to_objective(CUDFcoefficient lambda) { // We want to maximise each yi if (n > 0) { solver->set_obj_coeff(yi_n, +1); for (int i = 1; i < n; i++) { solver->add_objective(); solver->new_objective(); solver->set_obj_coeff(yi_n + i, +1); } // last objective is added by the underlying combiner } return 0; } // Add the combiner objective as a constraint int leximax_combiner::add_criteria_to_constraint(CUDFcoefficient lambda) { return 0; } // Add the required constraints (from the criteria set) int leximax_combiner::add_constraints() { return constraint_generation(); } // Compute the range of the combiner/criteria CUDFcoefficient leximax_combiner::bound_range() { CUDFcoefficient range = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) range += CUDFabs(lambda_crit) * (*crit)->bound_range(); return range; } // Compute the upper bound of the combiner/criteria CUDFcoefficient leximax_combiner::upper_bound() { CUDFcoefficient ub = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) if (lambda_crit >= 0) ub += lambda_crit * (*crit)->upper_bound(); else ub += lambda_crit * (*crit)->lower_bound(); return ub; } // Compute the lower bound of the combiner/criteria CUDFcoefficient leximax_combiner::lower_bound() { CUDFcoefficient lb = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) if (lambda_crit >= 0) lb += lambda_crit * (*crit)->lower_bound(); else lb += lambda_crit * (*crit)->upper_bound(); return lb; } // Does the combiner/criteria allows problem reduction bool leximax_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(lambda_crit); return result; } // Does the combiner/criteria allows problem reduction (taking into account lambda multiplier) bool leximax_combiner::can_reduce(CUDFcoefficient lambda) { bool result = true; CUDFcoefficient l = lambda * lambda_crit; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(l); return result; } mccs-1.1/sources/leximax_combiner.h0000600017777601777760000000360611574427503017307 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: leximax_combiner.h */ /* a concrete class for a leximax order combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __LEXIMAX_COMBINER_H #define __LEXIMAX_COMBINER_H #include // A concrete class which evaluates its criteria in a leximax order class leximax_combiner: public abstract_combiner, public abstract_criteria { public: CriteriaList *criteria; // set of criteria abstract_solver *solver; // used solver int n, ui_n, yi_n, lambdaij_nn; CUDFcoefficient max_lambda; // ******************************************************** // Seen as a combiner int column_allocation(int first_rank); int objective_generation(); int constraint_generation(); // ******************************************************** // Seen as a criteria int set_variable_range(int first_free_var); void initialize_intvars(); int add_criteria_to_objective(CUDFcoefficient lambda); int add_criteria_to_constraint(CUDFcoefficient lambda); int add_constraints(); // computing combiner/criteria ranges/bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // does this combiner/criteria allows problem reduction bool can_reduce(); bool can_reduce(CUDFcoefficient lambda); // initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lambda coefficient for the current combiner/criteria CUDFcoefficient lambda_crit ; // leximax combiner creation leximax_combiner(CriteriaList *criteria) { this->lambda_crit = 1; this->criteria = criteria; }; leximax_combiner(CriteriaList *criteria, CUDFcoefficient lambda_crit) { this->criteria = criteria; this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/leximin_combiner.c0000600017777601777760000001613111574427503017275 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: leximin_combiner.c */ /* Implementation of the leximin combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #include // Compute the number of columns required to handle the combiner int leximin_combiner::column_allocation(int first_rank) { // Number of criteria n = criteria->size(); // First, let each criteria get some room for they own purpose for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); // Need n variables to store criteria values ui_n = first_rank; first_rank += n; // Need n variables to store the yi i.e. actual objective values yi_n = first_rank; first_rank += n; // Need n*n variables to store the lambdaij values lambdaij_nn = first_rank; first_rank += n*n; return first_rank; } // Generate the objective function int leximin_combiner::objective_generation() { int ui; CUDFcoefficient min_y = MAXLONG, max_y = MINLONG, min_ui, max_ui; // Declare criteria values as integer ui = ui_n; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) { min_ui = (*crit)->lower_bound(); max_ui = (*crit)->upper_bound(); solver->set_intvar_range(ui++, min_ui, max_ui); if (max_y < max_ui) max_y = max_ui; if (min_y > min_ui) min_y = min_ui; } max_lambda = max_y - min_y; // Need n variables to store the yi i.e. actual objective values for (int i = 0; i < n; i++) solver->set_intvar_range(yi_n+i, min_y, max_y); // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); // We want to maximise each yi for (int i = 0; i < n; i++) { solver->new_objective(); solver->set_obj_coeff(yi_n + i, -1); solver->add_objective(); } return 0; } // Ask to criteria to generate their own constraints int leximin_combiner::constraint_generation() { // Generate the AtLeast constraints for (int i = 0; i < n; i++) { // add yi <= uj + lmax * lij i.e. - yi + uj + lmax * lij >= 0 for (int j = 0; j < n; j++) { solver->new_constraint(); solver->set_constraint_coeff(yi_n+i, -1); solver->set_constraint_coeff(ui_n+j, +1); solver->set_constraint_coeff(lambdaij_nn+i*n+j, +max_lambda); solver->add_constraint_geq(0); } // add \sigma_{i = 1}^{n} lij <= n - k where k = n - i + 1 i.e. <= i - 1 solver->new_constraint(); for (int j = 0; j < n; j++) solver->set_constraint_coeff(lambdaij_nn+i*n+j, +1); solver->add_constraint_leq(i); } // Add each criteria as a new constraint int ui = ui_n; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) { solver->new_constraint(); (*crit)->add_criteria_to_constraint(1); solver->set_constraint_coeff(ui++, -1); solver->add_constraint_eq(0); } // Let each criteria generates his own constraints for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Combiner initialization void leximin_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { if (! solver->has_intvars()) { fprintf(stderr, "leximin_combiner: initialize: leximin combiner requires integer variables.\n"); exit(-1); } this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } // Compute the number of required columns when the combiner is used as a criteria int leximin_combiner::set_variable_range(int first_free_var) { return column_allocation(first_free_var); } // Initialize integer variables void leximin_combiner::initialize_intvars() { int ui; CUDFcoefficient min_y = MAXLONG, max_y = MINLONG, min_ui, max_ui; // Declare criteria values as integer ui = ui_n; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) { min_ui = (*crit)->lower_bound(); max_ui = (*crit)->upper_bound(); solver->set_intvar_range(ui++, min_ui, max_ui); if (max_y < max_ui) max_y = max_ui; if (min_y > min_ui) min_y = min_ui; } max_lambda = max_y - min_y; // Need n variables to store the yi i.e. actual objective values for (int i = 0; i < n; i++) solver->set_intvar_range(yi_n+i, min_y, max_y); // Initialize criteria intvars for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize_intvars(); } // Add the combiner as a criteria to the curent objective function int leximin_combiner::add_criteria_to_objective(CUDFcoefficient lambda) { // We want to maximise each yi if (n > 0) { solver->set_obj_coeff(yi_n, -1); for (int i = 1; i < n; i++) { solver->add_objective(); solver->new_objective(); solver->set_obj_coeff(yi_n + i, -1); } // last objective is added by the underlying combiner } return 0; } // Add the combiner objective as a constraint int leximin_combiner::add_criteria_to_constraint(CUDFcoefficient lambda) { return 0; } // Add the required constraints (from the criteria set) int leximin_combiner::add_constraints() { return constraint_generation(); } // Compute the range of the combiner/criteria CUDFcoefficient leximin_combiner::bound_range() { CUDFcoefficient range = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) range += CUDFabs(lambda_crit) * (*crit)->bound_range(); return range; } // Compute the upper bound of the combiner/criteria CUDFcoefficient leximin_combiner::upper_bound() { CUDFcoefficient ub = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) if (lambda_crit >= 0) ub += lambda_crit * (*crit)->upper_bound(); else ub += lambda_crit * (*crit)->lower_bound(); return ub; } // Compute the lower bound of the combiner/criteria CUDFcoefficient leximin_combiner::lower_bound() { CUDFcoefficient lb = 0; for (CriteriaList::reverse_iterator crit = criteria->rbegin(); crit != criteria->rend(); ++crit) if (lambda_crit >= 0) lb += lambda_crit * (*crit)->lower_bound(); else lb += lambda_crit * (*crit)->upper_bound(); return lb; } // Does the combiner/criteria allows problem reduction bool leximin_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(lambda_crit); return result; } // Does the combiner/criteria allows problem reduction (taking into account lambda multiplier) bool leximin_combiner::can_reduce(CUDFcoefficient lambda) { bool result = true; CUDFcoefficient l = lambda * lambda_crit; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(l); return result; } mccs-1.1/sources/leximin_combiner.h0000600017777601777760000000362011574427503017301 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: leximin_combiner.h */ /* a concrete class for a leximin order combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __LEXIMIN_COMBINER_H #define __LEXIMIN_COMBINER_H #include // A concrete class which evaluates its criteria according to a leximin order class leximin_combiner: public abstract_combiner, public abstract_criteria { public: CriteriaList *criteria; // set of criteria abstract_solver *solver; // used solver int n, ui_n, yi_n, lambdaij_nn; CUDFcoefficient max_lambda; // ******************************************************** // Seen as a combiner int column_allocation(int first_rank); int objective_generation(); int constraint_generation(); // ******************************************************** // Seen as a criteria int set_variable_range(int first_free_var); void initialize_intvars(); int add_criteria_to_objective(CUDFcoefficient lambda); int add_criteria_to_constraint(CUDFcoefficient lambda); int add_constraints(); // computing combiner/criteria ranges/bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // does this combiner/criteria allows problem reduction bool can_reduce(); bool can_reduce(CUDFcoefficient lambda); // initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lambda coefficient for the current combiner/criteria CUDFcoefficient lambda_crit ; // leximin combiner creation leximin_combiner(CriteriaList *criteria) { this->lambda_crit = 1; this->criteria = criteria; }; leximin_combiner(CriteriaList *criteria, CUDFcoefficient lambda_crit) { this->criteria = criteria; this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/lexleximax_combiner.c0000600017777601777760000001042511574427503020010 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexleximax_combiner.c */ /* Implementation of the lexleximax combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #include // Compute the number of columns required to handle the combiner int lexleximax_combiner::column_allocation(int first_rank) { // Number of leximax handled criteria n = criteria->size() - 1; // First, let each criteria get some room for they own purpose for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); // Need n variables to store criteria values ui_n = first_rank; first_rank += n; // Need n variables to store the yi i.e. actual objective values yi_n = first_rank; first_rank += n; // Need n*n variables to store the lambdaij values lambdaij_nn = first_rank; first_rank += n*n; return first_rank; } // Generate the objective function int lexleximax_combiner::objective_generation() { if (n > 0) { int ui = ui_n; CUDFcoefficient min_y = MAXLONG, max_y = MINLONG, min_ui, max_ui; // Declare criteria values as integer CriteriaListIterator crit = criteria->begin(); crit++; for (; crit != criteria->end(); crit++) { min_ui = (*crit)->lower_bound(); max_ui = (*crit)->upper_bound(); solver->set_intvar_range(ui++, min_ui, max_ui); if (max_y < max_ui) max_y = max_ui; if (min_y > min_ui) min_y = min_ui; } max_lambda = max_y - min_y; // Need n variables to store the yi i.e. actual objective values for (int i = 0; i < n; i++) solver->set_intvar_range(yi_n+i, min_y, max_y); } // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); // First criteria is handled lexicographically solver->new_objective(); (*criteria)[0]->add_criteria_to_objective(+1); solver->add_objective(); // We want to maximise each yi for (int i = 0; i < n; i++) { solver->new_objective(); solver->set_obj_coeff(yi_n + i, +1); solver->add_objective(); } return 0; } // Ask to criteria to generate their own constraints int lexleximax_combiner::constraint_generation() { // Generate the AtLeast constraints for (int i = 0; i < n; i++) { // add uj <= yi + lmax * lij i.e. yi - uj + lmax * lij >= 0 for (int j = 0; j < n; j++) { solver->new_constraint(); solver->set_constraint_coeff(yi_n+i, +1); solver->set_constraint_coeff(ui_n+j, -1); solver->set_constraint_coeff(lambdaij_nn+i*n+j, +max_lambda); solver->add_constraint_geq(0); } // add \sigma_{i = 1}^{n} lij <= n - k where k = n - i + 1 i.e. <= i - 1 solver->new_constraint(); for (int j = 0; j < n; j++) solver->set_constraint_coeff(lambdaij_nn+i*n+j, +1); solver->add_constraint_leq(i); } // Add each criteria handled by leximax as a new constraint if (n > 0) { int ui = ui_n; CriteriaListIterator crit = criteria->begin(); crit++; for (; crit != criteria->end(); crit++) { solver->new_constraint(); (*crit)->add_criteria_to_constraint(1); solver->set_constraint_coeff(ui++, -1); solver->add_constraint_eq(0); } } // Let each criteria generates his own constraints for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Combiner initialization void lexleximax_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { if (! solver->has_intvars()) { fprintf(stderr, "lexleximax_combiner: initialize: lexleximax combiner requires integer variables.\n"); exit(-1); } this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } // Does the combiner allows problem reduction bool lexleximax_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(+1); return result; } mccs-1.1/sources/lexleximax_combiner.h0000600017777601777760000000242711574427503020020 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexleximax_combiner.h */ /* a concrete class for a lexleximax order combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __LEXLEXIMAX_COMBINER_H #define __LEXLEXIMAX_COMBINER_H #include // A concrete class for a lexleximax order combiner // Such a combiner first evaluates its first criteria according to a lexicographic order // Then it evaluates the rest of the criteria according to a leximax order with respect to the first criteria class lexleximax_combiner: public abstract_combiner { public: CriteriaList *criteria; // set of criteria abstract_solver *solver; // used solver int n, ui_n, yi_n, lambdaij_nn; CUDFcoefficient max_lambda; int column_allocation(int first_rank); // Generate combiner objective function int objective_generation(); // Combiner constraint generation int constraint_generation(); // Does the combiner allows problem reduction bool can_reduce(); // Initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // Creation lexleximax_combiner(CriteriaList *criteria) { this->criteria = criteria; }; }; #endif mccs-1.1/sources/lexleximin_combiner.c0000600017777601777760000001025711574427503020011 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexleximin_combiner.c */ /* Implementation of the lexleximin combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #include // Compute the number of columns required to handle the combiner int lexleximin_combiner::column_allocation(int first_rank) { // Number of leximin handled criteria n = criteria->size() - 1; // First, let each criteria get some room for they own purpose for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); // Need n variables to store criteria values ui_n = first_rank; first_rank += n; // Need n variables to store the yi i.e. actual objective values yi_n = first_rank; first_rank += n; // Need n*n variables to store the lambdaij values lambdaij_nn = first_rank; first_rank += n*n; return first_rank; } // Generate the objective function int lexleximin_combiner::objective_generation() { int ui; CUDFcoefficient min_y = MAXLONG, max_y = MINLONG, min_ui, max_ui; // Declare criteria values as integer ui = ui_n; for (CriteriaListIterator crit = (criteria->begin())++; crit != criteria->end(); crit++) { min_ui = (*crit)->lower_bound(); max_ui = (*crit)->upper_bound(); solver->set_intvar_range(ui++, min_ui, max_ui); if (max_y < max_ui) max_y = max_ui; if (min_y > min_ui) min_y = min_ui; } max_lambda = max_y - min_y; // Need n variables to store the yi i.e. actual objective values for (int i = 0; i < n; i++) solver->set_intvar_range(yi_n+i, min_y, max_y); // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); // First criteria is handled lexicographically solver->new_objective(); (*criteria)[0]->add_criteria_to_objective(+1); solver->add_objective(); // We want to maximise each yi for (int i = 0; i < n; i++) { solver->new_objective(); solver->set_obj_coeff(yi_n + i, -1); solver->add_objective(); } return 0; } // Ask to criteria to generate their own constraints int lexleximin_combiner::constraint_generation() { // Generate the AtLeast constraints for (int i = 0; i < n; i++) { // add yi <= uj + lmax * lij i.e. - yi + uj + lmax * lij >= 0 for (int j = 0; j < n; j++) { solver->new_constraint(); solver->set_constraint_coeff(yi_n+i, -1); solver->set_constraint_coeff(ui_n+j, +1); solver->set_constraint_coeff(lambdaij_nn+i*n+j, +max_lambda); solver->add_constraint_geq(0); } // add \sigma_{i = 1}^{n} lij <= n - k where k = n - i + 1 i.e. <= i - 1 solver->new_constraint(); for (int j = 0; j < n; j++) solver->set_constraint_coeff(lambdaij_nn+i*n+j, +1); solver->add_constraint_leq(i); } // Add each criteria handled by leximin as a new constraint int ui = ui_n; for (CriteriaListIterator crit = (criteria->begin())++; crit != criteria->end(); crit++) { solver->new_constraint(); (*crit)->add_criteria_to_constraint(1); solver->set_constraint_coeff(ui++, -1); solver->add_constraint_eq(0); } // Let each criteria generates his own constraints for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Combiner initialization void lexleximin_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { if (! solver->has_intvars()) { fprintf(stderr, "lexleximin_combiner: initialize: lexleximin combiner requires integer variables.\n"); exit(-1); } this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } // Does the combiner allows problem reduction bool lexleximin_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(+1); return result; } mccs-1.1/sources/lexleximin_combiner.h0000600017777601777760000000242711574427503020016 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexleximin_combiner.h */ /* a concrete class for a lexleximin order combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __LEXLEXIMIN_COMBINER_H #define __LEXLEXIMIN_COMBINER_H #include // A concrete class for a lexleximin order combiner // Such a combiner first evaluates its first criteria according to a lexicographic order // Then it evaluates the rest of the criteria according to a leximin order with respect to the first criteria class lexleximin_combiner: public abstract_combiner { public: CriteriaList *criteria; // set of criteria abstract_solver *solver; // used solver int n, ui_n, yi_n, lambdaij_nn; CUDFcoefficient max_lambda; int column_allocation(int first_rank); // Generate combiner objective function int objective_generation(); // Combiner constraint generation int constraint_generation(); // Does the combiner allows problem reduction bool can_reduce(); // Initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // Creation lexleximin_combiner(CriteriaList *criteria) { this->criteria = criteria; }; }; #endif mccs-1.1/sources/lexsemiagregate_combiner.c0000600017777601777760000000437311574427503021003 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexsemiagregate_combiner.c */ /* Implementation of the lexsemiagregate combiner */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include // Compute the number of columns required to handle the combiner int lexsemiagregate_combiner::column_allocation(int first_rank) { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) first_rank = (*crit)->set_variable_range(first_rank); return first_rank; } // Generate the objective function int lexsemiagregate_combiner::objective_generation() { int size = criteria->size(); CUDFcoefficient lambda = +1; // Allow criteria to set the range of their integer variables for (CriteriaListIterator icrit = criteria->begin(); icrit != criteria->end(); icrit++) (*icrit)->initialize_intvars(); for (int i = 0; i < size; i += 2) { lambda = +1; solver->new_objective(); if (i + 1 < size) { (*criteria)[i+1]->add_criteria_to_objective(+1); lambda = (*criteria)[i+1]->bound_range(); if (lambda == 0) lambda = 1; } (*criteria)[i]->add_criteria_to_objective(lambda); solver->add_objective(); } if ((size > 1) && (size % 2 != 0)) { solver->new_objective(); (*criteria)[size-1]->add_criteria_to_objective(+1); solver->add_objective(); } return 0; } // Ask to criteria to generate their own constraints int lexsemiagregate_combiner::constraint_generation() { for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->add_constraints(); return 0; } // Does the combiner/criteria allows problem reduction bool lexsemiagregate_combiner::can_reduce() { bool result = true; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) result = result && (*crit)->can_reduce(+1); return result; } // Combiner initialization void lexsemiagregate_combiner::initialize(CUDFproblem *problem, abstract_solver *solver) { this->solver = solver; for (CriteriaListIterator crit = criteria->begin(); crit != criteria->end(); crit++) (*crit)->initialize(problem, solver); } mccs-1.1/sources/lexsemiagregate_combiner.h0000600017777601777760000000237111574427503021004 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lexsemiagregate_combiner.h */ /* a concrete class for a semi lexicographic agregate */ /* combiner (i.e. agregate criteria 2 by 2) */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef __LEXSEMIAGREGATE_COMBINER_H #define __LEXSEMIAGREGATE_COMBINER_H #include // A concrete class for a semi lexicographic agregate combiner // Criteria are agregated 2 by 2 according to a lexicographic order // while the resulting objective are evaluated according to a lexical order // It allows to avoid objective range issues class lexsemiagregate_combiner: public abstract_combiner { public: CriteriaList *criteria; // set of criteria abstract_solver *solver; // used solver int column_allocation(int first_rank); int objective_generation(); int constraint_generation(); // does this combiner allows problem reduction bool can_reduce(); // lexsemiagregate initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lexsemiagregate creation lexsemiagregate_combiner(CriteriaList *criteria) { this->criteria = criteria; }; }; #endif mccs-1.1/sources/lp_solver.c0000600017777601777760000002777311574427503015775 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lp_solver.c */ /* Interface to the lp format solvers */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #include #include #include #define CLEAN_FILES 1 #define TMP_FILES_PATH "/tmp/" // external function for solver creation abstract_solver *new_lp_solver(char *lpsolver) { return new lp_solver(lpsolver); } // solver initialisation int lp_solver::init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars) { nb_packages = all_versioned_packages->size(); this->all_versioned_packages = all_versioned_packages; // Coefficient initialization initialize_coeffs(nb_packages + other_vars); nb_constraints = 0; mult = ' '; solution = (CUDFcoefficient *)malloc(nb_vars*sizeof(CUDFcoefficient)); lb = (CUDFcoefficient *)malloc(nb_vars*sizeof(CUDFcoefficient)); ub = (CUDFcoefficient *)malloc(nb_vars*sizeof(CUDFcoefficient)); for (int i = 0; i < nb_vars; i++) { lb[i] = 0; ub[i] = 1; } sprintf(ctlpfilename, TMP_FILES_PATH "ctlp_%lu_%lu.lp", (long unsigned)getuid(), (long unsigned)getpid()); ctlpfile = fopen(ctlpfilename, "w"); if ((solution == (CUDFcoefficient *)NULL) || (lb == (CUDFcoefficient *)NULL) || (ub == (CUDFcoefficient *)NULL)) { fprintf(stderr, "lp_solver: intialize: not enough memory.\n"); exit(-1); } else if (ctlpfile == (FILE *)NULL) { fprintf(stderr, "lp_solver: intialize: can not open %s.\n", ctlpfilename); exit(-1); } else return 0; } // write the problem into a file int lp_solver::writelp(char *filename) { return 0; } // solve the current problem int lp_solver::solve() { int status = 0; int rank, iobjval; char command[1024]; FILE *fsol = (FILE *)NULL; CUDFcoefficient objvals[20]; unsigned int nb_objectives = objectives.size(); sprintf(lpfilename, TMP_FILES_PATH "lppbs_%lu_%lu.lp", (long unsigned)getuid(), (long unsigned)getpid()); sprintf(lpoutfilename, TMP_FILES_PATH "lppbs_%lu_%lu.out", (long unsigned)getuid(), (long unsigned)getpid()); for (unsigned int iobj = 0; iobj < nb_objectives; iobj++) { if (objectives[iobj]->nb_coeffs == 0) continue; if ((lpfile = fopen(lpfilename, "w")) == (FILE *)NULL) { fprintf(stderr, "lp_solver: cannot open %s.\n", lpfilename); exit(-1); } fprintf(lpfile, "Minimize\n obj:"); for (int i = 0, nbc = 0; i < objectives[iobj]->nb_coeffs; i++, nbc++) { if (nbc == 20) { // scip does not like too long lines nbc = 0; fprintf(lpfile, "\n "); } fprintf(lpfile, " "CUDFflagsplus"%cx%d", objectives[iobj]->coefficients[i], mult, objectives[iobj]->sindex[i]); } fprintf(lpfile, "\n"); fprintf(lpfile, "Subject To\n"); for (unsigned int i = 0; i < iobj; i++) { if (objectives[i]->nb_coeffs > 0) { for (int j = 0, nbc = 0; j < objectives[i]->nb_coeffs; j++, nbc++) { if (nbc == 20) { // scip does not like too long lines nbc = 0; fprintf(lpfile, "\n "); } fprintf(lpfile, " "CUDFflagsplus"%cx%d", objectives[i]->coefficients[j], mult, objectives[i]->sindex[j]); } fprintf(lpfile, " = "CUDFflags"\n", objvals[i]); } } fclose(lpfile); if (verbosity < 2) sprintf(command, "cat %s >> %s; %s %s > %s 2> /dev/null", ctlpfilename, lpfilename, lpsolver, lpfilename, lpoutfilename); else sprintf(command, "cat %s >> %s; %s %s | tee %s", ctlpfilename, lpfilename, lpsolver, lpfilename, lpoutfilename); if (system(command) == -1) { fprintf(stderr, "mccs: error while calling solver.\n"); exit(-1); } if ((fsol = fopen(lpoutfilename, "r")) == (FILE *)NULL) { fprintf(stderr, "Cannot open solution file \"%s\".\n", lpoutfilename); exit(-1); } status = -1; while ((status == -1) && (! feof(fsol)) && (fgets(command, 1000, fsol) != NULL)) switch (command[0]) { case 'p': // scip ? if (strncmp(command, "primal solution:", 16) == 0) { if (fgets(command, 1000, fsol) != NULL) // read =========== if (fgets(command, 1000, fsol) != NULL) // read empty line if (fgets(command, 1000, fsol) != NULL) { // read objective value or no solution if (strncmp(command, "objective value:", 16) == 0) { status = 1; if (sscanf(command+16, "%d", &iobjval) > 0) objval = objvals[iobj] = iobjval; // Reading scip solution if (iobj + 1 == nb_objectives) { // read solutions for (int i = 0; i < nb_packages; i++) solution[i] = 0; // Set solution values to 0 while ((! feof(fsol)) && (fgets(command, 1000, fsol) != NULL)) if (command[0] == 'x') { if (sscanf(command+1, "%d", &rank) > 0) solution[rank] = 1; } else // end of solution reached break; } } else if (strncmp(command, "no solution available", 21) == 0) { status = 0; } } else { fprintf(stderr, "mccs: error while reading solution file.\n"); exit(-1); } else { fprintf(stderr, "mccs: error while reading solution file.\n"); exit(-1); } else { fprintf(stderr, "mccs: error while reading solution file.\n"); exit(-1); } } break; case 'C': // COIN or CPLEX ? if ((strncmp(command, "Coin:Infeasible - objective value", 33) == 0) || (strncmp(command, "CPLEX> MIP - Integer infeasible.", 32) == 0)) status = 0; else if (strncmp(command, "Coin:Optimal - objective value", 30) == 0) { status = 1; if (sscanf(command+30, "%d", &iobjval) > 0) objval = objvals[iobj] = iobjval; // Reading COIN solution if (iobj + 1 == nb_objectives) { // read solutions for (int i = 0; i < nb_packages; i++) solution[i] = 0; // Set solution values to 0 while ((! feof(fsol)) && (fgets(command, 1000, fsol) != NULL)) if ((command[0] == ' ') && (command[8] == 'x')) { if (sscanf(command+9, "%d", &rank) > 0) if (((command[30] == ' ') && (command[31] == '1')) || ((command[31] == ' ') && (command[32] == '1')) || ((command[32] == ' ') && (command[33] == '1')) || ((command[33] == ' ') && (command[34] == '1'))) solution[rank] = 1; } else // end of solution reached break; } } else if (strncmp(command, "CPLEX> MIP - Integer optimal solution: Objective = ", 52) == 0) { status = 1; if (sscanf(command+52, "%d", &iobjval) > 0) objval = objvals[iobj] = iobjval; // Reading CPLEX solution if (iobj + 1 == nb_objectives) { // read solutions for (int i = 0; i < nb_packages; i++) solution[i] = 0; // Set solution values to 0 if (fgets(command, 1000, fsol) != NULL) { // Forget two next lines if (fgets(command, 1000, fsol) != NULL) { while ((! feof(fsol)) && (fgets(command, 1000, fsol) != NULL)) if (command[0] == 'x') { if (sscanf(command+1, "%d", &rank) > 0) solution[rank] = 1; } else // end of solution reached break; } else { fprintf(stderr, "mccs: error while reading solution file.\n"); exit(-1); } } else { fprintf(stderr, "mccs: error while reading solution file.\n"); exit(-1); } } } break; } // If we are here with a status = -1, then we were enable to read the solution (or the infeasability) if (status == -1) { fprintf(stderr, "ERROR: Cannot read solution from lp solver.\n"); exit(-1); } } // end for objectives if (CLEAN_FILES) { remove(ctlpfilename); remove(lpfilename); remove(lpoutfilename); } return status; } // get objective function value CUDFcoefficient lp_solver::objective_value() { return objval; } // solution initialisation int lp_solver::init_solutions() { return 0; } // lp solvers have integer variables bool lp_solver::has_intvars() { return true; } // set integer variable range (must be used before end_objective) int lp_solver::set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper) { lb[rank] = lower; ub[rank] = upper; return 0; } // return the status of a package within the final configuration CUDFcoefficient lp_solver::get_solution(CUDFVersionedPackage *package) { return solution[package->rank]; } // initialize objective function int lp_solver::begin_objectives(void) { return 0; } // return the package coefficient of the objective function CUDFcoefficient lp_solver::get_obj_coeff(CUDFVersionedPackage *package) { return get_coeff(package); } // return the package coefficient of the objective function CUDFcoefficient lp_solver::get_obj_coeff(int rank) { return get_coeff(rank); } // set the package coefficient of the objective function int lp_solver::set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set the column coefficient of the objective function int lp_solver::set_obj_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } int lp_solver::new_objective(void) { reset_coeffs(); return 0; } // add current objective to the set of objectives int lp_solver::add_objective(void) { push_obj(); return 0; } // finalize the objective function int lp_solver::end_objectives(void) { return 0; } // initialize constraints int lp_solver::begin_add_constraints(void) { return 0; } // begin a new constraint int lp_solver::new_constraint(void) { reset_coeffs(); return 0; } // get the package coefficient of the current constraint CUDFcoefficient lp_solver::get_constraint_coeff(CUDFVersionedPackage *package) { return get_coeff(package); } // get the package coefficient of the current constraint CUDFcoefficient lp_solver::get_constraint_coeff(int rank) { return get_coeff(rank); } // set package coefficient of the current constraint int lp_solver::set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set column coefficient of the current constraint int lp_solver::set_constraint_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // add current constraint as a greater equal constraint int lp_solver::add_constraint_geq(CUDFcoefficient bound) { if (nb_coeffs > 0) { for (int i = 0; i < nb_coeffs; i++) fprintf(ctlpfile, " "CUDFflagsplus"%cx%d", coefficients[i], mult, sindex[i]); if (bound == 0) fprintf(ctlpfile, " >= 0\n"); else fprintf(ctlpfile, " >= "CUDFflags"\n", bound); nb_constraints++; } return 0; } // add current constraint as a less or equal constraint int lp_solver::add_constraint_leq(CUDFcoefficient bound) { if (nb_coeffs > 0) { for (int i = 0; i < nb_coeffs; i++) fprintf(ctlpfile, " "CUDFflagsplus"%cx%d", coefficients[i], mult, sindex[i]); if (bound == 0) fprintf(ctlpfile, " <= 0\n"); else fprintf(ctlpfile, " <= "CUDFflags"\n", bound); nb_constraints++; } return 0; } // add current constraint as an equality constraint int lp_solver::add_constraint_eq(CUDFcoefficient bound) { if (nb_coeffs > 0) { for (int i = 0; i < nb_coeffs; i++) fprintf(ctlpfile, " "CUDFflagsplus"%cx%d", coefficients[i], mult, sindex[i]); if (bound == 0) fprintf(ctlpfile, " = 0\n"); else fprintf(ctlpfile, " = "CUDFflags"\n", bound); nb_constraints++; } return 0; } // finalize constraints int lp_solver::end_add_constraints(void) { int nbcols = 0, nbvars = 0; fprintf(ctlpfile, "Bounds\n"); for (int i = 0; i < nb_vars; i++) { fprintf(ctlpfile, " "CUDFflags" <= x%d <= "CUDFflags"\n", lb[i], i, ub[i]); } fprintf(ctlpfile, "Binaries\n"); for (int i = 0; i < nb_vars; i++) { if ((lb[i] == 0) && (ub[i] == 1)) { nbcols++; if (nbcols == 10) { fprintf(ctlpfile, "\n"); nbcols = 0; } fprintf(ctlpfile, " x%d", i); } } for (int i = 0; i < nb_vars; i++) { if ((lb[i] != 0) || (ub[i] != 1)) { if (nbvars == 0) fprintf(ctlpfile, "\nGenerals\n"); nbcols++; nbvars++; if (nbcols == 10) { fprintf(ctlpfile, "\n"); nbcols = 0; } fprintf(ctlpfile, " x%d", i); } } fprintf(ctlpfile, "\nEnd\n"); fclose(ctlpfile); return 0; } mccs-1.1/sources/lp_solver.h0000600017777601777760000000734511574427503015773 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lp_solver.h */ /* Concrete class for lp format based solvers */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // concrete class which implements an interface to a lp (cplex format) compliant solver #ifndef _LP_SOLVER_H #define _LP_SOLVER_H #include #include class lp_solver: public abstract_solver, public scoeff_solver { public: // Solver initialization int init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars); // Write the lp on a file int writelp(char *filename); // Solve the problem int solve(); // Get the objective value (final one) CUDFcoefficient objective_value(); // Init solutions (required before calling get_solution) int init_solutions(); // Get the solution for a package CUDFcoefficient get_solution(CUDFVersionedPackage *package); // Does the solver use integer variables bool has_intvars(); // Allocate some columns for integer variables int set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper); // Init the objective function definitions int begin_objectives(void); // Get current objective coefficient of package CUDFcoefficient get_obj_coeff(CUDFVersionedPackage *package); // Get current objective coefficient of a column CUDFcoefficient get_obj_coeff(int rank); // Set current objective coefficient of package int set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current objective coefficient of column int set_obj_coeff(int rank, CUDFcoefficient value); // Begin the definition of a new objective int new_objective(void); // Add current objective to the set of objectives int add_objective(void); // End objective definitions int end_objectives(void); // Init constraint definitions int begin_add_constraints(void); // Begin the definition of a new constraint int new_constraint(void); // Get current constraint coefficient of a package CUDFcoefficient get_constraint_coeff(CUDFVersionedPackage *package); // Get current constraint coefficient of a column CUDFcoefficient get_constraint_coeff(int rank); // Set current constraint coefficient of a package int set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current constraint coefficient of a column int set_constraint_coeff(int rank, CUDFcoefficient value); // Add current constraint as a more or equal constraint int add_constraint_geq(CUDFcoefficient bound); // Add current constraint as a less or equal constraint int add_constraint_leq(CUDFcoefficient bound); // Add current constraint as a equality constraint int add_constraint_eq(CUDFcoefficient bound); // End constraint definitions int end_add_constraints(void); CUDFVersionedPackageList *all_versioned_packages; // list of all versioned packages int nb_packages; // number of packages CUDFcoefficient *lb; // array of lower bounds CUDFcoefficient *ub; // array of upper bounds int nb_constraints; // number of constraints CUDFcoefficient *solution; // array of solution values CUDFcoefficient objval; // objective value char ctlpfilename[256]; char lpfilename[256]; char lpoutfilename[256]; FILE *lpfile, *ctlpfile; char *lpsolver; // name of the solver to call char mult; // solver creation lp_solver(char *lpsolver) { this->lpsolver = lpsolver; nb_packages = 0; all_versioned_packages = (CUDFVersionedPackageList *)NULL; nb_constraints = 0; solution = (CUDFcoefficient *)NULL; lpfile = stdout; mult = ' '; } }; #endif mccs-1.1/sources/lpsolve_solver.c0000600017777601777760000002160111574427503017026 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lpsolve_solver.c */ /* Interface to the LPSOLVE solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #define OUTPUT_MODEL 0 // external creation of the solver abstract_solver *new_lpsolve_solver() { return new lpsolve_solver(); } // solver initialisation int lpsolve_solver::init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars) { nb_packages = all_versioned_packages->size(); // Coefficient initialization initialize_coeffs(nb_packages + other_vars); this->all_versioned_packages = all_versioned_packages; if (verbosity > 0) printf("nb vars = %d\n", nb_vars); if ((lp = make_lp(0, nb_vars)) == NULL) { fprintf(stderr, "Cannot create the lpsolve solver.\n"); exit(-1); } if (verbosity < 2) set_verbose(lp, -1); if ((lb = (CUDFcoefficient *)malloc((nb_vars+1)*sizeof(CUDFcoefficient))) == (CUDFcoefficient *)NULL) { fprintf(stderr, "glpk_solver: init_solver: not enough memory for lb.\n"); exit(-1); } if ((ub = (CUDFcoefficient *)malloc((nb_vars+1)*sizeof(CUDFcoefficient))) == (CUDFcoefficient *)NULL) { fprintf(stderr, "glpk_solver: init_solver: not enough memory for ub.\n"); exit(-1); } for (int i = 0; i <= nb_vars; i++) { lb[i] = 0; ub[i] = 1; } return 0; } // Does the solver provide integer variables bool lpsolve_solver::has_intvars() { return true; } // Set the range of an integer variable int lpsolve_solver::set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper) { lb[rank+1] = lower; ub[rank+1] = upper; return 0; } // write the lp to a file int lpsolve_solver::writelp(char *filename) { write_lp(lp, filename); return 0; } // call to the lpsolve solver (bypassing name issues) int lpsolve(lprec *lp) { return solve(lp); } // solve the lp int lpsolve_solver::solve() { int status = 0, nb_objectives = objectives.size(); if (nb_objectives == 1) { set_presolve(lp, PRESOLVE_ROWS | PRESOLVE_COLS | PRESOLVE_LINDEP | PRESOLVE_REDUCEMIP | PRESOLVE_REDUCEGCD | PRESOLVE_PROBEFIX | PRESOLVE_PROBEREDUCE, get_presolveloops(lp)); status = lpsolve(lp); if ((status == OPTIMAL) || (status == SUBOPTIMAL) || (status == PRESOLVED)) return 1; else return 0; } else { lprec *lps = copy_lp(lp); // Using a copy seems to be the only way to make it work for (int k = 0; k < nb_objectives; k++) { set_presolve(lp, PRESOLVE_ROWS | PRESOLVE_COLS | PRESOLVE_LINDEP | PRESOLVE_REDUCEMIP | PRESOLVE_REDUCEGCD | PRESOLVE_PROBEFIX | PRESOLVE_PROBEREDUCE, get_presolveloops(lp)); status = lpsolve(lp); if (k + 1 < nb_objectives) { CUDFcoefficient objval = objective_value(); if (verbosity > 0) printf(">>> Objective %d value : "CUDFflags"\n", k, objval); // Build the objective function if (! set_obj_fnex(lps, objectives[k+1]->nb_coeffs, objectives[k+1]->coefficients, objectives[k+1]->sindex)) { fprintf(stderr, "generate_milp: cannot create objective function.\n"); exit(-1); } set_add_rowmode(lps, TRUE); add_constraintex(lps, objectives[k]->nb_coeffs, objectives[k]->coefficients, objectives[k]->sindex, EQ, objval); set_add_rowmode(lps, FALSE); /* set_constr_type(lps, k+1, EQ); set_rh(lps, k+1, objval); */ lp = copy_lp(lps); if (OUTPUT_MODEL) write_lp(lp, (char *)"lpsolvepbs1.lp"); } } } if ((status == OPTIMAL) || (status == SUBOPTIMAL) || (status == PRESOLVED)) return 1; else return 0; } // return the objective value CUDFcoefficient lpsolve_solver::objective_value() { return (CUDFcoefficient)nearbyint(get_objective(lp)); } // initialize the solutions int lpsolve_solver::init_solutions() { return 0; } // return the package status within final configuration CUDFcoefficient lpsolve_solver::get_solution(CUDFVersionedPackage *package) { // get_ptr_variables gives a solution array that only takes into account columns left by the presolve. // Thus, the only way to get all solutions is the following one ... no comment ... return (CUDFcoefficient)nearbyint(get_var_primalresult(lp, get_Norig_rows(lp) + package->rank + 1)); } // initialize the objective function int lpsolve_solver::begin_objectives(void) { set_minim(lp); // Problem is minimization return 0; } // return the package coefficient of the objective value CUDFcoefficient lpsolve_solver::get_obj_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // return the package coefficient of the objective value CUDFcoefficient lpsolve_solver::get_obj_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set the package coefficient of the objective value int lpsolve_solver::set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set column coefficient of the objective value int lpsolve_solver::set_obj_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // initialize an additional objective function int lpsolve_solver::new_objective(void) { reset_coeffs(); return 0; } // add an additional objective function int lpsolve_solver::add_objective(void) { push_obj(); return 0; } // finalize the objective function int lpsolve_solver::end_objectives(void) { // Build the objective function if (! set_obj_fnex(lp, objectives[0]->nb_coeffs, objectives[0]->coefficients, objectives[0]->sindex)) { fprintf(stderr, "generate_milp: cannot create objective function.\n"); exit(-1); } // Use names for colunms set_use_names(lp, FALSE, TRUE); for (CUDFVersionedPackageListIterator ipkg = all_versioned_packages->begin(); ipkg != all_versioned_packages->end(); ipkg++) { int i = (*ipkg)->rank + 1; if ((! set_bounds(lp, i, 0, 1)) || (! set_binary(lp, i, TRUE)) || (! set_col_name(lp, i, (*ipkg)->versioned_name))) { fprintf(stderr, "generate_milp: cannot set type, bounds or name for objective function a.\n"); exit(-1); } } for (int i = nb_packages + 1; i <= nb_vars; i++) { char *name; char buffer[20]; sprintf(buffer, "x%d", i); if ((name = (char *)malloc(strlen(buffer)+1)) == (char *)NULL) { fprintf(stderr, "CUDF error: can not alloc memory for variable name in glpk_solver::end_objective.\n"); exit(-1); } strcpy(name, buffer); if ((lb[i] == 0) && (ub[i] == 1)) { if ((! set_bounds(lp, i, 0, 1)) || (! set_binary(lp, i, TRUE)) || (! set_col_name(lp, i, name))) { fprintf(stderr, "generate_milp: cannot set type, bounds or name for objective function b.\n"); exit(-1); } } else { if ((! set_bounds(lp, i, lb[i], ub[i])) || (! set_int(lp, i, TRUE)) || (! set_col_name(lp, i, name))) { fprintf(stderr, "generate_milp: cannot set type, bounds or name for objective function c.\n"); exit(-1); } } } /* for (unsigned int k = 0; k < objectives.size(); k++) { add_constraintex(lp, objectives[k]->nb_coeffs, objectives[k]->coefficients, objectives[k]->sindex, EQ, 0); set_constr_type(lp, k+1, FR); } */ return 0; } // initialize constraints int lpsolve_solver::begin_add_constraints(void) { set_add_rowmode(lp, TRUE); return 0; } // begin a new constraint int lpsolve_solver::new_constraint(void) { reset_coeffs(); return 0; } // get package coefficient of the constraint under construction CUDFcoefficient lpsolve_solver::get_constraint_coeff(CUDFVersionedPackage *package) { return (CUDFcoefficient)get_coeff(package); } // get package coefficient of the constraint under construction CUDFcoefficient lpsolve_solver::get_constraint_coeff(int rank) { return (CUDFcoefficient)get_coeff(rank); } // set package coefficient of the constraint under construction int lpsolve_solver::set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set package coefficient of the constraint under construction int lpsolve_solver::set_constraint_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // add constraint under construction as a greater or equal constraint int lpsolve_solver::add_constraint_geq(CUDFcoefficient bound) { if (nb_coeffs > 0) add_constraintex(lp, nb_coeffs, coefficients, sindex, GE, bound); return 0; } // add constraint under construction as a less or equal constraint int lpsolve_solver::add_constraint_leq(CUDFcoefficient bound) { if (nb_coeffs > 0) add_constraintex(lp, nb_coeffs, coefficients, sindex, LE, bound); return 0; } // add constraint under construction as an equality constraint int lpsolve_solver::add_constraint_eq(CUDFcoefficient bound) { if (nb_coeffs > 0) add_constraintex(lp, nb_coeffs, coefficients, sindex, EQ, bound); return 0; } // finalize constraints int lpsolve_solver::end_add_constraints(void) { set_add_rowmode(lp, FALSE); if (OUTPUT_MODEL) write_lp(lp, (char *)"lpsolvepbs.lp"); return 0; } mccs-1.1/sources/lpsolve_solver.h0000600017777601777760000000662711574427503017046 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: lpsolve_solver.h */ /* Concrete class for the Lpsolve solver */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // concrete class which implements an interface to lpsolve #ifndef _LPSOLVE_SOLVER_H #define _LPSOLVE_SOLVER_H #include #include #include class lpsolve_solver: public abstract_solver, public scoeff_solver { public: // Solver initialization int init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars); // Does the solver use integer variables bool has_intvars(); // Allocate some columns for integer variables int set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper); // Write the lp on a file int writelp(char *filename); // Solve the problem int solve(); // Get the objective value (final one) CUDFcoefficient objective_value(); // Init solutions (required before calling get_solution) int init_solutions(); // Get the solution for a package CUDFcoefficient get_solution(CUDFVersionedPackage *package); // Init the objective function definitions int begin_objectives(void); // Get current objective coefficient of package CUDFcoefficient get_obj_coeff(CUDFVersionedPackage *package); // Get current objective coefficient of a column CUDFcoefficient get_obj_coeff(int rank); // Set current objective coefficient of package int set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current objective coefficient of column int set_obj_coeff(int rank, CUDFcoefficient value); // Begin the definition of a new objective int new_objective(void); // Add current objective to the set of objectives int add_objective(void); // End objective definitions int end_objectives(void); // Init constraint definitions int begin_add_constraints(void); // Begin the definition of a new constraint int new_constraint(void); // Get current constraint coefficient of a package CUDFcoefficient get_constraint_coeff(CUDFVersionedPackage *package); // Get current constraint coefficient of a column CUDFcoefficient get_constraint_coeff(int rank); // Set current constraint coefficient of a package int set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current constraint coefficient of a column int set_constraint_coeff(int rank, CUDFcoefficient value); // Add current constraint as a more or equal constraint int add_constraint_geq(CUDFcoefficient bound); // Add current constraint as a less or equal constraint int add_constraint_leq(CUDFcoefficient bound); // Add current constraint as a equality constraint int add_constraint_eq(CUDFcoefficient bound); // End constraint definitions int end_add_constraints(void); lprec *lp; // internal solver representation CUDFVersionedPackageList *all_versioned_packages; // list of all versioned packages int nb_packages; // number of packages double *solution; // array of solution values CUDFcoefficient *lb, *ub; // arrays of lower and upper bounds // solver creation lpsolve_solver(void) { lp = (lprec *)NULL; all_versioned_packages = (CUDFVersionedPackageList *)NULL; solution = (double *)NULL; lb = ub = (CUDFcoefficient *)NULL; } }; #endif mccs-1.1/sources/new_criteria.c0000600017777601777760000000747611574427503016441 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: new_criteria.h */ /* Implementation the new criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include // Criteria initialization void new_criteria::initialize(CUDFproblem *problem, abstract_solver *solver) { this->problem = problem; this->solver = solver; range = 0; for (CUDFVirtualPackageListIterator ivpkg = problem->all_virtual_packages->begin(); ivpkg != problem->all_virtual_packages->end(); ivpkg++) { int size = (*ivpkg)->all_versions.size(); if ((size > 0) && ((*ivpkg)->highest_installed == (CUDFVersionedPackage *)NULL)) { all_uninstalled_versioned_virtual_packages.push_back((*ivpkg)); if (size > 1) range++; } } } // Computing the number of columns required to handle the criteria int new_criteria::set_variable_range(int first_free_var) { this->first_free_var = first_free_var; return first_free_var + range; } // Add the criteria to the current objective function int new_criteria::add_criteria_to_objective(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = all_uninstalled_versioned_virtual_packages.begin(); ivpkg != all_uninstalled_versioned_virtual_packages.end(); ivpkg++) if ((*ivpkg)->all_versions.size() == 1) { CUDFVersionedPackage *pkg = *((*ivpkg)->all_versions.begin()); solver->set_obj_coeff(pkg, lambda_crit * lambda + solver->get_obj_coeff(pkg)); } else solver->set_obj_coeff(ivpkg_rank++, lambda_crit * lambda); return 0; } // Add the criteria to the constraint set int new_criteria::add_criteria_to_constraint(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = all_uninstalled_versioned_virtual_packages.begin(); ivpkg != all_uninstalled_versioned_virtual_packages.end(); ivpkg++) if ((*ivpkg)->all_versions.size() == 1) solver->set_constraint_coeff(*((*ivpkg)->all_versions.begin()), lambda_crit * lambda); else solver->set_constraint_coeff(ivpkg_rank++, lambda_crit * lambda); return 0; } // Add the constraints required by the criteria int new_criteria::add_constraints() { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = all_uninstalled_versioned_virtual_packages.begin(); ivpkg != all_uninstalled_versioned_virtual_packages.end(); ivpkg++) { solver->new_constraint(); if ((*ivpkg)->all_versions.size() > 1) { for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) solver->set_constraint_coeff((*vers_pkg)->rank, +1); solver->set_constraint_coeff(ivpkg_rank, -1); solver->add_constraint_geq(0); solver->new_constraint(); for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) solver->set_constraint_coeff((*vers_pkg)->rank, +1); { int n = (*ivpkg)->all_versions.size(); solver->set_constraint_coeff(ivpkg_rank, -n); solver->add_constraint_leq(0); } ivpkg_rank++; } } return 0; } // Compute the criteria range CUDFcoefficient new_criteria::bound_range() { return CUDFabs(lambda_crit) * all_uninstalled_versioned_virtual_packages.size(); } // Compute the criteria upper bound CUDFcoefficient new_criteria::upper_bound() { if (lambda_crit >= 0) return lambda_crit * all_uninstalled_versioned_virtual_packages.size(); else return 0; } // Compute the criteria lower bound CUDFcoefficient new_criteria::lower_bound() { if (lambda_crit >= 0) return 0; else return lambda_crit * all_uninstalled_versioned_virtual_packages.size(); } mccs-1.1/sources/new_criteria.h0000600017777601777760000000370311574427503016433 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: new_criteria.h */ /* Concrete class for the new criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _NEW_CRITERIA_H_ #define _NEW_CRITERIA_H_ #include // A concrete class for the new criteria // i.e. number of virtual packages that were // not installed in the initial configuration and // that are installed in the final one class new_criteria: public abstract_criteria { public: CUDFproblem *problem; // a pointer to the problem abstract_solver *solver; // a pointer to the solver // list of all uninstalled virtual packaged with at list a versionned package CUDFVirtualPackageList all_uninstalled_versioned_virtual_packages; // range of the criteria int range; // column of the first variable used by the criteria int first_free_var; // Allocate some columns for the criteria int set_variable_range(int first_free_var); // Add the criteria to the objective int add_criteria_to_objective(CUDFcoefficient lambda); // Add the criteria to the constraint set int add_criteria_to_constraint(CUDFcoefficient lambda); // Add constraints required by the criteria int add_constraints(); // Compute the criteria range, upper and lower bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // Does the criteria allows problem reductions bool can_reduce(CUDFcoefficient lambda) { return ((lambda >= 0) && (lambda_crit >= 0)); } // Criteria initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lambda multiplier for the criteria CUDFcoefficient lambda_crit ; // Criteria initialization new_criteria() { this->lambda_crit = +1; }; new_criteria(CUDFcoefficient lambda_crit) { this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/notuptodate_criteria.c0000600017777601777760000000700411574427503020201 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: notuptodate_criteria.c */ /* Implementation the notuptodate criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include // Implementation of the not up to date criteria // // Criteria initialization void notuptodate_criteria::initialize(CUDFproblem *problem, abstract_solver *solver) { this->problem = problem; this->solver = solver; ub = 0; for (CUDFVirtualPackageListIterator ivpkg = problem->all_virtual_packages->begin(); ivpkg != problem->all_virtual_packages->end(); ivpkg++) if ((*ivpkg)->all_versions.size() > 1) ub++; } // Computing the number of columns required to handle the criteria int notuptodate_criteria::set_variable_range(int first_free_var) { this->first_free_var = first_free_var; return first_free_var + ub; } // Add the criteria to the current objective function int notuptodate_criteria::add_criteria_to_objective(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = problem->all_virtual_packages->begin(); ivpkg != problem->all_virtual_packages->end(); ivpkg++) if ((*ivpkg)->all_versions.size() > 1) solver->set_obj_coeff(ivpkg_rank++, lambda_crit * lambda); return 0; } // Add the criteria to the constraint set int notuptodate_criteria::add_criteria_to_constraint(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = problem->all_virtual_packages->begin(); ivpkg != problem->all_virtual_packages->end(); ivpkg++) if ((*ivpkg)->all_versions.size() > 1) solver->set_constraint_coeff(ivpkg_rank++, lambda_crit * lambda); return 0; } // Add the constraints required by the criteria int notuptodate_criteria::add_constraints() { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = problem->all_virtual_packages->begin(); ivpkg != problem->all_virtual_packages->end(); ivpkg++) { int size = (*ivpkg)->all_versions.size(); if (size > 1) { solver->new_constraint(); for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) if ((*vers_pkg)->version == (*ivpkg)->highest_version) solver->set_constraint_coeff((*vers_pkg)->rank, -(size - 1)); else solver->set_constraint_coeff((*vers_pkg)->rank, +1); solver->set_constraint_coeff(ivpkg_rank, -size); solver->add_constraint_leq(+0); solver->new_constraint(); for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) if ((*vers_pkg)->version == (*ivpkg)->highest_version) solver->set_constraint_coeff((*vers_pkg)->rank, -(size - 1)); else solver->set_constraint_coeff((*vers_pkg)->rank, +1); solver->set_constraint_coeff(ivpkg_rank, -size); solver->add_constraint_geq(-size+1); ivpkg_rank++; } } return 0; } // Compute the criteria range CUDFcoefficient notuptodate_criteria::bound_range() { return CUDFabs(lambda_crit) * ub; } // Compute the criteria upper bound CUDFcoefficient notuptodate_criteria::upper_bound() { if (lambda_crit >= 0) return lambda_crit * ub; else return 0; } // Compute the criteria lower bound CUDFcoefficient notuptodate_criteria::lower_bound() { if (lambda_crit >= 0) return 0; else return lambda_crit * ub; } mccs-1.1/sources/notuptodate_criteria.h0000600017777601777760000000351111574427503020205 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: notuptodate_criteria.h */ /* Concrete class for the notuptodate criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _NOTUPTODATE_CRITERIA_H_ #define _NOTUPTODATE_CRITERIA_H_ #include // A concrete class for the notuptodate criteria // i.e. number of virtual packages that are not installed // with their highest available version class notuptodate_criteria: public abstract_criteria { public: CUDFproblem *problem; // a pointer to the problem abstract_solver *solver; // a pointer to the solver // column of the first variable used by the criteria int first_free_var; // Allocate some columns for the criteria int set_variable_range(int first_free_var); // Add the criteria to the objective int add_criteria_to_objective(CUDFcoefficient lambda); // Add the criteria to the constraint set int add_criteria_to_constraint(CUDFcoefficient lambda); // Add constraints required by the criteria int add_constraints(); // upper bound of the criteria CUDFcoefficient ub; // Compute the criteria range, upper and lower bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // Does the criteria allows problem reductions bool can_reduce(CUDFcoefficient lambda) { return ((lambda >= 0) && (lambda_crit >= 0)); } // Criteria initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lambda multiplier for the criteria CUDFcoefficient lambda_crit ; // Criteria initialization notuptodate_criteria() { this->lambda_crit = +1; }; notuptodate_criteria(CUDFcoefficient lambda_crit) { this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/nunsat_criteria.c0000600017777601777760000002645211577377521017162 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: nunsat_criteria.c */ /* Implementation of the nunsat criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include // Check property availability void nunsat_criteria::check_property(CUDFproblem *problem) { CUDFPropertiesIterator prop = problem->properties->find(string(property_name)); has_property = false; if (prop == problem->properties->end()) printf("WARNING: cannot find \"%s\" property definition: criteria nunsat not used.\n", property_name); else if ((*prop).second->type_id != pt_vpkgformula) printf("WARNING: Property \"%s\" has wrong type: criteria nunsat not used.\n", property_name); else { has_property = true; process_properties.push_back(prop); } } // Criteria initialization void nunsat_criteria::initialize(CUDFproblem *problem, abstract_solver *solver) { CUDFPropertiesIterator prop = problem->properties->find(string(property_name)); this->problem = problem; this->solver = solver; disjuncts = 0; range = 0; if (has_property) { versioned_pkg_with_property = new CUDFVersionedPackageList(); for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) { for (CUDFPropertyValueListIterator propval = (*ipkg)->properties.begin(); propval != (*ipkg)->properties.end(); propval++) if ((*propval)->property == (*prop).second) { CUDFVpkgFormula *property = (*propval)->vpkgformula; versioned_pkg_with_property->push_back((*ipkg)); for (CUDFVpkgFormulaIterator conjunct = (*property).begin(); conjunct != (*property).end(); conjunct++) { int nb = 0; bool self_depend = false; for (CUDFVpkgListIterator disjunct = (*conjunct)->begin(); disjunct != (*conjunct)->end(); disjunct++) { if (((*disjunct) == vpkg_true) || ((*disjunct) == vpkg_false)) continue; CUDFVirtualPackage *vpackage = (*disjunct)->virtual_package; a_compptr comp = get_comparator((*disjunct)->op); if (vpackage->all_versions.size() > 0) { for (CUDFVersionedPackageSetIterator jpkg = vpackage->all_versions.begin(); jpkg != vpackage->all_versions.end(); jpkg++) if (comp((*jpkg)->version, (*disjunct)->version)) { if ((*jpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; nb = 0; break; } else { nb++; } } } if (with_providers) { // as well as from all the providers if ((! self_depend) && (vpackage->providers.size() > 0)) { for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if ((*jpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; nb = 0; break; } else { nb++; } } // as well as from all the versioned providers with the right version if (! self_depend) for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (self_depend) break; else if (comp(jpkg->first, (*disjunct)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if ((*kpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; nb = 0; break; } else { nb++; } } } // disjunct if (nb > 0) { range++; if (nb > 1) disjuncts++; } } // conjunct break; } // is propval } } } // Computing the number of columns required to handle the criteria int nunsat_criteria::set_variable_range(int first_free_var) { if (has_property) { this->first_free_var = first_free_var; return range + disjuncts + first_free_var; } else return first_free_var; } // Add the criteria to the current objective function int nunsat_criteria::add_criteria_to_objective(CUDFcoefficient lambda) { if (has_property) for (int i = 0; i < range; i++) solver->set_obj_coeff(first_free_var + i, lambda_crit * lambda); return 0; } // Add the criteria to the constraint set int nunsat_criteria::add_criteria_to_constraint(CUDFcoefficient lambda) { if (has_property) { for (int i = 0; i < range; i++) solver->set_constraint_coeff(first_free_var + i, lambda_crit * lambda); } return 0; } // Add the constraints required by the criteria int nunsat_criteria::add_constraints() { if (has_property) { CUDFPropertiesIterator prop = problem->properties->find(string(property_name)); // int ipkg_rank = gstart = first_free_var; // int disjunct_rank = gend = ipkg_rank + range; int ipkg_rank = first_free_var; int disjunct_rank = ipkg_rank + range; // printf("ipkg_rank = %d, disjunct_rank = %d, range = %d, disjuncts = %d, size = %u\n", ipkg_rank, disjunct_rank, // range, disjuncts, versioned_pkg_with_property->size()); for (CUDFVersionedPackageListIterator ipkg = versioned_pkg_with_property->begin(); ipkg != versioned_pkg_with_property->end(); ipkg++) { // printf("handling (%s, "CUDFflags")\n", (*ipkg)->name, (*ipkg)->version); for (CUDFPropertyValueListIterator propval = (*ipkg)->properties.begin(); propval != (*ipkg)->properties.end(); propval++) if ((*propval)->property == (*prop).second) { CUDFVpkgFormula *property = (*propval)->vpkgformula; int last_pkg = 0; for (CUDFVpkgFormulaIterator conjunct = (*property).begin(); conjunct != (*property).end(); conjunct++) { int nb = 0; bool self_depend = false; bool has_false = false; solver->new_constraint(); for (CUDFVpkgListIterator disjunct = (*conjunct)->begin(); disjunct != (*conjunct)->end(); disjunct++) { if ((*disjunct) == vpkg_true) { // The disjunct contains true has_false = false; // False is ignored nb = 0; // Other packages are ignored break; // Skip next packages } if ((*disjunct) == vpkg_true) { // The disjunct contains false has_false = true; continue; // Directly handle next package } CUDFVirtualPackage *vpackage = (*disjunct)->virtual_package; a_compptr comp = get_comparator((*disjunct)->op); if (vpackage->all_versions.size() > 0) { for (CUDFVersionedPackageSetIterator jpkg = vpackage->all_versions.begin(); jpkg != vpackage->all_versions.end(); jpkg++) if (comp((*jpkg)->version, (*disjunct)->version)) { if ((*jpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; nb = 0; break; } else if (solver->get_constraint_coeff(*jpkg) == 0) { nb++; solver->set_constraint_coeff(*jpkg, +1); last_pkg = (*jpkg)->rank; } } } if (with_providers) { // as well as from all the providers if ((! self_depend) && (vpackage->providers.size() > 0)) { for (CUDFProviderListIterator jpkg = vpackage->providers.begin(); jpkg != vpackage->providers.end(); jpkg++) if ((*jpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; nb = 0; break; } else if (solver->get_constraint_coeff(*jpkg) == 0) { nb++; solver->set_constraint_coeff(*jpkg, +1); last_pkg = (*jpkg)->rank; } } // as well as from all the versioned providers with the right version if (! self_depend) for (CUDFVersionedProviderListIterator jpkg = vpackage->versioned_providers.begin(); jpkg != vpackage->versioned_providers.end(); jpkg++) if (self_depend) break; else if (comp(jpkg->first, (*disjunct)->version)) for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) if ((*kpkg) == (*ipkg)) { // Then, the dependency is always checked self_depend = true; nb = 0; break; } else if (solver->get_constraint_coeff(*kpkg) == 0) { nb++; solver->set_constraint_coeff(*kpkg, +1); last_pkg = (*kpkg)->rank; } } } // disjunct if (nb == 0) { if (has_false) { solver->new_constraint(); // ipkg_rank == (*ipkg) solver->set_constraint_coeff((*ipkg), -1); solver->set_constraint_coeff(ipkg_rank, +1); solver->add_constraint_eq(0); } } else if (nb > 0) { // disjunct_rank = 1 if unsat disjunct, 0 otherwise if (nb == 1) { solver->new_constraint(); // ipkg_rank = 0 if package is not installed solver->set_constraint_coeff((*ipkg), -1); solver->set_constraint_coeff(ipkg_rank, +1); solver->add_constraint_leq(0); solver->new_constraint(); // ipkg_rank = 0 if disjunct is satisfied (i.e. = 0) solver->set_constraint_coeff(last_pkg, +1); solver->set_constraint_coeff(ipkg_rank, +1); solver->add_constraint_leq(+1); solver->new_constraint(); // if package is installed and disjunct_rank is unsatified, ipkg_rank = 1 solver->set_constraint_coeff((*ipkg), -1); solver->set_constraint_coeff(last_pkg, +1); solver->set_constraint_coeff(ipkg_rank, +1); solver->add_constraint_geq(0); } else { solver->set_constraint_coeff(disjunct_rank, +1); solver->add_constraint_geq(+1); solver->set_constraint_coeff(disjunct_rank, +nb); solver->add_constraint_leq(+nb); solver->new_constraint(); // ipkg_rank = 0 if package is not installed solver->set_constraint_coeff((*ipkg), -1); solver->set_constraint_coeff(ipkg_rank, +1); solver->add_constraint_leq(0); solver->new_constraint(); // ipkg_rank = 0 if disjunct is satisfied (i.e. = 0) solver->set_constraint_coeff(disjunct_rank, -1); solver->set_constraint_coeff(ipkg_rank, +1); solver->add_constraint_leq(0); solver->new_constraint(); // if package is installed and disjunct_rank is unsatified, ipkg_rank = 1 solver->set_constraint_coeff((*ipkg), -1); solver->set_constraint_coeff(disjunct_rank, -1); solver->set_constraint_coeff(ipkg_rank, +1); solver->add_constraint_geq(-1); disjunct_rank++; } ipkg_rank++; } // nb > 0 } // conjunct // We've got the requested property. Don't need to go further. break; } // is propval } // ipkgs // printf("ipkg_rank = %d, disjunct_rank = %d\n", ipkg_rank, disjunct_rank); fflush(stdout); } // has_property return 0; } // Compute the criteria range CUDFcoefficient nunsat_criteria::bound_range() { if (has_property) return CUDFabs(lambda_crit) * range; else return 0; } // Compute the criteria upper bound CUDFcoefficient nunsat_criteria::upper_bound() { if ((has_property) && (lambda_crit >= 0)) return lambda_crit * range; else return 0; } // Compute the criteria lower bound CUDFcoefficient nunsat_criteria::lower_bound() { if (has_property) { if (lambda_crit >= 0) return 0; else return lambda_crit * range; } else return 0; } mccs-1.1/sources/nunsat_criteria.h0000600017777601777760000000464611574427503017161 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: nunsat_criteria.h */ /* Concrete class for the nunsat criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _NUNSAT_CRITERIA_H_ #define _NUNSAT_CRITERIA_H_ #include // A concrete class for the nunsat criteria // i.e. number of disjuncts from a given property // of installed virtual packages which are unsat // in the final configuration class nunsat_criteria: public abstract_criteria { public: CUDFproblem *problem; // a pointer to the problem abstract_solver *solver; // a pointer to the solver char *property_name; // property name bool has_property; // is the property available // list of versionned virtual packages CUDFVersionedPackageList *versioned_pkg_with_property; int disjuncts; // number of disjunct int range; // criteria range // column of the first variable used by the criteria int first_free_var; // Allocate some columns for the criteria int set_variable_range(int first_free_var); // Add the criteria to the objective int add_criteria_to_objective(CUDFcoefficient lambda); // Add the criteria to the constraint set int add_criteria_to_constraint(CUDFcoefficient lambda); // Add constraints required by the criteria int add_constraints(); // Compute the criteria range, upper and lower bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // Does the criteria allows problem reductions bool can_reduce(CUDFcoefficient lambda) { return ((lambda >= 0) && (lambda_crit >= 0)); } // Criteria initialization void initialize(CUDFproblem *problem, abstract_solver *solver); void check_property(CUDFproblem *problem); // lambda multiplier for the criteria CUDFcoefficient lambda_crit ; // shall providers be taken into account bool with_providers; // Criteria initialization nunsat_criteria(char *property_name, bool with_providers) { this->property_name = property_name; this->lambda_crit = +1; this->with_providers = with_providers; }; nunsat_criteria(char *property_name, bool with_providers, CUDFcoefficient lambda_crit) { this->property_name = property_name; this->lambda_crit = lambda_crit; this->with_providers = with_providers; }; }; #endif mccs-1.1/sources/pblib_solver.c0000600017777601777760000002344511574427503016442 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: pblib_solver.c */ /* Interface to the pblib format solvers */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include #include #include #include #define CLEAN_FILES 1 #define TMP_FILES_PATH "/tmp/" // external function for solver creation abstract_solver *new_pblib_solver(char *pb_solver) { return new pblib_solver(pb_solver); } // solver initialisation int pblib_solver::init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars) { nb_packages = all_versioned_packages->size(); this->all_versioned_packages = all_versioned_packages; // Coefficient initialization initialize_coeffs(nb_packages + other_vars); nb_constraints = 0; mult = ' '; for (int i = 0; i < ((int)strlen(pb_solver) - 7); i++) if ((pb_solver[i] == 'm') && (strncmp(pb_solver+i, "minisat", 7) == 0)) { mult = '*'; break; } solution = (CUDFcoefficient *)malloc(nb_vars*sizeof(CUDFcoefficient)); sprintf(ctpbfilename, TMP_FILES_PATH "ctpblib_%lu_%lu.lp", (long unsigned)getuid(), (long unsigned)getpid()); ctpbfile = fopen(ctpbfilename, "w"); if (solution == (CUDFcoefficient *)NULL) { fprintf(stderr, "lp_solver: intialize: not enough memory to store solution.\n"); exit(-1); } else if (ctpbfile == (FILE *)NULL) { fprintf(stderr, "lp_solver: intialize: can not open %s.\n", ctpbfilename); exit(-1); } else return 0; } // write the problem into a file int pblib_solver::writelp(char *filename) { return 0; } // solve the current problem int pblib_solver::solve() { int status = 0; int rank, iobjval; char command[1024]; FILE *fsol = (FILE *)NULL; bool is_scip = false; CUDFcoefficient objvals[20]; int nb_objectives = (int)objectives.size(); for (int i = 0; i < ((int)strlen(pb_solver) - 4); i++) if ((pb_solver[i] == 's') && (strncmp(pb_solver+i, "scip", 4) == 0)) { is_scip = true; break; } sprintf(pbfilename, TMP_FILES_PATH "pblib_%lu_%lu.opb", (long unsigned)getuid(), (long unsigned)getpid()); sprintf(pboutfilename, TMP_FILES_PATH "pblib_%lu_%lu.out", (long unsigned)getuid(), (long unsigned)getpid()); for (int iobj = 0; iobj < nb_objectives; iobj++) { if (objectives[iobj]->nb_coeffs == 0) continue; if ((pbfile = fopen(pbfilename, "w")) == (FILE *)NULL) { fprintf(stderr, "pblib_solver: cannot open %s.\n", pbfilename); exit(-1); } fprintf(pbfile, "* #variable= %d #constraint= %d \n* a CUDF problem\nmin:", nb_vars, nb_constraints+iobj); for (int i = 0; i < objectives[iobj]->nb_coeffs; i++) fprintf(pbfile, " "CUDFflagsplus"%cx%d", objectives[iobj]->coefficients[i], mult, objectives[iobj]->sindex[i]); fprintf(pbfile, ";\n"); for (int i = 0; i < iobj; i++) { if (objectives[i]->nb_coeffs > 0) { char *sep = (char *)""; for (int j = 0; j < objectives[i]->nb_coeffs; j++) { fprintf(pbfile, "%s"CUDFflagsplus"%cx%d", sep, objectives[i]->coefficients[j], mult, objectives[i]->sindex[j]); sep = (char *)" "; } fprintf(pbfile, " = "CUDFflags";\n", objvals[i]); } } fclose(pbfile); if (verbosity < 2) { if (is_scip) sprintf(command, "cat %s >> %s; %s -f %s > %s 2> /dev/null", ctpbfilename, pbfilename, pb_solver, pbfilename, pboutfilename); else sprintf(command, "cat %s >> %s; %s %s > %s 2> /dev/null", ctpbfilename, pbfilename, pb_solver, pbfilename, pboutfilename); } else { if (is_scip) sprintf(command, "cat %s >> %s; %s -f %s | tee %s", ctpbfilename, pbfilename, pb_solver, pbfilename, pboutfilename); else sprintf(command, "cat %s >> %s; %s %s | tee %s", ctpbfilename, pbfilename, pb_solver, pbfilename, pboutfilename); } if (system(command) == -1) { fprintf(stderr, "mccs: error while calling solver.\n"); exit(-1); } if ((fsol = fopen(pboutfilename, "r")) == (FILE *)NULL) { fprintf(stderr, "Cannot open solution file \"%s\".\n", pboutfilename); exit(-1); } for (int i = 0; i < nb_packages; i++) solution[i] = 0; if (is_scip) { int state = 1; size_t size = 2048; char buff[2048]; char *buffer = buff; while (! feof(fsol)) { /* seek : primal solution: */ int nbread = getline((char **)&buffer, &size, fsol); if ((state == 1) && (buffer[0] == 'p') && (nbread >= 16) && (strncmp(buffer, "primal solution:", 16) == 0)) { nbread = getline((char **)&buffer, &size, fsol); /* forget next line */ nbread = getline((char **)&buffer, &size, fsol); /* forget next line */ state = 2; } else if (state == 2) { if ((buffer[0] == 'n') && (nbread >= 21) && (strncmp(buffer, "no solution available", 21) == 0)) return 0; else if ((buffer[0] == 'o') && (nbread >= 16) && (strncmp(buffer, "objective value:", 16) == 0)) { int i = 17; while ((buffer[i] != '-') && ((buffer[i] < '0') || (buffer[i] > '9'))) i++; if (sscanf(buffer+i, "%d", &iobjval) > 0) objval = objvals[iobj] = iobjval; status = 1; state = 3; } } else if (state == 3) { if (buffer[0] == ' ') break; else if ((buffer[0] == 'x') && (sscanf(buffer+1, "%d", &rank) > 0)) solution[rank-1] = 1; } } } else { objval = objvals[iobj] = 0; while (! feof(fsol)) { char c = fgetc(fsol); switch (c) { case '\n': break; case 's': fgetc(fsol); if (fgets(command, 1000, fsol) != NULL) { if (strncmp(command, "OPTIMUM FOUND", 12) == 0) status = 1; else return 0; } break; case 'v': while (! feof(fsol)) { c = fgetc(fsol); if (c == '\n') break; else if (c == '-') while (! feof(fsol)) { if (fgetc(fsol) == ' ') break;} else if (c == 'x') if (fscanf(fsol, "%d", &rank) > 0) solution[rank-1] = 1; } break; case 'o': fgetc(fsol); if (fscanf(fsol, "%d", &iobjval) > 0) objval = objvals[iobj] = iobjval; default: while ((! feof(fsol)) && (fgetc(fsol) != '\n')); } } } } if (CLEAN_FILES) { remove(ctpbfilename); remove(pbfilename); remove(pboutfilename); } return status; } // get objective function value CUDFcoefficient pblib_solver::objective_value() { return objval; } // solution initialisation int pblib_solver::init_solutions() { return 0; } // return the status of a package within the final configuration CUDFcoefficient pblib_solver::get_solution(CUDFVersionedPackage *package) { return solution[package->rank]; } // initialize objective function int pblib_solver::begin_objectives(void) { return 0; } // return the package coefficient of the objective function CUDFcoefficient pblib_solver::get_obj_coeff(CUDFVersionedPackage *package) { return get_coeff(package); } // return the package coefficient of the objective function CUDFcoefficient pblib_solver::get_obj_coeff(int rank) { return get_coeff(rank); } // set the package coefficient of the objective function int pblib_solver::set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set the column coefficient of the objective function int pblib_solver::set_obj_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } int pblib_solver::new_objective(void) { reset_coeffs(); return 0; } int pblib_solver::add_objective(void) { push_obj(); return 0; } // finalize the objective function int pblib_solver::end_objectives(void) { return 0; } // initialize constraints int pblib_solver::begin_add_constraints(void) { return 0; } // begin a new constraint int pblib_solver::new_constraint(void) { reset_coeffs(); return 0; } // get the package coefficient of the current constraint CUDFcoefficient pblib_solver::get_constraint_coeff(CUDFVersionedPackage *package) { return get_coeff(package); } // get the package coefficient of the current constraint CUDFcoefficient pblib_solver::get_constraint_coeff(int rank) { return get_coeff(rank); } // set package coefficient of the current constraint int pblib_solver::set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value) { set_coeff(package, value); return 0; } // set column coefficient of the current constraint int pblib_solver::set_constraint_coeff(int rank, CUDFcoefficient value) { set_coeff(rank, value); return 0; } // add current constraint as a greater equal constraint int pblib_solver::add_constraint_geq(CUDFcoefficient bound) { char *sep = (char *)""; if (nb_coeffs > 0) { for (int i = 0; i < nb_coeffs; i++) { fprintf(ctpbfile, "%s"CUDFflagsplus"%cx%d", sep, coefficients[i], mult, sindex[i]); sep = (char *)" "; } if (bound == 0) fprintf(ctpbfile, " >= 0;\n"); else fprintf(ctpbfile, " >= "CUDFflags";\n", bound); nb_constraints++; } return 0; } // add current constraint as a less or equal constraint int pblib_solver::add_constraint_leq(CUDFcoefficient bound) { char *sep = (char *)""; if (nb_coeffs > 0) { for (int i = 0; i < nb_coeffs; i++) { fprintf(ctpbfile, "%s"CUDFflagsplus"%cx%d", sep, coefficients[i], mult, sindex[i]); sep = (char *)" "; } if (bound == 0) fprintf(ctpbfile, " <= 0;\n"); else fprintf(ctpbfile, " <= "CUDFflags";\n", bound); nb_constraints++; } return 0; } // add current constraint as an equality constraint int pblib_solver::add_constraint_eq(CUDFcoefficient bound) { char *sep = (char *)""; if (nb_coeffs > 0) { for (int i = 0; i < nb_coeffs; i++) { fprintf(ctpbfile, "%s"CUDFflagsplus"%cx%d", sep, coefficients[i], mult, sindex[i]); sep = (char *)" "; } if (bound == 0) fprintf(ctpbfile, " = 0;\n"); else fprintf(ctpbfile, " = "CUDFflags";\n", bound); nb_constraints++; } return 0; } // finalize constraints int pblib_solver::end_add_constraints(void) { fclose(ctpbfile); return 0; } mccs-1.1/sources/pblib_solver.h0000600017777601777760000000666211574427503016451 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: pblib_solver.h */ /* Concrete class for pblib format based solvers */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // concrete class which implements an interface to a pblib compliant solver #ifndef _PBLIB_SOLVER_H #define _PBLIB_SOLVER_H #include #include class pblib_solver: public abstract_solver, public scoeff_solver { public: // Solver initialization int init_solver(CUDFVersionedPackageList *all_versioned_packages, int other_vars); // Write the lp on a file int writelp(char *filename); // Solve the problem int solve(); // Get the objective value (final one) CUDFcoefficient objective_value(); // Init solutions (required before calling get_solution) int init_solutions(); // Get the solution for a package CUDFcoefficient get_solution(CUDFVersionedPackage *package); // Init the objective function definitions int begin_objectives(void); // Get current objective coefficient of package CUDFcoefficient get_obj_coeff(CUDFVersionedPackage *package); // Get current objective coefficient of a column CUDFcoefficient get_obj_coeff(int rank); // Set current objective coefficient of package int set_obj_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current objective coefficient of column int set_obj_coeff(int rank, CUDFcoefficient value); // Begin the definition of a new objective int new_objective(void); // Add current objective to the set of objectives int add_objective(void); // End objective definitions int end_objectives(void); // Init constraint definitions int begin_add_constraints(void); // Begin the definition of a new constraint int new_constraint(void); // Get current constraint coefficient of a package CUDFcoefficient get_constraint_coeff(CUDFVersionedPackage *package); // Get current constraint coefficient of a column CUDFcoefficient get_constraint_coeff(int rank); // Set current constraint coefficient of a package int set_constraint_coeff(CUDFVersionedPackage *package, CUDFcoefficient value); // Set current constraint coefficient of a column int set_constraint_coeff(int rank, CUDFcoefficient value); // Add current constraint as a more or equal constraint int add_constraint_geq(CUDFcoefficient bound); // Add current constraint as a less or equal constraint int add_constraint_leq(CUDFcoefficient bound); // Add current constraint as a equality constraint int add_constraint_eq(CUDFcoefficient bound); // End constraint definitions int end_add_constraints(void); CUDFVersionedPackageList *all_versioned_packages; // list of all versioned packages int nb_packages; // number of packages int nb_constraints; // number of constraints char mult; CUDFcoefficient *solution; // array of solution values CUDFcoefficient objval; // objective value char ctpbfilename[256]; char pbfilename[256]; char pboutfilename[256]; FILE *pbfile, *ctpbfile; char *pb_solver; // name of the solver to call // solver creation pblib_solver(char *pb_solver) { this->pb_solver = pb_solver; nb_packages = 0; all_versioned_packages = (CUDFVersionedPackageList *)NULL; nb_constraints = 0; solution = (CUDFcoefficient *)NULL; pbfile = stdout; mult = ' '; } }; #endif mccs-1.1/sources/removed_criteria.c0000600017777601777760000001021511577377270017302 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: removed_criteria.c */ /* Implementation of the removed criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include #include // Criteria initialization void removed_criteria::initialize(CUDFproblem *problem, abstract_solver *solver) { this->problem = problem; this->solver = solver; ub = lb = 0; for (CUDFVirtualPackageListIterator ivpkg = problem->all_virtual_packages->begin(); ivpkg != problem->all_virtual_packages->end(); ivpkg++) if ((*ivpkg)->highest_installed != (CUDFVersionedPackage *)NULL) { installed_virtual_packages.push_back(*ivpkg); if (criteria_opt_var) if ((*ivpkg)->all_versions.size() > 1) ub++; else lb--; else ub++; } } // Computing the number of columns required to handle the criteria int removed_criteria::set_variable_range(int first_free_var) { this->first_free_var = first_free_var; return first_free_var + ub; } // Add the criteria to the current objective function int removed_criteria::add_criteria_to_objective(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = installed_virtual_packages.begin(); ivpkg != installed_virtual_packages.end(); ivpkg++) if ((*ivpkg)->all_versions.size() > 1) solver->set_obj_coeff(ivpkg_rank++, lambda * lambda_crit); else if (criteria_opt_var) { CUDFVersionedPackage *package = (*((*ivpkg)->all_versions.begin())); solver->set_obj_coeff(package, - lambda * lambda_crit + solver->get_obj_coeff(package)); } else solver->set_obj_coeff(ivpkg_rank++, lambda * lambda_crit); return 0; } // Add the criteria to the constraint set int removed_criteria::add_criteria_to_constraint(CUDFcoefficient lambda) { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = installed_virtual_packages.begin(); ivpkg != installed_virtual_packages.end(); ivpkg++) if ((*ivpkg)->all_versions.size() > 1) solver->set_constraint_coeff(ivpkg_rank++, lambda * lambda_crit); else if (criteria_opt_var) { CUDFVersionedPackage *package = (*((*ivpkg)->all_versions.begin())); solver->set_constraint_coeff(package, - lambda * lambda_crit + solver->get_obj_coeff(package)); } else solver->set_constraint_coeff(ivpkg_rank++, lambda * lambda_crit); return 0; } // Add the constraints required by the criteria int removed_criteria::add_constraints() { int ivpkg_rank = first_free_var; for (CUDFVirtualPackageListIterator ivpkg = installed_virtual_packages.begin(); ivpkg != installed_virtual_packages.end(); ivpkg++) if ((*ivpkg)->all_versions.size() > 1) { solver->new_constraint(); for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) solver->set_constraint_coeff((*vers_pkg)->rank, +1); solver->set_constraint_coeff(ivpkg_rank, +1); solver->add_constraint_geq(+1); solver->new_constraint(); for (CUDFVersionedPackageSetIterator vers_pkg = (*ivpkg)->all_versions.begin(); vers_pkg != (*ivpkg)->all_versions.end(); vers_pkg++) solver->set_constraint_coeff((*vers_pkg)->rank, +1); { int n = (*ivpkg)->all_versions.size(); solver->set_constraint_coeff(ivpkg_rank, +n); solver->add_constraint_leq(+n); } ivpkg_rank++; } else if (! criteria_opt_var) { solver->new_constraint(); solver->set_constraint_coeff((*((*ivpkg)->all_versions.begin()))->rank, +1); solver->set_constraint_coeff(ivpkg_rank, +1); solver->add_constraint_eq(+1); ivpkg_rank++; } return 0; } // Compute the criteria range CUDFcoefficient removed_criteria::bound_range() { return CUDFabs(lambda_crit) * (ub - lb); } // Compute the criteria upper bound CUDFcoefficient removed_criteria::upper_bound() { return lambda_crit * (lambda_crit >= 0)?ub:lb; } // Compute the criteria lower bound CUDFcoefficient removed_criteria::lower_bound() { return lambda_crit * (lambda_crit >= 0)?lb:ub; } mccs-1.1/sources/removed_criteria.h0000600017777601777760000000366011574427503017305 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: removed_criteria.h */ /* Concrete class for the removed criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _REMOVED_CRITERIA_H_ #define _REMOVED_CRITERIA_H_ #include // A concrete criteria class for the removed criteria // i.e. number of virtual packages that were installed in the initial // configuration and that are not installed in the final configuration class removed_criteria: public abstract_criteria { public: CUDFproblem *problem; // a pointer to the problem abstract_solver *solver; // a pointer to the solver // list of installed virtual packages CUDFVirtualPackageList installed_virtual_packages; // column of the first variable used by the criteria int first_free_var; // Allocate some columns for the criteria int set_variable_range(int first_free_var); // Add the criteria to the objective int add_criteria_to_objective(CUDFcoefficient lambda); // Add the criteria to the constraint set int add_criteria_to_constraint(CUDFcoefficient lambda); // Add constraints required by the criteria int add_constraints(); // lower and upper bound of the criteria CUDFcoefficient ub, lb; // Compute the criteria range, upper and lower bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // Does the criteria allows problem reductions bool can_reduce(CUDFcoefficient lambda) { return true; } // Criteria initialization void initialize(CUDFproblem *problem, abstract_solver *solver); // lambda multiplier for the criteria CUDFcoefficient lambda_crit ; // Criteria initialization removed_criteria() { this->lambda_crit = +1; }; removed_criteria(CUDFcoefficient lambda_crit) { this->lambda_crit = lambda_crit; }; }; #endif mccs-1.1/sources/scoeff_solver.h0000600017777601777760000001147011574427503016617 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: scoeff_solver.h */ /* Templates to handle constraint coefficients */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // Sparse coefficient handling for solvers #ifndef _SCOEFF_SOLVER_H #define _SCOEFF_SOLVER_H #include // Template to allow coefficient saving // mainly used to save objective coefficients template class saved_coefficients { public: int nb_coeffs; // number of saved coefficients int *sindex; // column number (within the solver) of each coefficient coeffT *coefficients; // saved coefficients // return k-th coefficient inline coeffT get_coeff(int k) { return coefficients[k]; }; // return k-th index inline int get_index(int k) { return sindex[k]; }; // do save the coefficients saved_coefficients(int nb_coeffs, int *sindex, coeffT *coefficients) { int n = nb_coeffs + first_tab_index; this->nb_coeffs = nb_coeffs; if ((this->sindex = (int *)malloc(n*sizeof(int))) == 0) { fprintf(stderr, "saved_coefficients: new: not enough memory to create rindex.\n"); exit(-1); } if ((this->coefficients = (coeffT *)malloc(n*sizeof(coeffT))) == 0) { fprintf(stderr, "saved_coefficients: new: not enough memory to create coefficients.\n"); exit(-1); } for (int k = 0; k < n; k++) { this->sindex[k] = sindex[k]; this->coefficients[k] = coefficients[k]; } }; ~saved_coefficients() { free(sindex); free(coefficients); }; }; // Template used to manage the constraints and objective coefficient for a give solver // using sparse matrix // coeffT gives the type of coefficients // first_coeff_index gives the first index value used by the solver to store coefficients // first_tab_index gives the first index value used to store coefficients in the solver (some solvers do not use the 0) template class scoeff_solver { public: int nb_vars; // total amount of variables (columns) int nb_coeffs; // current number of stored coefficients int *tindex; // allow to get a coefficient from its index within the problem (=-1 for unstored coefficients) int *sindex; // column number (within the solver) of each coefficient coeffT *coefficients; // stored coefficients // Reset coefficients (required before handling another set of coefficients) void reset_coeffs(void) { for (int k = first_tab_index; k < nb_coeffs + first_tab_index; k++) tindex[sindex[k] - first_coeff_index] = -1; nb_coeffs = 0; }; // Return the coefficient of a given package (-1 if not stored) coeffT get_coeff(CUDFVersionedPackage *package) { return get_coeff(package->rank); }; // Return the coefficient of a given rank (column) (-1 if not stored) coeffT get_coeff(int rank) { if (tindex[rank] == -1) return 0; else return coefficients[tindex[rank]]; }; // Set the coefficient of a given package to value void set_coeff(CUDFVersionedPackage *package, coeffT value) { set_coeff(package->rank, value); }; // Set the coefficient of a given rank (column) to value void set_coeff(int rank, coeffT value) { if (tindex[rank] == -1) { int k = nb_coeffs + first_tab_index; tindex[rank] = k ; sindex[k] = rank + first_coeff_index; coefficients[k] = value; nb_coeffs++; } else { coefficients[tindex[rank]] = value; } }; // Initialize the structures used to store the coefficient void initialize_coeffs(int nb_vars) { int n = nb_vars + first_tab_index; this->nb_vars = nb_vars; nb_coeffs = 0; if ((tindex = (int *)malloc(n*sizeof(int))) == 0) { fprintf(stderr, "scoeff_solvers: new: not enough memory to create tindex.\n"); exit(-1); } for (int k = 0; k < n; k++) tindex[k] = -1; if ((sindex = (int *)malloc(n*sizeof(int))) == 0) { fprintf(stderr, "scoeff_solvers: new: not enough memory to create rindex.\n"); exit(-1); } if ((coefficients = (coeffT *)malloc(n*sizeof(coeffT))) == 0) { fprintf(stderr, "scoeff_solvers: new: not enough memory to create coefficients.\n"); exit(-1); } }; // Store the multiple objective functions vector *> objectives; // Save a new objective function void push_obj() { objectives.push_back(new saved_coefficients(nb_coeffs, sindex, coefficients)); } // new scoeff_solver() { }; // destructor ~scoeff_solver() { free(tindex); free(sindex); free(coefficients); }; }; #endif mccs-1.1/sources/unaligned_criteria.c0000600017777601777760000006272211613556440017606 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: unaligned_criteria.c */ /* Implementation of the unaligned criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include // Check property availability void unaligned_criteria::check_property(CUDFproblem *problem) { CUDFPropertiesIterator source_prop = problem->properties->find(string(source_name)); CUDFPropertiesIterator sourceversion_prop = problem->properties->find(string(sourceversion_name)); CUDFPropertiesIterator version_prop = problem->properties->find(string(version_name)); has_properties = false; if (source_prop == problem->properties->end()) printf("WARNING: cannot find \"%s\" property definition: criteria unaligned not used.\n", source_name); else if (sourceversion_prop == problem->properties->end()) printf("WARNING: cannot find \"%s\" property definition: criteria unaligned not used.\n", sourceversion_name); else if (version_prop == problem->properties->end()) printf("WARNING: cannot find \"%s\" property definition: criteria unaligned not used.\n", version_name); else if ((*source_prop).second->type_id != pt_string) printf("WARNING: Property \"%s\" has wrong type: criteria unaligned not used.\n", source_name); else if ((*sourceversion_prop).second->type_id != pt_string) printf("WARNING: Property \"%s\" has wrong type: criteria unaligned not used.\n", sourceversion_name); else if ((*version_prop).second->type_id != pt_string) printf("WARNING: Property \"%s\" has wrong type: criteria unaligned not used.\n", version_name); else { has_properties = true; } } // Get n number from +b version name int get_n_from_bn(char *version_name) { int n = 0; if (version_name != (char *)NULL) { int l = strlen(version_name); char *ptr = version_name + l - 1; bool has_digit = false; for (; ('0' <= *ptr) && (*ptr <= '9'); ptr--, has_digit = true); if (has_digit && (ptr > version_name) && (*ptr == 'b') && (*(ptr - 1) == '+')) n = atoi(ptr+1); } return n; } // Criteria initialization void unaligned_criteria::initialize(CUDFproblem *problem, abstract_solver *solver) { this->problem = problem; this->solver = solver; if (has_properties) { CUDFPropertiesIterator source_prop = problem->properties->find(string(source_name)); CUDFPropertiesIterator sourceversion_prop = problem->properties->find(string(sourceversion_name)); CUDFPropertiesIterator version_prop = problem->properties->find(string(version_name)); source_set = new a_source_set(1000); // Check properties availability for all packages for (CUDFVersionedPackageListIterator ipkg = problem->all_packages->begin(); ipkg != problem->all_packages->end(); ipkg++) { char *pkg_source = (char *)NULL; char *pkg_sourceversion = (char *)NULL; char *pkg_version = (char *)NULL; for (CUDFPropertyValueListIterator propval = (*ipkg)->properties.begin(); propval != (*ipkg)->properties.end(); propval++) { if ((*propval)->property == (*source_prop).second) pkg_source = (*propval)->strval; // Here is package source name else if ((*propval)->property == (*sourceversion_prop).second) pkg_sourceversion = (*propval)->strval; // Here is package source version name else if ((*propval)->property == (*version_prop).second) pkg_version = (*propval)->strval; // Here is package version name } // printf("('%s', %llu) -> '%s', '%s', '%s'\n", (*ipkg)->name, (*ipkg)->version, pkg_source, pkg_sourceversion, pkg_version); if ((pkg_source != (char *)NULL) && (pkg_sourceversion != (char *)NULL)) { // Check if we've got something for this package a_source_set_iterator source_item; string source_hash_name = string(pkg_source); int bn = 0; if (pkg_version != (char *)NULL) bn = get_n_from_bn(pkg_version); source_item = source_set->find(source_hash_name); if (source_item != source_set->end()) { // source already available a_sourceversion_set_iterator sourceversion_set_item = (source_item->second)->find(string(pkg_sourceversion)); if (sourceversion_set_item == (source_item->second)->end()) { a_pkg_compil *pkg_compil; a_pkg_compil_set *pkg_compil_set; pkg_compil = new a_pkg_compil(); (*pkg_compil)[bn] = *ipkg; pkg_compil_set = new a_pkg_compil_set(); (*pkg_compil_set)[string((*ipkg)->name)] = pkg_compil; (*(source_item->second))[string(pkg_sourceversion)] = pkg_compil_set; } else { a_pkg_compil_set_iterator pkg_compil_set_item = (sourceversion_set_item->second)->find(string((*ipkg)->name)); if (pkg_compil_set_item == (sourceversion_set_item->second)->end()) { a_pkg_compil *pkg_compil; pkg_compil = new a_pkg_compil(); (*pkg_compil)[bn] = *ipkg; (*(sourceversion_set_item->second))[string((*ipkg)->name)] = pkg_compil; } else { a_pkg_compil_iterator pkg_compil_item = (pkg_compil_set_item->second)->find(bn); if (pkg_compil_item == (pkg_compil_set_item->second)->end()) { (*(pkg_compil_set_item->second))[bn] = *ipkg; } else { fprintf(stderr, "unaligned_criteria.c: 2 packages sharing same cell: (%s, %llu) & (%s, %llu)", (*ipkg)->name, (*ipkg)->version, (pkg_compil_item->second)->name, (pkg_compil_item->second)->version); } } } } else { // source creation a_pkg_compil *pkg_compil; a_pkg_compil_set *pkg_compil_set; a_sourceversion_set *sourceversion_set; pkg_compil = new a_pkg_compil(); (*pkg_compil)[bn] = *ipkg; pkg_compil_set = new a_pkg_compil_set(); (*pkg_compil_set)[string((*ipkg)->name)] = pkg_compil; sourceversion_set = new a_sourceversion_set(); (*sourceversion_set)[string(pkg_sourceversion)] = pkg_compil_set; (*source_set)[source_hash_name] = sourceversion_set; } } } // Check properties availability for all packages // Print it out if (verbosity > 2) { printf("===================================================================================\n"); for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { int srcsize = (int)((*isrc).second)->size(); printf("source: %s\nsrcsize: %d\n", (*isrc).first.c_str(), srcsize); for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { int srcversize = (int)((*isrcver).second)->size(); printf(" source version: %s\n srcversize: %d\n", (*isrcver).first.c_str(), srcversize); for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { printf(" package: %s\n", (*ipkgset).first.c_str()); for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { printf(" b%d: (%s, %llu)\n", (*ipkg).first, ((*ipkg).second)->name, ((*ipkg).second)->version); } } } } printf("===================================================================================\n"); } // Cleanning it out (throw out any source reduced to 1 package per version) and compute nb_sources and nb_versions if (1) { nb_versions = 0; nb_packages = 0; nb_pairs = 0; for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { int srcsize = (int)((*isrc).second)->size(); int src_nb_versions = 0; int snb_packages = 0; vector verszs; for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { int srcversize = (int)((*isrcver).second)->size(); int sverpkg = 0; src_nb_versions += srcversize; for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { int size = ((*ipkgset).second)->size(); snb_packages += size; sverpkg += size; } verszs.push_back(sverpkg); } if (srcsize == 1) source_set->erase(isrc); else { nb_versions += src_nb_versions; nb_packages += snb_packages; for (int i = 0; i < srcsize -1; i++) { int sum = 0; for (int j = i+1; j < srcsize; j++) sum += verszs[j]; nb_pairs += verszs[i]*sum; } } } nb_sources = source_set->size(); if (verbosity > 0) { printf("nb_sources = %d, nb_versions = %d, nb_packages = %d, nb_pairs = %d\n", nb_sources, nb_versions, nb_packages, nb_pairs); printf("packages => %d cols\n", nb_packages+nb_versions); printf("pairs => %d cols\n", nb_pairs); printf("clusters => %d cols\n", nb_sources*2+nb_versions); printf("changes => %d cols\n", nb_sources*3+nb_versions); } } // Print it out if (verbosity > 2) for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { int srcsize = (int)((*isrc).second)->size(); printf("source: %s\nsrcsize: %d\n", (*isrc).first.c_str(), srcsize); for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { int srcversize = (int)((*isrcver).second)->size(); printf(" source version: %s\n srcversize: %d\n", (*isrcver).first.c_str(), srcversize); for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { printf(" package: %s\n", (*ipkgset).first.c_str()); for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { printf(" b%d: (%s, %llu)\n", (*ipkg).first, ((*ipkg).second)->name, ((*ipkg).second)->version); } } } } } // Has properties } // temp void unaligned_criteria::display_struct() { for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { bool installedver = false; int srcsize = (int)((*isrc).second)->size(); printf("source: %s\nsrcsize: %d\n", (*isrc).first.c_str(), srcsize); for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { bool has_installed = false; int srcversize = (int)((*isrcver).second)->size(); printf(" source version: %s\n srcversize: %d\n", (*isrcver).first.c_str(), srcversize); for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { printf(" package: %s\n", (*ipkgset).first.c_str()); for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { printf(" b%d: (%s, %llu)", (*ipkg).first, ((*ipkg).second)->name, ((*ipkg).second)->version); if (solver->get_solution((*ipkg).second)) { has_installed = true; if (installedver) printf(" -> INSTALLED !!\n"); else printf(" -> installed\n"); } else printf("\n"); } } if (has_installed) installedver = true; } } } // Initialize integer variables void unaligned_criteria::initialize_intvars() { if (has_properties) { int nbver; switch(alignment) { case ALIGNED_PACKAGES: break; case ALIGNED_PAIRS: break; case ALIGNED_CLUSTERS: nbver = first_free_var + nb_sources; for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { int size = (int)((*isrc).second)->size(); solver->set_intvar_range(nbver++, 0, size); } break; case ALIGNED_CHANGES: int nbchange = first_free_var; nbver = first_free_var + nb_sources; for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { int size = (int)((*isrc).second)->size(); solver->set_intvar_range(nbver++, 0, size); solver->set_intvar_range(nbchange++, 0, size - 1); } break; } } } // Computing the number of columns required to handle the criteria int unaligned_criteria::set_variable_range(int first_free_var) { if (has_properties) { this->first_free_var = first_free_var; switch(alignment) { case ALIGNED_PACKAGES: return first_free_var + nb_packages + nb_versions; case ALIGNED_PAIRS: return first_free_var + nb_pairs; case ALIGNED_CLUSTERS: return first_free_var + nb_sources*2 + nb_versions; case ALIGNED_CHANGES: return first_free_var + nb_sources*3 + nb_versions; } return first_free_var; } else return first_free_var; } // Add the criteria to the current objective function int unaligned_criteria::add_criteria_to_objective(CUDFcoefficient lambda) { if (has_properties) { switch(alignment) { case ALIGNED_PACKAGES: for (int i = 0; i < nb_packages; i++) solver->set_obj_coeff(first_free_var + i, lambda_crit * lambda); break; case ALIGNED_PAIRS: for (int i = 0; i < nb_pairs; i++) solver->set_obj_coeff(first_free_var + i, lambda_crit * lambda); break; case ALIGNED_CLUSTERS: for (int i = 0; i < nb_sources; i++) solver->set_obj_coeff(first_free_var + i, lambda_crit * lambda); break; case ALIGNED_CHANGES: for (int i = 0; i < nb_sources; i++) solver->set_obj_coeff(first_free_var + i, lambda_crit * lambda); break; } } return 0; } // Add the criteria to the constraint set int unaligned_criteria::add_criteria_to_constraint(CUDFcoefficient lambda) { if (has_properties) { switch(alignment) { case ALIGNED_PACKAGES: for (int i = 0; i < nb_packages; i++) solver->set_constraint_coeff(first_free_var + i, lambda_crit * lambda); break; case ALIGNED_PAIRS: for (int i = 0; i < nb_pairs; i++) solver->set_constraint_coeff(first_free_var + i, lambda_crit * lambda); break; case ALIGNED_CLUSTERS: for (int i = 0; i < nb_sources; i++) solver->set_constraint_coeff(first_free_var + i, lambda_crit * lambda); break; case ALIGNED_CHANGES: for (int i = 0; i < nb_sources; i++) solver->set_constraint_coeff(first_free_var + i, lambda_crit * lambda); break; } } return 0; } // Add the constraints required by the criteria int unaligned_criteria::add_constraints() { if (has_properties) { if (alignment == ALIGNED_CHANGES) { // ======================================================================================= int nbchange = first_free_var; int nbver = first_free_var + nb_sources; int cond = first_free_var + nb_sources*2; int version = first_free_var + nb_sources*3; // sum(pkg) - ver >= 0 for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { solver->new_constraint(); for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { solver->set_constraint_coeff(((*ipkg).second), +1); } } solver->set_constraint_coeff(version++, -1); solver->add_constraint_geq(0); } } version = first_free_var + nb_sources*3; // for each pkg, ver - pkg >= 0 for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { solver->new_constraint(); solver->set_constraint_coeff(version, +1); solver->set_constraint_coeff(((*ipkg).second), -1); solver->add_constraint_geq(0); } } version++; } } version = first_free_var + nb_sources*3; for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { // nbver = sum(versions) solver->new_constraint(); for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) solver->set_constraint_coeff(version++, +1); solver->set_constraint_coeff(nbver, -1); solver->add_constraint_eq(0); // max nb version * cond - nbver >= 0 (set cond to 1 iff nbver >= 1) solver->new_constraint(); solver->set_constraint_coeff(cond, (int)((*isrc).second)->size()); solver->set_constraint_coeff(nbver, -1); solver->add_constraint_geq(0); // nbver - cond >= 0 (set cond to 0 iff nbver = 0) solver->new_constraint(); solver->set_constraint_coeff(nbver, +1); solver->set_constraint_coeff(cond, -1); solver->add_constraint_geq(0); // nbchange = nbver - cond == nbchange - nbver + cond = 0 solver->new_constraint(); solver->set_constraint_coeff(nbchange++, +1); solver->set_constraint_coeff(nbver++, -1); solver->set_constraint_coeff(cond++, +1); solver->add_constraint_eq(0); } } else if (alignment == ALIGNED_CLUSTERS) { // ======================================================================================= int cluster = first_free_var; int nbver = first_free_var + nb_sources; int version = first_free_var + 2*nb_sources; // sum(pkg) - ver >= 0 for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { solver->new_constraint(); for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { solver->set_constraint_coeff(((*ipkg).second), +1); } } solver->set_constraint_coeff(version++, -1); solver->add_constraint_geq(0); } } version = first_free_var + 2*nb_sources; // for each pkg, ver - pkg >= 0 for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { solver->new_constraint(); solver->set_constraint_coeff(version, +1); solver->set_constraint_coeff(((*ipkg).second), -1); solver->add_constraint_geq(0); } } version++; } } version = first_free_var + 2*nb_sources; for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { // nbver = sum(versions) solver->new_constraint(); for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) solver->set_constraint_coeff(version++, +1); solver->set_constraint_coeff(nbver, -1); solver->add_constraint_eq(0); // max nb version * cluster - nbver >= -1 (set cluster to 1 iff nbver >= 2) solver->new_constraint(); solver->set_constraint_coeff(cluster, (int)((*isrc).second)->size()); solver->set_constraint_coeff(nbver, -1); solver->add_constraint_geq(-1); // nbver - 2 * cluster >= 0 (set cluster to 0 iff nbver <= 1) solver->new_constraint(); solver->set_constraint_coeff(nbver++, +1); solver->set_constraint_coeff(cluster++, -2); solver->add_constraint_geq(0); } } else if (alignment == ALIGNED_PACKAGES) { // ======================================================================================= int nalignpkg = first_free_var; int version = first_free_var + nb_packages; // sum(pkg) - ver >= 0 for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { solver->new_constraint(); for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { solver->set_constraint_coeff(((*ipkg).second), +1); } } solver->set_constraint_coeff(version++, -1); solver->add_constraint_geq(0); } } version = first_free_var + nb_packages; // for each pkg, ver - pkg >= 0 for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { solver->new_constraint(); solver->set_constraint_coeff(version, +1); solver->set_constraint_coeff(((*ipkg).second), -1); solver->add_constraint_geq(0); } } version++; } } version = first_free_var + nb_packages; int sourceversion = version; for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { int nbver = ((*isrc).second)->size(); int ver = 0; for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { // nalignpkg <= pkgi i.e. nalignpkg = 0 if pkgi not installed solver->new_constraint(); solver->set_constraint_coeff(nalignpkg, -1); solver->set_constraint_coeff(((*ipkg).second), +1); solver->add_constraint_geq(0); // nalignpkg >= version + pkgi -1 i.e. nalignpkg = 1 iff pkgi = 1 and version = 1 for (int v = 0; v < nbver; v++) if (v != ver) { solver->new_constraint(); solver->set_constraint_coeff(nalignpkg, +1); solver->set_constraint_coeff(sourceversion + v, -1); solver->set_constraint_coeff(((*ipkg).second), -1); solver->add_constraint_geq(-1); } // nalignpkg <= sum(version != pkgi version) i.e. nalignpkg = 0 iff none other version installed solver->new_constraint(); for (int v = 0; v < nbver; v++) if (v != ver) { solver->set_constraint_coeff(sourceversion + v, +1); } solver->set_constraint_coeff(nalignpkg, -1); solver->add_constraint_geq(0); nalignpkg++; } } ver++; version++; } sourceversion = version; } } else if (alignment == ALIGNED_PAIRS) { // ======================================================================================= int nalignpair = first_free_var; // printf("nb_packages = %d\n", nb_packages); for (a_source_set_iterator isrc = source_set->begin(); isrc != source_set->end(); isrc++) { for (a_sourceversion_set_iterator isrcver = ((*isrc).second)->begin(); isrcver != ((*isrc).second)->end(); isrcver++) { for (a_pkg_compil_set_iterator ipkgset = ((*isrcver).second)->begin(); ipkgset != ((*isrcver).second)->end(); ipkgset++) { for (a_pkg_compil_iterator ipkg = ((*ipkgset).second)->begin(); ipkg != ((*ipkgset).second)->end(); ipkg++) { for (a_sourceversion_set_iterator isrcveri = isrcver; isrcveri != ((*isrc).second)->end(); isrcveri++) { if (isrcver != isrcveri) for (a_pkg_compil_set_iterator ipkgseti = ((*isrcveri).second)->begin(); ipkgseti != ((*isrcveri).second)->end(); ipkgseti++) { for (a_pkg_compil_iterator ipkgi = ((*ipkgseti).second)->begin(); ipkgi != ((*ipkgseti).second)->end(); ipkgi++) { // printf("x%d = (%s, %llu) and (%s, %llu)\n", nalignpair, // ((*ipkg).second)->name, ((*ipkg).second)->version, // ((*ipkgi).second)->name, ((*ipkgi).second)->version); // nalignpair <= ipkg i.e. nalignpair = 0 if ipkg not installed solver->new_constraint(); solver->set_constraint_coeff(((*ipkg).second), +1); solver->set_constraint_coeff(nalignpair, -1); solver->add_constraint_geq(0); // nalignpair <= ipkgi i.e. nalignpair = 0 if ipkgi not installed solver->new_constraint(); solver->set_constraint_coeff(((*ipkgi).second), +1); solver->set_constraint_coeff(nalignpair, -1); solver->add_constraint_geq(0); // nalignpair >= ipkg + ipkgi - 1 i.e. nalignpair = 1 if ipkg and ipkgi are installed solver->new_constraint(); solver->set_constraint_coeff(((*ipkg).second), -1); solver->set_constraint_coeff(((*ipkgi).second), -1); solver->set_constraint_coeff(nalignpair, +1); solver->add_constraint_geq(-1); nalignpair++; } } } } } } } } } return 0; } // Compute the criteria range CUDFcoefficient unaligned_criteria::bound_range() { if (has_properties) switch(alignment) { case ALIGNED_PACKAGES: return lambda_crit * nb_packages; case ALIGNED_PAIRS: return lambda_crit * nb_pairs; case ALIGNED_CLUSTERS: return lambda_crit * nb_sources; case ALIGNED_CHANGES: return lambda_crit * nb_versions; } return 0; } // Compute the criteria upper bound CUDFcoefficient unaligned_criteria::upper_bound() { return bound_range(); } // Compute the criteria lower bound CUDFcoefficient unaligned_criteria::lower_bound() { return 0; } mccs-1.1/sources/unaligned_criteria.h0000600017777601777760000000756111577623600017615 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: unaligned_criteria.h */ /* Concrete class for the unaligned criteria */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef _UNALIGNED_CRITERIA_H_ #define _UNALIGNED_CRITERIA_H_ #include #include // allowed type of alignments #define ALIGNED_PACKAGES 1 #define ALIGNED_PAIRS 2 #define ALIGNED_CLUSTERS 3 #define ALIGNED_CHANGES 4 typedef map a_pkg_compil; typedef a_pkg_compil::iterator a_pkg_compil_iterator; typedef map a_pkg_compil_set; typedef a_pkg_compil_set::iterator a_pkg_compil_set_iterator; typedef map a_sourceversion_set; typedef a_sourceversion_set::iterator a_sourceversion_set_iterator; typedef tr1::unordered_map a_source_set; typedef a_source_set::iterator a_source_set_iterator; // A concrete class for the unaligned criteria // i.e. number of unaligned packages, pairs of packages, // clusters or changes with respect to a given source class unaligned_criteria: public abstract_criteria { public: CUDFproblem *problem; // a pointer to the problem abstract_solver *solver; // a pointer to the solver char *version_name; // property that holds the full version as a string char *source_name; // property that holds source package name char *sourceversion_name; // property that holds source version as a string bool has_properties; // are the properties available // set of sources a_source_set *source_set; int nb_sources; // number of sources with more than one versionned package int nb_versions; // total amount of versions among sources with more than one versionned package int nb_packages; // total amount of versionned packages among sources with more than one versionned package int nb_pairs; int range; // criteria range // column of the first variable used by the criteria int first_free_var; // Allocate some columns for the criteria int set_variable_range(int first_free_var); // Initialize integer variable ranges void initialize_intvars(); // Add the criteria to the objective int add_criteria_to_objective(CUDFcoefficient lambda); // Add the criteria to the constraint set int add_criteria_to_constraint(CUDFcoefficient lambda); // Add constraints required by the criteria int add_constraints(); // Compute the criteria range, upper and lower bounds CUDFcoefficient bound_range(); CUDFcoefficient upper_bound(); CUDFcoefficient lower_bound(); // Does the criteria allows problem reductions bool can_reduce(CUDFcoefficient lambda) { return ((lambda >= 0) && (lambda_crit >= 0)); } // Criteria initialization void initialize(CUDFproblem *problem, abstract_solver *solver); void check_property(CUDFproblem *problem); // lambda multiplier for the criteria CUDFcoefficient lambda_crit ; // type of alignment int alignment; // temp void display_struct(); // Criteria creation unaligned_criteria(int alignment, char *source_name, char *sourceversion_name, char *version_name) { this->alignment = alignment; this->source_name = source_name; this->sourceversion_name = sourceversion_name; this->version_name = version_name; this->lambda_crit = +1; nb_sources = nb_versions = nb_packages = nb_pairs = 0; }; unaligned_criteria(int alignment, char *source_name, char *sourceversion_name, char *version_name, CUDFcoefficient lambda_crit) { this->alignment = alignment; this->source_name = source_name; this->sourceversion_name = sourceversion_name; this->version_name = version_name; this->lambda_crit = lambda_crit; nb_sources = nb_versions = nb_packages = nb_pairs = 0; }; }; #endif mccs-1.1/libsrcs/cudf.h0000600017777601777760000002774111574427503014667 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf.h */ /* Handling of CUDF problem files */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // main CUDF include file #ifndef _CUDF_H #define _CUDF_H #include #include #include #include #include #include #include #include using namespace std; // class predeclarations class CUDFPropertyValue; class CUDFPackage; class CUDFVersionedPackage; class CUDFVirtualPackage; class CUDFPackage_comparator; class CUDFProperty; // type of list of property values and its iterator typedef vector CUDFPropertyValueList; typedef vector::iterator CUDFPropertyValueListIterator; // type of the version of a package typedef unsigned long long CUDFVersion; // the different types of operations which can be done on a package enum CUDFPackageOp { op_none, op_eq, op_neq, op_inf, op_sup, op_infeq, op_supeq}; // CUDF class for a vpkg class CUDFVpkg { public: CUDFVirtualPackage *virtual_package; // the package it operates on CUDFPackageOp op; // kind of operation CUDFVersion version; // version it operates on (e.g. 5 in p >= 5) // constructor CUDFVpkg(CUDFVirtualPackage *the_virtual_package, CUDFPackageOp the_op, CUDFVersion the_version) { virtual_package = the_virtual_package; op = the_op; version = the_version; }; }; // true and false for a vpkg extern CUDFVpkg *vpkg_true; extern CUDFVpkg *vpkg_false; // A package i.e. either a versioned package or a virtual package class CUDFPackage { public: char *name; // package name as provided by the CUDF problem file int rank; // rank of the package, i.e., column number in a simplex matrix or variable id char *versioned_name; // internal name of the package bool in_reduced; }; // type of a CUDF Vpkg list and its iterator type typedef vector CUDFVpkgList; typedef CUDFVpkgList::iterator CUDFVpkgListIterator; // type of a CUDF Vpkg formula and its iterator type typedef vector< CUDFVpkgList *> CUDFVpkgFormula; typedef CUDFVpkgFormula::iterator CUDFVpkgFormulaIterator; // The different types of keep operations enum CUDFKeepOp { keep_none, keep_feature, keep_package, keep_version}; // Versioned package class (used to store a couple) class CUDFVersionedPackage: public CUDFPackage { public: CUDFVersion version; // package version CUDFVpkgFormula *depends; // package dependencies CUDFVpkgList *conflicts; // package conflicts CUDFVpkgList *provides; // features provided by the package bool installed; // whether the package is installed in the initial configuration bool wasinstalled; // whether the package was installed CUDFKeepOp keep; // keep field value CUDFPropertyValueList properties; // set of additional properties of the package CUDFVirtualPackage *virtual_package; // pointer to the virtual package the package belongs to CUDFVersionedPackage(const char *pkg_name, int my_rank); // constructor void set_version(CUDFVersion pkg_version); // allows to set the package version (not always known at package creation) }; // Compares two versioned package (used by ordered set packages likes CUDFVersionedPackageSet) class CUDFPackage_comparator { public: bool operator()(CUDFVersionedPackage *p1, CUDFVersionedPackage *p2) { if (p1->version < p2->version) return true; else return false; } }; // type of an ordered set of versioned packages and its iterator type typedef set CUDFVersionedPackageSet; typedef CUDFVersionedPackageSet::iterator CUDFVersionedPackageSetIterator; // type of a list of providers and its iterator type typedef vector CUDFProviderList; typedef CUDFProviderList::iterator CUDFProviderListIterator; // type of a list of versioned providers and its iterator type typedef map CUDFVersionedProviderList; typedef CUDFVersionedProviderList::iterator CUDFVersionedProviderListIterator; // Virtual packages or features class CUDFVirtualPackage: public CUDFPackage { public: CUDFVersionedPackageSet all_versions; // set of all versions of the package (versioned packages with the same name) CUDFVersionedPackage *highest_installed; // highest version of the installed versioned packages CUDFVersion highest_version; // highest available version of the versioned packages CUDFProviderList providers; // list of all the packages (with a different name than the virtual package name) // which provide this feature (without providing a version) CUDFVersionedProviderList versioned_providers; // list of all the packages (with a different name than the virtual package name) // which provide this feature with a version CUDFVersion highest_installed_provider_version; // highest installed version of the providers CUDFVirtualPackage(const char *pkg_name, int my_rank); // constructor }; // type of a list of versioned packages and its iterator type typedef vector CUDFVersionedPackageList; typedef CUDFVersionedPackageList::iterator CUDFVersionedPackageListIterator; // type of a list of virtual packages and its iterator type typedef vector CUDFVirtualPackageList; typedef CUDFVirtualPackageList::iterator CUDFVirtualPackageListIterator; // type of an enums and its iterator type typedef vector CUDFEnums; typedef vector::iterator CUDFEnumsIterator; // get enum "estr" from "e" enum list extern char *get_enum(CUDFEnums *e, char *estr); // a property mapping type and its iterator type typedef map CUDFProperties; typedef CUDFProperties::iterator CUDFPropertiesIterator; // all user defined properties extern CUDFProperties properties; // Types allowed for properties enum CUDFPropertyType { pt_none, pt_bool, pt_int, pt_nat, pt_posint, pt_enum, pt_string, pt_vpkg, pt_veqpkg, pt_vpkglist, pt_veqpkglist, pt_vpkgformula}; // Class to describe user defined property values class CUDFPropertyValue { public: CUDFProperty *property; // type of the property value int intval; // use to store property value when its basic type is an int char *strval; // use to store property value when its basic type is a string CUDFVpkg *vpkg; // use to store property value when its basic type is a vpkg CUDFVpkgList *vpkglist; // use to store property value when its basic type is a vpkglist CUDFVpkgFormula *vpkgformula; // use to store property value when its basic type is a vpkgformula CUDFPropertyValue(CUDFProperty *the_property, int the_value); // constructor for int valued properties CUDFPropertyValue(CUDFProperty *the_property, char *the_value); // constructor for string valued properties CUDFPropertyValue(CUDFProperty *the_property, CUDFVpkg *the_value); // constructor for vpkg valued properties CUDFPropertyValue(CUDFProperty *the_property, CUDFVpkgList *the_value); // constructor for vpkglist valued properties CUDFPropertyValue(CUDFProperty *the_property, CUDFVpkgFormula *the_value); // constructor for vpkgformula valued properties }; // Class to describe user defined properties class CUDFProperty { public: char *name; // property name CUDFPropertyType type_id; // property type CUDFEnums *enuml; // allowed enum values for enum type properties bool required; // whether the property id required or not CUDFPropertyValue *default_value; // default property value CUDFProperty(char *tname, CUDFPropertyType ttype); // CUDF property constructors (without and with default value) CUDFProperty(char *tname, CUDFPropertyType ttype, int tdefault); CUDFProperty(char *tname, CUDFPropertyType ttype, char *tdefault); CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFEnums *tenum); CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFEnums *tenum, char *tident); CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFVpkg *tdefault); CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFVpkgList *tdefault); CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFVpkgFormula *tdefault); }; // A CUDF problem class class CUDFproblem { public: // Problem's properties CUDFProperties *properties; // list of user property declarations // Problem's packages CUDFVersionedPackageList *all_packages; // list of all the versioned packages of the initial configuration CUDFVersionedPackageList *installed_packages; // list of all installed versioned packages in the initial configuration CUDFVersionedPackageList *uninstalled_packages; // list of all uninstalled versioned packages in the inital configuration // Problem's virtual packages CUDFVirtualPackageList *all_virtual_packages; // list of all the virtual packages in the initial configuration // Problem's requests CUDFVpkgList *install; // Vpkg list of the packages to install CUDFVpkgList *remove; // Vpkg list of the packages to remove CUDFVpkgList *upgrade; // Vpkg list of the packages to upgrade CUDFproblem() { // constructor install = (CUDFVpkgList *)NULL; remove = (CUDFVpkgList *)NULL; upgrade = (CUDFVpkgList *)NULL; } }; // current CUDF problem extern CUDFproblem *the_problem; // list of all the versioned packages of the initial configuration extern CUDFVersionedPackageList all_packages; // list of all installed versioned packages in the initial configuration extern CUDFVersionedPackageList installed_packages; // list of all uninstalled versioned packages in the inital configuration extern CUDFVersionedPackageList uninstalled_packages; // list of all the virtual packages in the initial configuration extern CUDFVirtualPackageList all_virtual_packages; // parse the CUDF problem from input_file extern int parse_cudf(FILE *input_file); // operations to compare a package version to another one extern bool op_none_comp(CUDFVersion v1, CUDFVersion v2); extern bool op_eq_comp(CUDFVersion v1, CUDFVersion v2); extern bool op_neq_comp(CUDFVersion v1, CUDFVersion v2); extern bool op_sup_comp(CUDFVersion v1, CUDFVersion v2); extern bool op_supeq_comp(CUDFVersion v1, CUDFVersion v2); extern bool op_inf_comp(CUDFVersion v1, CUDFVersion v2); extern bool op_infeq_comp(CUDFVersion v1, CUDFVersion v2); typedef bool (*a_compptr)(CUDFVersion, CUDFVersion); // get the comparison operation from a package operation extern a_compptr get_comparator(CUDFPackageOp op); // Printing out capabilities extern void print_enum(FILE *output, CUDFEnums *enuml); // print out a list of enums extern void print_properties(FILE *output, CUDFProperties *properties); // print out a property // print out a versioned package as installed if install parameter is true, uninstalled otherwise extern void print_versioned_package_with_install(FILE *output, CUDFVersionedPackage *pkg, bool install, bool wasinstalled); // print out a versioned package extern void print_versioned_package(FILE *output, CUDFVersionedPackage *pkg, bool wasinstalled); // print out a versioned package as installed extern void print_versioned_package_as_installed(FILE *output, CUDFVersionedPackage *pkg, bool wasinstalled); // print out a virtual package extern void print_virtual_package(FILE *output, CUDFVirtualPackage *vpkg); // print out a problem extern void print_problem(FILE *output, CUDFproblem *pbs); // handling verbosity level extern int verbosity; #endif mccs-1.1/libsrcs/cudf_hash_table.c0000600017777601777760000000764211574427503017032 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf_hash_table.c */ /* Handling hash tables to get a virtual package from */ /* it name */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ // CUDF hash table capabilities // used to get a virtual package from its name #include #ifdef HASH_STRING #include #endif an_hash_table cudf_packages(5); int virtual_package_rank = 0; // return a virtual package knowing its name #ifdef HASH_STRING CUDFVirtualPackage *get_virtual_package(const char *pkgname) { CUDFVirtualPackage *pkg; an_hash_table_iterator pkg_item; string hash_name = string(pkgname); pkg_item = cudf_packages.find(hash_name); if (pkg_item == cudf_packages.end()) { // printf("get_virtual_package create \"%s\"\n", hash_name); pkg = new CUDFVirtualPackage(pkgname, virtual_package_rank++); all_virtual_packages.push_back(pkg); cudf_packages[hash_name] = pkg; } else { // printf("get_virtual_package reuse \"%s\"\n", hash_name); pkg = pkg_item->second; } if (strcmp(pkgname, pkg->name) != 0) { int lgth; printf("NAME CLASH FOR \"%s\" : got \"%s\"\n", pkgname, pkg->name); lgth = strlen(pkgname); for (int i = 0; i < lgth; i++) if (pkgname[i] < 32) printf("\\%2d", pkgname[i]); else printf("%c", pkgname[i]); printf("\n"); lgth = strlen(pkg->name); for (int i = 0; i < lgth; i++) if (pkgname[i] < 32) printf("\\%2d", pkg->name[i]); else printf("%c", pkg->name[i]); printf("\n"); exit(1); } return pkg; } #else char hash_name[1024]; /* Always use the same buffer for hash table ... otherwise it stucks ... */ CUDFVirtualPackage *get_virtual_package(const char *pkgname) { CUDFVirtualPackage *pkg; an_hash_table_iterator pkg_item; strcpy(hash_name, pkgname); // printf("Handling 2 %s.\n", pkgname); pkg_item = cudf_packages.find(hash_name); if (pkg_item == cudf_packages.end()) { printf("get_virtual_package create \"%s\"\n", hash_name); pkg = new CUDFVirtualPackage(hash_name, virtual_package_rank++); all_virtual_packages.push_back(pkg); cudf_packages[hash_name] = pkg; } else { printf("get_virtual_package reuse \"%s\"\n", hash_name); pkg = pkg_item->second; } if (strcmp(pkgname, pkg->name) != 0) { int lgth; printf("NAME CLASH FOR \"%s\" : got \"%s\"\n", pkgname, pkg->name); lgth = strlen(pkgname); for (int i = 0; i < lgth; i++) if (pkgname[i] < 32) printf("\\%2d", pkgname[i]); else printf("%c", pkgname[i]); printf("\n"); lgth = strlen(pkg->name); for (int i = 0; i < lgth; i++) if (pkgname[i] < 32) printf("\\%2d", pkg->name[i]); else printf("%c", pkg->name[i]); printf("\n"); exit(1); } return pkg; } CUDFVirtualPackage *get_virtual_package_old(const char *pkgname) { CUDFVirtualPackage *pkg; an_hash_table_iterator pkg_item; pkg_item = cudf_packages.find(pkgname); if (pkg_item == cudf_packages.end()) { printf("get_virtual_package create \"%s\"\n", pkgname); pkg = new CUDFVirtualPackage(pkgname, virtual_package_rank++); all_virtual_packages.push_back(pkg); cudf_packages[pkgname] = pkg; } else { printf("get_virtual_package reuse \"%s\"\n", pkgname); pkg = pkg_item->second; } if (strcmp(pkgname, pkg->name) != 0) { int lgth; printf("NAME CLASH FOR \"%s\" : got \"%s\"\n", pkgname, pkg->name); lgth = strlen(pkgname); for (int i = 0; i < lgth; i++) if (pkgname[i] < 32) printf("\\%2d", pkgname[i]); else printf("%c", pkgname[i]); printf("\n"); lgth = strlen(pkg->name); for (int i = 0; i < lgth; i++) if (pkgname[i] < 32) printf("\\%2d", pkg->name[i]); else printf("%c", pkg->name[i]); printf("\n"); exit(1); } return pkg; } #endif mccs-1.1/libsrcs/cudf_hash_table.h0000600017777601777760000000331411574427503017027 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf_hash_table.h */ /* Handling hash tables to get a virtual package from */ /* it name */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #ifndef CUDF_HASH_TABLE_H #define CUDF_HASH_TABLE_H #include //#define HASHMAP 1 #ifdef HASHMAP #include #else #include #endif #define HASH_STRING 1 #ifdef HASH_STRING #ifdef HASHMAP typedef __gnu_cxx::hash_map an_hash_table; typedef __gnu_cxx::hash_map::iterator an_hash_table_iterator; #else typedef tr1::unordered_map an_hash_table; typedef tr1::unordered_map::iterator an_hash_table_iterator; #endif #else // required by hash table to compare two strings struct eqstr { bool operator()(const char* s1, const char* s2) const { return (strcmp(s1, s2) == 0); } }; #ifdef HASHMAP typedef __gnu_cxx::hash_map, eqstr> an_hash_table; typedef __gnu_cxx::hash_map, eqstr>::iterator an_hash_table_iterator; #else typedef tr1::unordered_map, eqstr> an_hash_table; typedef tr1::unordered_map, eqstr>::iterator an_hash_table_iterator; #endif #endif // return a virtual package knowing its name extern CUDFVirtualPackage *get_virtual_package(const char *pkgname); #endif mccs-1.1/libsrcs/cudf.l0000600017777601777760000001210711574427503014661 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf.l */ /* Lexical analyser of CUDF problems */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ /* Based on flex lexical analizer generator*/ %{ #include #include #include #define STRLIMIT 5000 /* max string size */ char astring[STRLIMIT]; int strsize = 0; extern int pidenttype(char *pname); %} %x anstr keepstate proptype linestring %option yylineno %option noyywrap %% preamble: return PREAMBLE; property: return PROPERTYDEF; package: return PACKAGE; version: return VERSION; depends: return DEPENDS; conflicts: return CONFLICTS; provides: return PROVIDES; installed: return INSTALLED; was-installed: return WASINSTALLED; keep: { BEGIN(keepstate); return KEEP; } true return TRUE; false return FALSE; true! return VTRUE; false! return VFALSE; = return EQ; != return NEQ; > return SUP; >= return SUPEQ; \< return INF; \<= return INFEQ; version { BEGIN(INITIAL); return KEEPVERSION; } package { BEGIN(INITIAL); return KEEPPACKAGE; } feature { BEGIN(INITIAL); return KEEPFEATURE; } none { BEGIN(INITIAL); return KEEPNONE; } [\t ] . fprintf(stderr, "CUDF scanner error: Unrecognized character in keep state value: %s\n", yytext); request:[^\n]* return PROBLEM; install: return INSTALL; remove: return REMOVE; upgrade: return UPGRADE; univ-checksum:[^\n]* /* Ignore */ status-checksum:[^\n]* /* Ignore */ req-checksum:[^\n]* /* Ignore */ \" { strsize = 0; BEGIN(anstr); } /* handling strings */ \" { BEGIN(INITIAL); astring[strsize++] = '\0'; return STRING; } \\\" { if (strsize < STRLIMIT) astring[strsize++] = yytext[1]; else { fprintf(stderr, "CUDF error (line %d): string are limited to %d characters.\n", cudflineno, STRLIMIT); exit(-1); } } [^"] { if (strsize < STRLIMIT) astring[strsize++] = yytext[0]; else { fprintf(stderr, "CUDF error (line %d): string are limited to %d characters.\n", cudflineno, STRLIMIT); exit(-1); } } [^\n]* { BEGIN(INITIAL); strcpy(astring, (yytext + 1)); return STRING; } [+-]?[0-9]+ { strcpy(cudflval.str, yytext); return INTEGER; } /* handling integers */ [a-zA-Z0-9+*_%/\-\.@]*[ \t]*":" { /* user property names */ int l = (int)strlen(yytext), i; for (i = 0; i < l; i++) if ((yytext[i] == ' ') || (yytext[i] == '\t')) { cudflval.str[i] = ':'; break; } else cudflval.str[i] = yytext[i]; if (cudflval.str[i-1] != ':') cudflval.str[i++] = ':'; cudflval.str[i] = '\0'; switch(pidenttype(cudflval.str)) { case pt_bool: return PIDENT_BOOL; case pt_int: return PIDENT_INT; case pt_nat: return PIDENT_NAT; case pt_posint: return PIDENT_POSINT; case pt_enum: return PIDENT_ENUM; case pt_string: BEGIN(linestring); return PIDENT_STRING; case pt_vpkg: return PIDENT_VPKG; case pt_veqpkg: return PIDENT_VEQPKG; case pt_vpkglist: return PIDENT_VPKGLIST; case pt_veqpkglist: return PIDENT_VEQPKGLIST; case pt_vpkgformula: return PIDENT_VPKGFORMULA; case pt_none: default: return PIDENT; } } [a-zA-Z0-9+*_%/\-\.@()]* { strcpy(cudflval.str, yytext); return IDENT; } #[^\n]* /* comment */ [,:|\[\]] return yytext[0]; [\t\n ] /* Just ignore spaces */ . fprintf(stderr, "CUDF scanner error: Unrecognized character: %s\n", yytext); %% mccs-1.1/libsrcs/cudf_tools.c0000600017777601777760000005147411574427503016102 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf_tools.h */ /* Tools to handle CUDF problems */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ #include // Handling verbosity level int verbosity = 0; // List of all the user declared properties CUDFProperties properties; // True and false for Vpkg CUDFVpkg *vpkg_true = new CUDFVpkg((CUDFVirtualPackage *)NULL, op_none, 0); CUDFVpkg *vpkg_false = new CUDFVpkg((CUDFVirtualPackage *)NULL, op_none, 0); // Versioned package constructor // requires package name and unique package ident (i.e. simplex column number) CUDFVersionedPackage::CUDFVersionedPackage(const char *pkg_name, int my_rank) { // Get some piece of memory to store package name if ((name = (char *)malloc(strlen(pkg_name)+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for CUDFVersionedPackage.\n"); exit(-1); } strcpy(name, pkg_name); // Default initialization of variables versioned_name = (char *)NULL; version = 0; installed = false; wasinstalled = false; keep = keep_none; depends = (CUDFVpkgFormula *)NULL; conflicts = (CUDFVpkgList *)NULL; provides = (CUDFVpkgList *)NULL; virtual_package = (CUDFVirtualPackage *)NULL; rank = my_rank; in_reduced = false; } // Set the version of a package // requires package version // assumes that package name is already available void CUDFVersionedPackage::set_version(CUDFVersion pkg_version) { static char temp[50]; sprintf(temp, "%llu", pkg_version); if ((versioned_name = (char *)malloc(strlen(name)+strlen(temp)+2)) == NULL) { fprintf(stderr, "error: cannot alloc versioned_name for CUDFVersionedPackage.\n"); exit(-1); } sprintf(versioned_name, "%s_%s", name, temp); version = pkg_version; } // Virtual package constructor // requires virtual package name and virtual package rank CUDFVirtualPackage::CUDFVirtualPackage(const char *pkg_name, int my_rank) { if ((name = (char *)malloc(strlen(pkg_name)+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for CUDFVirtualPackage.\n"); exit(-1); } strcpy(name, pkg_name); versioned_name = name; highest_installed = (CUDFVersionedPackage *)NULL; highest_version = 0; highest_installed_provider_version = 0; rank = my_rank; in_reduced = false; } // User property constructor // requires property name and type of the property CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = true; default_value = (CUDFPropertyValue *)NULL; } // User property constructor // requires property name, type of the property (must be an int subtype) and int default value CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype, int tdefault) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = false; // Checking property if ((type_id == pt_bool) && (tdefault != 0) && (tdefault != 1)) { fprintf(stderr, "CUDF error: default value for property %s: bool must be true or false.\n", tname); exit(-1); } if ((type_id == pt_nat) && (tdefault < 0)) { fprintf(stderr, "CUDF error: default value for property %s: nat must be >= 0.\n", tname); exit(-1); } if ((type_id == pt_posint) && (tdefault <= 0)) { fprintf(stderr, "CUDF error: default value for property %s: posint must be > 0.\n", tname); exit(-1); } default_value = new CUDFPropertyValue(this, tdefault); } // User property constructor // requires property name, type of the property (must be a string subtype) and string default value CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype, char *tdefault) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = false; default_value = new CUDFPropertyValue(this, tdefault); // unsure of that } // User property constructor // requires property name, type of the property (must be a enum type) and enum default value CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFEnums *tenum) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = true; enuml = tenum; default_value = (CUDFPropertyValue *)NULL; } // User property constructor // requires property name, type of the property (must be a enum type), the list of allowed enum values and enum default value CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFEnums *tenum, char *tident) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = true; enuml = tenum; char *defval = get_enum(tenum, tident); if (defval == (char *)NULL) { fprintf(stderr, "CUDF error: property %s default value can not be %s.\n", tname, tident); exit(-1); } else default_value = new CUDFPropertyValue(this, defval); } // User property constructor // requires property name, type of the property (must be a vpkg type) and vpkg default value CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFVpkg *tdefault) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = false; default_value = new CUDFPropertyValue(this, tdefault); } // User property constructor // requires property name, type of the property (must be a vpkglist type) and vpkglist default value CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFVpkgList *tdefault) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = false; default_value = new CUDFPropertyValue(this, tdefault); } // User property constructor // requires property name, type of the property (must be a vpkgformula type) and vpkgformula default value CUDFProperty::CUDFProperty(char *tname, CUDFPropertyType ttype, CUDFVpkgFormula *tdefault) { int lgth = strlen(tname); if ((name = (char *)malloc(lgth+1)) == NULL) { fprintf(stderr, "error: cannot alloc name for property %s.\n", tname); exit(-1); } strcpy(name, tname); type_id = ttype; required = false; default_value = new CUDFPropertyValue(this, tdefault); } // User property value constructor // requires a pointer to the user property (must be an int subtype) and its int value CUDFPropertyValue::CUDFPropertyValue(CUDFProperty *the_property, int the_value) { property = the_property; intval = the_value; } // User property value constructor // requires a pointer to the user property (must be a string subtype) and its string value CUDFPropertyValue::CUDFPropertyValue(CUDFProperty *the_property, char *the_value) { char *the_nvalue = (char *)malloc(strlen(the_value)+1); property = the_property; strval = the_nvalue; strcpy(the_nvalue, the_value); } // User property value constructor // requires a pointer to the user property (must be a vpkg type) and its vpkg value CUDFPropertyValue::CUDFPropertyValue(CUDFProperty *the_property, CUDFVpkg *the_value) { property = the_property; vpkg = the_value; } // User property value constructor // requires a pointer to the user property (must be a vpkglist type) and its vpkglist value CUDFPropertyValue::CUDFPropertyValue(CUDFProperty *the_property, CUDFVpkgList *the_value) { property = the_property; vpkglist = the_value; } // User property value constructor // requires a pointer to the user property (must be a vpkgformula type) and its vpkgformula value CUDFPropertyValue::CUDFPropertyValue(CUDFProperty *the_property, CUDFVpkgFormula *the_value) { property = the_property; vpkgformula = the_value; } // Operators to compare two version // requires the two version to compare bool op_none_comp(CUDFVersion v1, CUDFVersion v2) { return true; } bool op_eq_comp(CUDFVersion v1, CUDFVersion v2) { return (v1 == v2); } bool op_neq_comp(CUDFVersion v1, CUDFVersion v2) { return (v1 != v2); } bool op_sup_comp(CUDFVersion v1, CUDFVersion v2) { return (v1 > v2); } bool op_supeq_comp(CUDFVersion v1, CUDFVersion v2) { return (v1 >= v2); } bool op_inf_comp(CUDFVersion v1, CUDFVersion v2) { return (v1 < v2); } bool op_infeq_comp(CUDFVersion v1, CUDFVersion v2) { return (v1 <= v2); } // Gives back a comparison operator according to its parameter value a_compptr get_comparator(CUDFPackageOp op) { switch (op) { case op_none: return op_none_comp; break; case op_eq: return op_eq_comp; break; case op_neq: return op_neq_comp; break; case op_sup: return op_sup_comp; break; case op_supeq: return op_supeq_comp; break; case op_inf: return op_inf_comp; break; case op_infeq: return op_infeq_comp; break; } return op_none_comp; } // Print out a vpkg // requires the file descriptor of the targetted file and a vpkg pointer void print_vpkg(FILE *output, CUDFVpkg *vpkg) { if (vpkg == vpkg_true) fprintf(output, "true!"); else if (vpkg == vpkg_false) fprintf(output, "false!"); else { fprintf(output, "%s", vpkg->virtual_package->name); switch (vpkg->op) { case op_none: break; case op_eq: fprintf(output, " = %llu", vpkg->version); break; case op_neq: fprintf(output, " != %llu", vpkg->version); break; case op_inf: fprintf(output, " < %llu", vpkg->version); break; case op_infeq: fprintf(output, " <= %llu", vpkg->version); break; case op_sup: fprintf(output, " > %llu", vpkg->version); break; case op_supeq: fprintf(output, " >= %llu", vpkg->version); break; } } } // Print out a vpkglist // requires the file descriptor of the targetted file and a vpkglist pointer void print_vpkglist(FILE *output, vector *vpkglist, bool is_or) { CUDFVpkgListIterator ipkg; if ((vpkglist != (CUDFVpkgList *)NULL) && ((*vpkglist).size() > 0)) { ipkg = vpkglist->begin(); print_vpkg(output, *ipkg); ipkg++; for (; ipkg != vpkglist->end(); ipkg++) { if (is_or) fprintf(output, " | "); else fprintf(output, ", "); print_vpkg(output, *ipkg); } } } // Print out a vpkgformula // requires the file descriptor of the targetted file and a vpkgformula pointer void print_vpkgformula(FILE *output, CUDFVpkgFormula *vpkgformula) { CUDFVpkgFormulaIterator ipkg; if (vpkgformula != (CUDFVpkgFormula *)NULL) { ipkg = vpkgformula->begin(); print_vpkglist(output, *ipkg, true); ipkg++; for (; ipkg != vpkgformula->end(); ipkg++) { fprintf(output, ", "); print_vpkglist(output, *ipkg, true); } } } // Print out a list of enums // requires the file descriptor of the targetted file and a pointer to the list of enums void print_enum(FILE *output, CUDFEnums *enuml) { CUDFEnumsIterator i = enuml->begin(); if (i != enuml->end()) { fprintf(output, "enum[%s", *i); i++; for ( ; i != enuml->end(); i++) fprintf(output, ", %s", *i); fprintf(output, "]"); } } // Print out a string // requires the file descriptor of the targetted file and a string pointer void print_string(FILE *output, char *str) { int lgth = strlen(str); fprintf(output, "\""); for (int i = 0; i < lgth; i++) if (str[i] == '"') fprintf(output, "\\\""); else fprintf(output, "%c", str[i]); fprintf(output, "\""); } // Print out a list of properties // requires the file descriptor of the targetted file and a pointer to the list of properties void print_properties(FILE *output, CUDFProperties *properties) { if (properties != (CUDFProperties *)NULL) { char sep = ' '; fprintf(output, "property:"); for (CUDFPropertiesIterator adecl = properties->begin(); adecl != properties->end(); adecl++) { fprintf(output, "%c %s ", sep, adecl->second->name); switch (adecl->second->type_id) { case pt_bool: if (adecl->second->required) fprintf(output, "bool"); else { if (adecl->second->default_value->intval == 0) fprintf(output, "bool = [false]"); else fprintf(output, "bool = [true]"); } break; case pt_int: if (adecl->second->required) fprintf(output, "int"); else fprintf(output, "int = [%d]", adecl->second->default_value->intval); break; case pt_nat: if (adecl->second->required) fprintf(output, "nat"); else fprintf(output, "nat = [%d]", adecl->second->default_value->intval); break; case pt_posint: if (adecl->second->required) fprintf(output, "posint"); else fprintf(output, "posint = [%d]", adecl->second->default_value->intval); break; case pt_string: if (adecl->second->required) fprintf(output, "string"); else { fprintf(output, "string = ["); print_string(output, adecl->second->default_value->strval); fprintf(output, "]"); } break; case pt_enum: print_enum(output, adecl->second->enuml); if (adecl->second->required) fprintf(output, " = [%s]", adecl->second->default_value->strval); break; case pt_vpkg: if (adecl->second->required) fprintf(output, "vpkg"); else { fprintf(output, "vpkg = ["); print_vpkg(output, adecl->second->default_value->vpkg); fprintf(output, "]"); } break; case pt_veqpkg: if (adecl->second->required) fprintf(output, "veqpkg"); else { fprintf(output, "veqpkg = ["); print_vpkg(output, adecl->second->default_value->vpkg); fprintf(output, "]"); } break; case pt_vpkglist: if (adecl->second->required) fprintf(output, "vpkglist"); else { fprintf(output, "vpkglist = ["); print_vpkglist(output, adecl->second->default_value->vpkglist, false); fprintf(output, "]"); } break; case pt_veqpkglist: if (adecl->second->required) fprintf(output, "veqpkglist"); else { fprintf(output, "veqpkglist = ["); print_vpkglist(output, adecl->second->default_value->vpkglist, false); fprintf(output, "]"); } break; case pt_vpkgformula: if (adecl->second->required) fprintf(output, "vpkgformula"); else { fprintf(output, "vpkgformula = ["); print_vpkgformula(output, adecl->second->default_value->vpkgformula); fprintf(output, "]"); } break; case pt_none: fprintf(output, "NONE!!"); break; } sep = ','; } } } // Print out a versioned package (according to its install boolean parameter value) // requires the file descriptor of the targetted file, a pointer to the versioned package, whether it should // be printed out as installed or uninstalled, whether it was installed or not void print_versioned_package_with_install(FILE *output, CUDFVersionedPackage *pkg, bool install, bool wasinstalled) { fprintf(output, "package: %s\n", pkg->name); fprintf(output, "version: %llu\n", pkg->version); if (pkg->depends != (CUDFVpkgFormula *)NULL) { fprintf(output, "depends: "); print_vpkgformula(output, pkg->depends); fprintf(output, "\n"); } if (pkg->provides != (CUDFVpkgList *)NULL) { fprintf(output, "provides: "); print_vpkglist(output, pkg->provides, false); fprintf(output, "\n"); } if (pkg->conflicts != (CUDFVpkgList *)NULL) { fprintf(output, "conflicts: "); print_vpkglist(output, pkg->conflicts, false); fprintf(output, "\n"); } if (install) fprintf(output, "installed: true\n"); if (wasinstalled) if (pkg->installed) fprintf(output, "was-installed: true\n"); //else fprintf(output, "was-installed: false\n"); switch(pkg->keep) { case keep_none: break; case keep_feature: fprintf(output, "keep: feature\n"); break; case keep_package: fprintf(output, "keep: package\n"); break; case keep_version: fprintf(output, "keep: version\n"); break; } for (CUDFPropertyValueListIterator ip = pkg->properties.begin(); ip != pkg->properties.end(); ip++) switch((*ip)->property->type_id) { case pt_bool: if ((*ip)->intval == 0) fprintf(output, "%s false\n", (*ip)->property->name); else fprintf(output, "%s true\n", (*ip)->property->name); break; case pt_int: case pt_nat: case pt_posint: fprintf(output, "%s %d\n", (*ip)->property->name, (*ip)->intval); break; case pt_enum: fprintf(output, "%s %s\n", (*ip)->property->name, (*ip)->strval); break; case pt_string: fprintf(output, "%s %s\n", (*ip)->property->name, (*ip)->strval); break; case pt_vpkg: case pt_veqpkg: fprintf(output, "%s ", (*ip)->property->name); print_vpkg(output, (*ip)->vpkg); fprintf(output, "\n"); break; case pt_vpkglist: case pt_veqpkglist: fprintf(output, "%s ", (*ip)->property->name); print_vpkglist(output, (*ip)->vpkglist, false); fprintf(output, "\n"); break; case pt_vpkgformula: fprintf(output, "%s ", (*ip)->property->name); print_vpkgformula(output, (*ip)->vpkgformula); fprintf(output, "\n"); break; case pt_none: fprintf(output, "%s ", (*ip)->property->name); fprintf(output, "NONE!!\n"); break; } fprintf(output, "\n"); } // Print out a versioned package // requires the file descriptor of the targetted file, a pointer to the versioned package and whether it was installed or not void print_versioned_package(FILE *output, CUDFVersionedPackage *pkg, bool wasinstalled) { print_versioned_package_with_install(output, pkg, pkg->installed, wasinstalled); } // Print out a versioned package as installed // requires the file descriptor of the targetted file, a pointer to the versioned package and whether it was installed or not void print_versioned_package_as_installed(FILE *output, CUDFVersionedPackage *pkg, bool wasinstalled) { print_versioned_package_with_install(output, pkg, true, wasinstalled); } // Print out a virtual package // requires the file descriptor of the targetted file and a pointer to the virtual package void print_virtual_package(FILE *output, CUDFVirtualPackage *vpkg) { bool out; char sep; fprintf(output, "virtual package: %s\n", vpkg->name); fprintf(output, "versions:"); sep = ' '; if (vpkg->all_versions.size() > 0) for (CUDFVersionedPackageSetIterator jpkg = vpkg->all_versions.begin(); jpkg != vpkg->all_versions.end(); jpkg++) { fprintf(output, "%c %s = %llu", sep, (*jpkg)->name, (*jpkg)->version); sep = ','; } else fprintf(output, " none"); fprintf(output, "\n"); fprintf(output, "providers (any version):"); sep = ' '; if (vpkg->providers.size() > 0) for (CUDFProviderListIterator jpkg = vpkg->providers.begin(); jpkg != vpkg->providers.end(); jpkg++) { fprintf(output, "%c %s = %llu", sep, (*jpkg)->name, (*jpkg)->version); sep = ','; } else fprintf(output, " none"); fprintf(output, "\n"); fprintf(output, "versioned providers:"); out = false; for (CUDFVersionedProviderListIterator jpkg = vpkg->versioned_providers.begin(); jpkg != vpkg->versioned_providers.end(); jpkg++) { out = true; fprintf(output, "\n\t%llu:", jpkg->first); sep = ' '; for (CUDFProviderListIterator kpkg = jpkg->second.begin(); kpkg != jpkg->second.end(); kpkg++) { fprintf(output, "%c %s = %llu", sep, (*kpkg)->name, (*kpkg)->version); sep = ','; } } if (! out) fprintf(output, " none"); fprintf(output, "\n"); fprintf(output, "highest installed provider version: %llu\n", vpkg->highest_installed_provider_version); if (vpkg->highest_installed != (CUDFVersionedPackage *)NULL) fprintf(output, "highest version installed: %s = %llu\n", vpkg->highest_installed->name, vpkg->highest_installed->version); else fprintf(output, "highest version installed: none\n"); fprintf(output, "\n"); } // Print out a CUDF problem // requires the file descriptor of the targetted file and a pointer to the CUDF problem void print_problem(FILE *output, CUDFproblem *pbs) { fprintf(output, "request:\n"); if (pbs != (CUDFproblem *)NULL) { if (pbs->install != (CUDFVpkgList *)NULL) { fprintf(output, "install: "); print_vpkglist(output, pbs->install, false); fprintf(output, "\n"); } if (pbs->remove != (CUDFVpkgList *)NULL) { fprintf(output, "remove: "); print_vpkglist(output, pbs->remove, false); fprintf(output, "\n"); } if (pbs->upgrade != (CUDFVpkgList *)NULL) { fprintf(output, "upgrade: "); print_vpkglist(output, pbs->upgrade, false); fprintf(output, "\n"); } } } mccs-1.1/libsrcs/cudf.y0000600017777601777760000006745711574427503014720 0ustar nobodynogroup /*******************************************************/ /* CUDF solver: cudf.y */ /* Syntactic analyser for CUDF */ /* (c) Claude Michel I3S (UNSA-CNRS) 2009,2010,2011 */ /*******************************************************/ /* Based on Bison syntactic analyser generator */ %{ #include #include #include #include extern int cudflineno; /* number of the current line */ extern int cudflex (void); /* lexical analyser */ /* Print out a CUDF problem error location */ void yyerror(const char *str) { fprintf(stderr,"cudf syntax error (line: %d): %s\n", cudflineno, str); } int package_line = 0; /* last line of a package declaration */ CUDFVersionedPackage *current_package = (CUDFVersionedPackage *)NULL; /* package under analysis */ int versioned_package_rank = 0; /* last rank of a versionned package */ CUDFproblem *current_problem = (CUDFproblem *)NULL; /* current problem */ CUDFVersionedPackageList all_packages; /* list of all versioned packages */ CUDFVirtualPackageList all_virtual_packages; /* list of all virtual packages */ CUDFVirtualPackageList version_installed_virtual_packages; /* list of all virtual packages with at least one version installed */ CUDFVirtualPackageList all_virtual_packages_with_version; /* list of all virtual packages with at least one */ CUDFVirtualPackageList uninstalled_virtual_packages_with_version; /* list of all virtual packages with at least one */ CUDFVersionedPackageList installed_packages; /* list of all installed versioned packages */ CUDFVersionedPackageList uninstalled_packages; /* list of all uninstalled versioned packages */ CUDFproblem *the_problem = (CUDFproblem *)NULL; /* the CUDF problem to solve */ CUDFVpkgFormula *current_vpkgformula = (CUDFVpkgFormula *)NULL; /* vpkgformula under analysis */ CUDFVpkgList *current_vpkglist = (CUDFVpkgList *)NULL; /* vpkglist under analysis */ CUDFVpkg *current_vpkg = (CUDFVpkg *)NULL; /* vpkg under analysis */ CUDFPropertyType current_pt_type = pt_vpkgformula; /* type of the user property under analysis */ CUDFVpkg *build_vpkg(const char *vpkgname, CUDFPackageOp op, CUDFVersion version) { /* internal construction of a vpkg */ return new CUDFVpkg(get_virtual_package(vpkgname), op, version); } void build_vpkgformula() { /* internal construction of a vpkg formula */ if (current_vpkgformula == (CUDFVpkgFormula *)NULL) { current_vpkgformula = new CUDFVpkgFormula; } current_vpkgformula->push_back(current_vpkglist); current_vpkglist = (CUDFVpkgList *)NULL; } void build_vpkglist(CUDFVpkg *avpkg) { /* internal construction of a vpkglist */ if (current_vpkglist == (CUDFVpkgList *)NULL) { current_vpkglist = new CUDFVpkgList; } current_vpkglist->push_back(avpkg); } // internal construction of a veqpkglist ... only used by provides void build_veqpkglist(CUDFVpkg *avpkg) { CUDFVirtualPackage *vpackage = avpkg->virtual_package; CUDFVersion version = avpkg->version; if (current_vpkglist == (CUDFVpkgList *)NULL) { current_vpkglist = new CUDFVpkgList; } current_vpkglist->push_back(avpkg); switch(avpkg->op) { case op_none: vpackage->providers.push_back(current_package); break; case op_eq: if ((current_package->installed) && (version > vpackage->highest_installed_provider_version)) vpackage->highest_installed_provider_version = version; { CUDFVersionedProviderListIterator ivpkgl = vpackage->versioned_providers.find(version); if (ivpkgl == vpackage->versioned_providers.end()) vpackage->versioned_providers.insert(CUDFVersionedProviderList::value_type(version, CUDFProviderList(1, current_package))); else ivpkgl->second.push_back(current_package); } break; default: fprintf(stderr, "CUDF error (line %d): veqpkglist is restricted to = operator.\n", cudflineno); exit(-1); break; } } // get package version CUDFVersion getversion(const char *svalue) { CUDFVersion version = 0; if (svalue[0] != '-') { sscanf(svalue, "%llu", &version); if (version >= 0) return version; // WARNING : should be restricted to > 0 } fprintf(stderr, "Package version must be a .\n"); exit(-1); } // list of the user required properties vector required_properties; // post process a versioned package declaration void package_postprocess() { if (current_package != (CUDFVersionedPackage *)NULL) { CUDFVirtualPackage *vpackage = current_package->virtual_package; if (vpackage->all_versions.find(current_package) == vpackage->all_versions.end()) vpackage->all_versions.insert(current_package); else { fprintf(stderr, "CUDF error (line %d): (package, version) must be unique (see package %s).\n", package_line, current_package->name); exit(-1); } if (current_package->installed) { installed_packages.push_back(current_package); if (vpackage->highest_installed == (CUDFVersionedPackage *)NULL) vpackage->highest_installed = current_package; else if (current_package->version > vpackage->highest_installed->version) vpackage->highest_installed = current_package; if (current_package->provides != (CUDFVpkgList *)NULL) for (CUDFVpkgListIterator iop = current_package->provides->begin(); iop != current_package->provides->end(); iop++) if ((*iop)->op == op_eq) { if ((*iop)->virtual_package->highest_installed_provider_version < (*iop)->version) (*iop)->virtual_package->highest_installed_provider_version = (*iop)->version; } } else uninstalled_packages.push_back(current_package); if (current_package->version > vpackage->highest_version) vpackage->highest_version = current_package->version; for (vector::iterator prop = required_properties.begin(); prop != required_properties.end(); prop++) { bool hasprop = false; for (CUDFPropertyValueListIterator pval = current_package->properties.begin(); pval != current_package->properties.end(); pval++) if ((*pval)->property == *prop) { hasprop = true; break; } if (! hasprop) { fprintf(stderr, "CUDF error (line %d): package (%s, %llu) lacks property %s.\n", package_line, current_package->name, current_package->version, (*prop)->name); exit(-1); } } } } //#define YYMAXDEPTH 800000 //#define YYMAXDEPTH 80 // list of enum under analysis CUDFEnums *enuml; // build an enum void build_enum(char *estr) { char *the_enum; if ((the_enum = (char *)malloc(strlen(estr)+1)) == (char *)NULL) { fprintf(stderr, "CUDF error: can not alloc memory for enum %s.\n", estr); exit(-1); } strcpy(the_enum, estr); enuml->push_back(the_enum); } // get an enum from its name in an enum list char *get_enum(CUDFEnums *e, char *estr) { for (CUDFEnumsIterator ei = e->begin(); ei != e->end(); ei++) if (strcmp((*ei), estr) == 0) return (*ei); return (char *)NULL; } // get a property ident type from a user property name extern int pidenttype(char *pname); int pidenttype(char *pname) { CUDFPropertiesIterator p = properties.find(string(pname)); if (p == properties.end()) return pt_none; return p->second->type_id; } // get a CUDF type from a type name CUDFPropertyType gettype(char *ident) { /* enum CUDFPropertyType { pt_bool, pt_int, pt_nat, pt_posint, pt_enum, pt_string, */ int length = strlen(ident); if (length >= 1) switch (ident[0]) { case 'b': if ((length == 4) && (ident[1] == 'o') && (ident[2] == 'o') && (ident[3] == 'l') && (ident[4] == '\0')) return pt_bool; case 'e': if ((length == 4) && (ident[1] == 'n') && (ident[2] == 'u') && (ident[3] == 'm') && (ident[4] == '\0')) return pt_enum; case 'i': if ((length == 3) && (ident[1] == 'n') && (ident[2] == 't') && (ident[3] == '\0')) return pt_int; case 'n': if ((length == 3) && (ident[1] == 'a') && (ident[2] == 't') && (ident[3] == '\0')) return pt_nat; case 'p': if ((length == 6) && (ident[1] == 'o') && (ident[2] == 's') && (ident[3] == 'i') && (ident[4] == 'n') && (ident[5] == 't') && (ident[6] == '\0')) return pt_posint; case 's': if ((length == 6) && (ident[1] == 't') && (ident[2] == 'r') && (ident[3] == 'i') && (ident[4] == 'n') && (ident[5] == 'g') && (ident[6] == '\0')) return pt_string; case 'v': if (length >= 4) { if (ident[1] == 'p') { if ((ident[2] == 'k') && (ident[3] == 'g')) switch (ident[4]) { case '\0': return pt_vpkg; case 'l': if ((length == 8) && (ident[5] == 'i') && (ident[6] == 's') && (ident[7] == 't') && (ident[8] == '\0')) return pt_vpkglist; case 'f': if ((length == 11) && (ident[5] == 'o') && (ident[6] == 'r') && (ident[7] == 'm') && (ident[8] == 'u') && (ident[9] == 'l') && (ident[10] == 'a') && (ident[11] == '\0')) return pt_vpkgformula; } } else if (ident[1] == 'e') { if ((ident[2] == 'q') && (ident[3] == 'p') && (length >= 6) && (ident[4] == 'k') && (ident[5] == 'g')) switch (ident[6]) { case '\0': return pt_veqpkg; case 'l': if ((length == 10) && (ident[7] == 'i') && (ident[8] == 's') && (ident[9] == 't') && (ident[10] == '\0')) return pt_veqpkglist; } } } } fprintf(stderr, "CUDF error (line %d): property type awaited \"%s\" (%d).\n", cudflineno, ident, length); exit(-1); } extern char astring[]; %} %union { // CUDFVersion value; CUDFVpkg *avpkg; char str[256]; } %token PREAMBLE PROPERTYDEF %token PACKAGE VERSION DEPENDS CONFLICTS PROVIDES INSTALLED %token KEEP KEEPVERSION KEEPPACKAGE KEEPFEATURE KEEPNONE %token EQ NEQ SUP SUPEQ INF INFEQ %token TRUE FALSE VTRUE VFALSE %token PROBLEM INSTALL WASINSTALLED REMOVE UPGRADE %token PIDENT_BOOL PIDENT_INT PIDENT_NAT PIDENT_POSINT PIDENT_ENUM PIDENT_STRING %token PIDENT_VPKG PIDENT_VEQPKG PIDENT_VPKGLIST PIDENT_VEQPKGLIST PIDENT_VPKGFORMULA %token INTEGER IDENT PIDENT %token STRING %type vpkg veqpkg %% cudf: preambles | preambles package_declarations | problem_declaration | preambles package_declarations problem_declaration ; preambles: /* empty */ | PREAMBLE property_definitions property_definitions: typedecls | PROPERTYDEF typedecls ; typedecls: typedecl | typedecls ',' typedecl typedecl: PIDENT IDENT { CUDFProperty *prop = new CUDFProperty($1, gettype($2)); properties[string($1)] = prop; required_properties.push_back(prop); } typedecl: PIDENT IDENT EQ '[' TRUE ']' { if (gettype($2) == pt_bool) properties[string($1)] = new CUDFProperty($1, pt_bool, 1); else { fprintf(stderr, "CUDF error (line %d): property value requires a boolean typed property (%s).\n", cudflineno, $2); exit(-1); } } typedecl: PIDENT IDENT EQ '[' FALSE ']' { if (gettype($2) == pt_bool) properties[string($1)] = new CUDFProperty($1, pt_bool, 0); else { fprintf(stderr, "CUDF error (line %d): property value requires a boolean typed property (%s).\n", cudflineno, $2); exit(-1); } } typedecl: PIDENT IDENT EQ '[' INTEGER ']' { CUDFPropertyType pt = gettype($2); if (pt == pt_int) properties[string($1)] = new CUDFProperty($1, pt_int, atoi($5)); else if (pt == pt_posint) properties[string($1)] = new CUDFProperty($1, pt_posint, atoi($5)); else if (pt == pt_nat) properties[string($1)] = new CUDFProperty($1, pt_nat, atoi($5)); else { fprintf(stderr, "CUDF error (line %d): property value requires an integer typed property (%s).\n", cudflineno, $2); exit(-1); } } typedecl: PIDENT IDENT EQ '[' STRING ']' { if (gettype($2) == pt_string) properties[string($1)] = new CUDFProperty($1, pt_string, astring); else { fprintf(stderr, "CUDF error (line %d): property value requires a string typed property (%s).\n", cudflineno, $2); exit(-1); } } typedecl: PIDENT IDENT '[' enums ']' { CUDFProperty *prop = new CUDFProperty($1, pt_enum, enuml); if (gettype($2) != pt_enum) { fprintf(stderr, "CUDF error (line %d): this must be an enum type (%s).\n", cudflineno, $2); exit(-1); } properties[string($1)] = prop; required_properties.push_back(prop); } typedecl: PIDENT IDENT '[' enums ']' EQ '[' IDENT ']' { if (gettype($2) == pt_enum) properties[string($1)] = new CUDFProperty($1, pt_enum, enuml, $8); else { fprintf(stderr, "CUDF error (line %d): property value requires an enum type (%s).\n", cudflineno, $2); exit(-1); } } /* typedecl: PIDENT IDENT EQ '[' vpkg ']' {} typedecl: PIDENT IDENT EQ '[' veqpkg ']' {} typedecl: PIDENT IDENT EQ '[' vpkglist ']' {} typedecl: PIDENT IDENT EQ '[' veqpkglist ']' {} */ typedecl: PIDENT IDENT EQ '[' ']' { // No type checking is done here ... switch(gettype($2)) { case pt_vpkglist: properties[string($1)] = new CUDFProperty($1, pt_vpkglist, new CUDFVpkgList); break; case pt_veqpkglist: properties[string($1)] = new CUDFProperty($1, pt_veqpkglist, new CUDFVpkgList); break; default: fprintf(stderr, "CUDF error (line %d): property value requires a default value (%s).\n", cudflineno, $2); exit(-1); } } typedecl: PIDENT IDENT EQ '[' vpkgformula ']' { // No type checking is done here ... CUDFPropertyType pt = gettype($2); if (pt == pt_vpkg) { properties[string($1)] = new CUDFProperty($1, pt_vpkg, current_vpkgformula[0][0]); } else if (pt == pt_veqpkg) properties[string($1)] = new CUDFProperty($1, pt_veqpkg, current_vpkgformula[0][0]); else if (pt == pt_vpkglist) properties[string($1)] = new CUDFProperty($1, pt_vpkglist, current_vpkgformula->front()); else if (pt == pt_veqpkglist) properties[string($1)] = new CUDFProperty($1, pt_veqpkglist, current_vpkgformula->front()); else if (pt == pt_vpkgformula) properties[string($1)] = new CUDFProperty($1, pt_vpkgformula, current_vpkgformula); else { fprintf(stderr, "CUDF error (line %d): property value requires a (sub)vpkgformula typed property (%s).\n", cudflineno, $2); exit(-1); } current_vpkgformula = (CUDFVpkgFormula *)NULL; } enums: IDENT { enuml = new CUDFEnums; build_enum($1); } | enums ',' IDENT { build_enum($3); } /* package_declarations: package_declaration ; package_declarations: package_declarations package_declaration ; */ package_declarations: package_declaration | package_declarations package_declaration /* Problem here : pushing this state for ever */ ; package_declaration: package_version package_options ; package_version: PACKAGE IDENT { package_postprocess(); package_line = cudflineno; CUDFVirtualPackage *virtual_package = get_virtual_package($2); current_package = new CUDFVersionedPackage($2, versioned_package_rank++); all_packages.push_back(current_package); current_package->virtual_package = virtual_package; } package_options: /* empty */ | package_options package_option ; package_option: version | depends | conflicts | provides | installed | wasinstalled | keep | property ; problem_declaration: problem | problem problem_actions ; problem_actions: problem_action | problem_actions problem_action ; problem_action: install | remove | upgrade ; version: VERSION INTEGER { current_package->set_version(getversion($2)); } depends: DEPENDS | DEPENDS vpkgformula { if (current_package->depends == (CUDFVpkgFormula *)NULL) { current_package->depends = current_vpkgformula; current_vpkgformula = (CUDFVpkgFormula *)NULL; } else { fprintf(stderr, "CUDF error (line %d): depends declared twice for package %s.\n", cudflineno, current_package->name); exit(-1); } } conflicts: CONFLICTS | CONFLICTS vpkglist { if (current_package->conflicts == (CUDFVpkgList *)NULL) { current_package->conflicts = current_vpkglist; current_vpkglist = (CUDFVpkgList *)NULL; } else { fprintf(stderr, "CUDF error (line %d): conflicts declared twice for package %s.\n", cudflineno, current_package->name); exit(-1); } } provides: PROVIDES | PROVIDES veqpkglist { if (current_package->provides == (CUDFVpkgList *)NULL) { current_package->provides = current_vpkglist; current_vpkglist = (CUDFVpkgList *)NULL; } else { fprintf(stderr, "CUDF error (line %d): provides declared twice for package %s.\n", cudflineno, current_package->name); exit(-1); } } installed: INSTALLED TRUE { current_package->installed = true; } installed: INSTALLED FALSE { current_package->installed = false; } wasinstalled: WASINSTALLED TRUE { current_package->wasinstalled = true; } wasinstalled: WASINSTALLED FALSE { current_package->wasinstalled = false; } keep: KEEP keepvalue ; /* properties: property | properties property ; */ property: PIDENT_BOOL TRUE { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_bool: current_package->properties.push_back(new CUDFPropertyValue(p->second, 1)); break; default: fprintf(stderr, "CUDF error (line %d): bad value (true) for property %s.\n", cudflineno, $1); exit(-1); } } property: PIDENT_BOOL FALSE { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_bool: current_package->properties.push_back(new CUDFPropertyValue(p->second, 0)); break; default: fprintf(stderr, "CUDF error (line %d): bad value (false) for property %s.\n", cudflineno, $1); exit(-1); } } property: PIDENT_INT INTEGER { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); print_properties(stdout, &properties); exit(-1); } int value = atoi($2); switch (p->second->type_id) { case pt_int: current_package->properties.push_back(new CUDFPropertyValue(p->second, value)); break; default: fprintf(stderr, "CUDF error (line %d): bad value (%d) for property %s.\n", cudflineno, value, $1); exit(-1); } } property: PIDENT_NAT INTEGER { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); print_properties(stdout, &properties); exit(-1); } int value = atoi($2); switch (p->second->type_id) { case pt_nat: if (value < 0) { fprintf(stderr, "CUDF error (line %d): property %s (nat) requires values >= 0: %d.\n", cudflineno, $1, value); exit(-1); } current_package->properties.push_back(new CUDFPropertyValue(p->second, value)); break; default: fprintf(stderr, "CUDF error (line %d): bad value (%d) for property %s.\n", cudflineno, value, $1); exit(-1); } } property: PIDENT_POSINT INTEGER { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); print_properties(stdout, &properties); exit(-1); } int value = atoi($2); switch (p->second->type_id) { case pt_posint: if (value <= 0) { fprintf(stderr, "CUDF error (line %d): property %s (posint) requires values > 0: %d.\n", cudflineno, $1, value); exit(-1); } current_package->properties.push_back(new CUDFPropertyValue(p->second, value)); break; default: fprintf(stderr, "CUDF error (line %d): bad value (%d) for property %s.\n", cudflineno, value, $1); exit(-1); } } property: PIDENT_ENUM IDENT { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } char *value; switch (p->second->type_id) { case pt_enum: value = get_enum(p->second->enuml, $2); if (value == (char *)NULL) { fprintf(stderr, "CUDF error (line %d): property %s (enum) can not take value %s.\n", cudflineno, $1, $2); exit(-1); } current_package->properties.push_back(new CUDFPropertyValue(p->second, value)); break; default: fprintf(stderr, "CUDF error (line %d): bad value (%s) for property %s.\n", cudflineno, $2, $1); exit(-1); } } property: PIDENT_STRING STRING { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_string: current_package->properties.push_back(new CUDFPropertyValue(p->second, astring)); break; default: fprintf(stderr, "CUDF error (line %d): bad value (%s) for property %s.\n", cudflineno, astring, $1); exit(-1); } } property: PIDENT_VPKG vpkg { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_vpkg: current_package->properties.push_back(new CUDFPropertyValue(p->second, $1)); break; default: fprintf(stderr, "CUDF error (line %d): bad value for property %s.\n", cudflineno, $1); exit(-1); } } property: PIDENT_VEQPKG veqpkg { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_veqpkg: current_package->properties.push_back(new CUDFPropertyValue(p->second, $1)); break; default: fprintf(stderr, "CUDF error (line %d): bad value for property %s.\n", cudflineno, $1); exit(-1); } } property: PIDENT_VPKGLIST | PIDENT_VPKGLIST vpkglist { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_vpkglist: current_package->properties.push_back(new CUDFPropertyValue(p->second, current_vpkglist)); current_vpkglist = (CUDFVpkgList *)NULL; break; default: fprintf(stderr, "CUDF error (line %d): bad value for property %s.\n", cudflineno, $1); exit(-1); } } property: PIDENT_VEQPKGLIST | PIDENT_VEQPKGLIST veqpkglist { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_veqpkglist: current_package->properties.push_back(new CUDFPropertyValue(p->second, current_vpkglist)); current_vpkglist = (CUDFVpkgList *)NULL; break; default: fprintf(stderr, "CUDF error (line %d): bad value for property %s.\n", cudflineno, $1); exit(-1); } } property: PIDENT_VPKGFORMULA vpkgformula { CUDFPropertiesIterator p = properties.find(string($1)); if (p == properties.end()) { fprintf(stderr, "CUDF error (line %d): property %s is not defined.\n", cudflineno, $1); exit(-1); } switch (p->second->type_id) { case pt_vpkgformula: current_package->properties.push_back(new CUDFPropertyValue(p->second, current_vpkgformula)); current_vpkgformula = (CUDFVpkgFormula *)NULL; break; default: fprintf(stderr, "CUDF error (line %d): bad value for property %s.\n", cudflineno, $1); exit(-1); } } problem: PROBLEM { package_postprocess(); if (the_problem == (CUDFproblem *)NULL) the_problem = current_problem = new CUDFproblem(); } install: INSTALL | INSTALL vpkglist { if (current_problem->install == (CUDFVpkgList *)NULL) { current_problem->install = current_vpkglist; current_vpkglist = (CUDFVpkgList *)NULL; } else { fprintf(stderr, "CUDF error (line %d): install declared twice.\n", cudflineno); exit(-1); } } remove: REMOVE | REMOVE vpkglist { if (current_problem->remove == (CUDFVpkgList *)NULL) { current_problem->remove = current_vpkglist; current_vpkglist = (CUDFVpkgList *)NULL; } else { fprintf(stderr, "CUDF error (line %d): remove declared twice.\n", cudflineno); exit(-1); } } upgrade: UPGRADE | UPGRADE vpkglist { if (current_problem->upgrade == (CUDFVpkgList *)NULL) { current_problem->upgrade = current_vpkglist; current_vpkglist = (CUDFVpkgList *)NULL; } else { fprintf(stderr, "CUDF error (line %d): upgrade declared twice.\n", cudflineno); exit(-1); } } keepvalue: KEEPVERSION { if (current_package->keep == keep_none) { current_package->keep = keep_version; } else { fprintf(stderr, "CUDF error (line %d): keep declared twice for package %s.\n", cudflineno, current_package->name); exit(-1); } } keepvalue: KEEPPACKAGE { if (current_package->keep == keep_none) { current_package->keep = keep_package; } else { fprintf(stderr, "CUDF error (line %d): keep declared twice for package %s.\n", cudflineno, current_package->name); exit(-1); } } keepvalue: KEEPFEATURE { if (current_package->keep == keep_none) { current_package->keep = keep_version; } else { fprintf(stderr, "CUDF error (line %d): keep declared twice for package %s.\n", cudflineno, current_package->name); exit(-1); } } keepvalue: KEEPNONE { current_package->keep = keep_none; } vpkgformula: VTRUE { build_vpkglist(vpkg_true); build_vpkgformula(); } vpkgformula: VFALSE { build_vpkglist(vpkg_false); build_vpkgformula(); } vpkgformula: avpkgformula avpkgformula: vpkgor { build_vpkgformula(); } avpkgformula: avpkgformula ',' vpkgor { build_vpkgformula(); } vpkgor: vpkg { build_vpkglist($1); } vpkgor: vpkgor '|' vpkg { build_vpkglist($3); } veqpkg: IDENT { current_vpkg = $$ = build_vpkg($1, op_none, 0); } veqpkg: IDENT EQ INTEGER { current_vpkg = $$ = build_vpkg($1, op_eq, getversion($3)); } vpkg: veqpkg { $$ = $1; } vpkg: IDENT NEQ INTEGER { current_vpkg = $$ = build_vpkg($1, op_neq, getversion($3)); } vpkg: IDENT SUP INTEGER { current_vpkg = $$ = build_vpkg($1, op_sup, getversion($3)); } vpkg: IDENT SUPEQ INTEGER { current_vpkg = $$ = build_vpkg($1, op_supeq, getversion($3)); } vpkg: IDENT INF INTEGER { current_vpkg = $$ = build_vpkg($1, op_inf, getversion($3)); } vpkg: IDENT INFEQ INTEGER { current_vpkg = $$ = build_vpkg($1, op_infeq, getversion($3));} vpkglist: vpkg { build_vpkglist($1); } vpkglist: vpkglist ',' vpkg { build_vpkglist($3); } veqpkglist: veqpkg { build_veqpkglist($1); } veqpkglist: veqpkglist ',' veqpkg { build_veqpkglist($3); } %% extern FILE *cudfin; // main parser function int parse_cudf(FILE *input_file) { int retval; // cudfdebug = 1; cudfin = input_file; retval = cudfparse(); if (the_problem == (CUDFproblem *)NULL) the_problem = current_problem = new CUDFproblem(); the_problem->properties = &properties; the_problem->all_packages = &all_packages; the_problem->installed_packages = &installed_packages; the_problem->uninstalled_packages = &uninstalled_packages; the_problem->all_virtual_packages = &all_virtual_packages; return retval; } mccs-1.1/makefile0000600017777601777760000002257311577461164013636 0ustar nobodynogroup # make for all systems # make USEGLPK=1 USELPSOLVE=1 USECPLEX=1 USEGUROBI=1 # WARNING: You should not modify this makefile. See make.local to define your own settings. #---------------------------------------------------------------------------------- include make.local #---------------------------------------------------------------------------------- OBJS= $(OBJDIR)/cudf.o \ $(OBJDIR)/constraint_generation.o \ $(OBJDIR)/lp_solver.o $(OBJDIR)/pblib_solver.o \ $(OBJDIR)/removed_criteria.o $(OBJDIR)/changed_criteria.o $(OBJDIR)/new_criteria.o $(OBJDIR)/notuptodate_criteria.o $(OBJDIR)/nunsat_criteria.o \ $(OBJDIR)/count_criteria.o $(OBJDIR)/unaligned_criteria.o \ $(OBJDIR)/lexicographic_combiner.o $(OBJDIR)/lexagregate_combiner.o $(OBJDIR)/agregate_combiner.o $(OBJDIR)/lexsemiagregate_combiner.o \ $(OBJDIR)/leximin_combiner.o $(OBJDIR)/leximax_combiner.o $(OBJDIR)/lexleximin_combiner.o $(OBJDIR)/lexleximax_combiner.o \ $(OBJDIR)/cudf_reductions.o CCC+= ifeq ($(USEGLPK),1) OBJS += $(OBJDIR)/glpk_solver.o CCC += -DUSEGLPK else GLPKLD = endif ifeq ($(USELPSOLVE),1) OBJS += $(OBJDIR)/lpsolve_solver.o CCC += -DUSELPSOLVE else LPSOLVELD = endif ifeq ($(USECPLEX),1) OBJS += $(OBJDIR)/cplex_solver.o CCC += -DUSECPLEX else CPXLD = endif ifeq ($(USEGUROBI),1) OBJS += $(OBJDIR)/gurobi_solver.o CCC += -DUSEGUROBI else GUROBILD = endif # to make mccs solver mccs: $(OBJS) libccudf.a $(CCC) -o mccs $(OBJS) -lfl -L. -lccudf \ $(CPXLD) \ $(GUROBILD) \ $(LPSOLVELD) \ $(GLPKLD) # to make a light version of mccs solver which does not include libccudf mccs-light: $(OBJS) libccudf.so $(CCC) -o mccs $(OBJS) -lfl -L. -lccudf -Wl,-rpath,$(PWD) \ $(CPXLD) \ $(GUROBILD) \ $(LPSOLVELD) \ $(GLPKLD) # to make a static version of mccs solver (cannot be done with Gurobi: no static library) mccs-static: $(OBJS) libccudf.a $(CCC) -o mccs -static $(OBJS) -lfl -L. -lccudf \ $(CPXLD) \ $(LPSOLVELD) \ $(GLPKLD) \ -ldl #---------------------------------------------------------------------------------- $(OBJDIR)/cudf.o: $(SRCDIR)/cudf.c $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/cudf.c -o $(OBJDIR)/cudf.o $(OBJDIR)/constraint_generation.o: $(SRCDIR)/constraint_generation.c $(SRCDIR)/constraint_generation.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/constraint_generation.c -o $(OBJDIR)/constraint_generation.o $(OBJDIR)/pblib_solver.o: $(SRCDIR)/pblib_solver.c $(SRCDIR)/pblib_solver.h \ $(SRCDIR)/abstract_solver.h $(SRCDIR)/scoeff_solver.h $(SRCDIR)/cudf_types.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/pblib_solver.c -o $(OBJDIR)/pblib_solver.o $(OBJDIR)/lp_solver.o: $(SRCDIR)/lp_solver.c $(SRCDIR)/lp_solver.h \ $(SRCDIR)/abstract_solver.h $(SRCDIR)/scoeff_solver.h $(SRCDIR)/cudf_types.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/lp_solver.c -o $(OBJDIR)/lp_solver.o $(OBJDIR)/cplex_solver.o: $(SRCDIR)/cplex_solver.c $(SRCDIR)/cplex_solver.h \ $(SRCDIR)/abstract_solver.h $(SRCDIR)/scoeff_solver.h $(SRCDIR)/cudf_types.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) -I$(CPXINC) $(SRCDIR)/cplex_solver.c -o $(OBJDIR)/cplex_solver.o $(OBJDIR)/gurobi_solver.o: $(SRCDIR)/gurobi_solver.c $(SRCDIR)/gurobi_solver.h \ $(SRCDIR)/abstract_solver.h $(SRCDIR)/scoeff_solver.h $(SRCDIR)/cudf_types.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) -I$(GUROBIINC) $(SRCDIR)/gurobi_solver.c -o $(OBJDIR)/gurobi_solver.o $(OBJDIR)/lpsolve_solver.o: $(SRCDIR)/lpsolve_solver.c $(SRCDIR)/lpsolve_solver.h \ $(SRCDIR)/abstract_solver.h $(SRCDIR)/scoeff_solver.h $(SRCDIR)/cudf_types.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) -I$(LPSOLVEINC) $(SRCDIR)/lpsolve_solver.c -o $(OBJDIR)/lpsolve_solver.o $(OBJDIR)/glpk_solver.o: $(SRCDIR)/glpk_solver.c $(SRCDIR)/glpk_solver.h \ $(SRCDIR)/abstract_solver.h $(SRCDIR)/scoeff_solver.h $(SRCDIR)/cudf_types.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) -I$(GLPKINC) $(SRCDIR)/glpk_solver.c -o $(OBJDIR)/glpk_solver.o $(OBJDIR)/removed_criteria.o: $(SRCDIR)/removed_criteria.c $(SRCDIR)/removed_criteria.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/removed_criteria.c -o $(OBJDIR)/removed_criteria.o $(OBJDIR)/changed_criteria.o: $(SRCDIR)/changed_criteria.c $(SRCDIR)/changed_criteria.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/changed_criteria.c -o $(OBJDIR)/changed_criteria.o $(OBJDIR)/new_criteria.o: $(SRCDIR)/new_criteria.c $(SRCDIR)/new_criteria.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/new_criteria.c -o $(OBJDIR)/new_criteria.o $(OBJDIR)/notuptodate_criteria.o: $(SRCDIR)/notuptodate_criteria.c $(SRCDIR)/notuptodate_criteria.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/notuptodate_criteria.c -o $(OBJDIR)/notuptodate_criteria.o $(OBJDIR)/nunsat_criteria.o: $(SRCDIR)/nunsat_criteria.c $(SRCDIR)/nunsat_criteria.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/nunsat_criteria.c -o $(OBJDIR)/nunsat_criteria.o $(OBJDIR)/count_criteria.o: $(SRCDIR)/count_criteria.c $(SRCDIR)/count_criteria.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/count_criteria.c -o $(OBJDIR)/count_criteria.o $(OBJDIR)/unaligned_criteria.o: $(SRCDIR)/unaligned_criteria.c $(SRCDIR)/unaligned_criteria.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/unaligned_criteria.c -o $(OBJDIR)/unaligned_criteria.o $(OBJDIR)/lexicographic_combiner.o: $(SRCDIR)/lexicographic_combiner.c $(SRCDIR)/lexicographic_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/lexicographic_combiner.c -o $(OBJDIR)/lexicographic_combiner.o $(OBJDIR)/lexagregate_combiner.o: $(SRCDIR)/lexagregate_combiner.c $(SRCDIR)/lexagregate_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/lexagregate_combiner.c -o $(OBJDIR)/lexagregate_combiner.o $(OBJDIR)/agregate_combiner.o: $(SRCDIR)/agregate_combiner.c $(SRCDIR)/agregate_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCDIR)/abstract_criteria.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/agregate_combiner.c -o $(OBJDIR)/agregate_combiner.o $(OBJDIR)/lexsemiagregate_combiner.o: $(SRCDIR)/lexsemiagregate_combiner.c $(SRCDIR)/lexsemiagregate_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/lexsemiagregate_combiner.c -o $(OBJDIR)/lexsemiagregate_combiner.o $(OBJDIR)/leximin_combiner.o: $(SRCDIR)/leximin_combiner.c $(SRCDIR)/leximin_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/leximin_combiner.c -o $(OBJDIR)/leximin_combiner.o $(OBJDIR)/leximax_combiner.o: $(SRCDIR)/leximax_combiner.c $(SRCDIR)/leximax_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/leximax_combiner.c -o $(OBJDIR)/leximax_combiner.o $(OBJDIR)/lexleximin_combiner.o: $(SRCDIR)/lexleximin_combiner.c $(SRCDIR)/lexleximin_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/lexleximin_combiner.c -o $(OBJDIR)/lexleximin_combiner.o $(OBJDIR)/lexleximax_combiner.o: $(SRCDIR)/lexleximax_combiner.c $(SRCDIR)/lexleximax_combiner.h $(SRCDIR)/abstract_combiner.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/lexleximax_combiner.c -o $(OBJDIR)/lexleximax_combiner.o $(OBJDIR)/cudf_reductions.o: $(SRCDIR)/cudf_reductions.c $(SRCDIR)/cudf_reductions.h $(SRCLIB)/cudf.h $(CCC) -c $(INC) $(SRCDIR)/cudf_reductions.c -o $(OBJDIR)/cudf_reductions.o #---------------------------------------------------------------------------------- libccudf.a: $(OBJDIR)/cudf.tab.o $(OBJDIR)/cudf.l.o $(OBJDIR)/cudf_hash_table.o $(OBJDIR)/cudf_tools.o ar rcs libccudf.a $(OBJDIR)/cudf.tab.o $(OBJDIR)/cudf.l.o $(OBJDIR)/cudf_hash_table.o $(OBJDIR)/cudf_tools.o libccudf.so: $(OBJDIR)/cudf.tab.o $(OBJDIR)/cudf.l.o $(OBJDIR)/cudf_hash_table.o $(OBJDIR)/cudf_tools.o $(CCC) -shared -W1,-soname,libccudf.so -o libccudf.so \ $(OBJDIR)/cudf.tab.o $(OBJDIR)/cudf.l.o $(OBJDIR)/cudf_hash_table.o $(OBJDIR)/cudf_tools.o $(OBJDIR)/cudf_hash_table.o: $(SRCLIB)/cudf_hash_table.c $(SRCLIB)/cudf_hash_table.h $(CCC) -c $(INC) -fPIC $(SRCLIB)/cudf_hash_table.c -o $(OBJDIR)/cudf_hash_table.o $(OBJDIR)/cudf_tools.o: $(SRCLIB)/cudf_tools.c $(SRCLIB)/cudf.h $(CCC) -c $(INC) -fPIC $(SRCLIB)/cudf_tools.c -o $(OBJDIR)/cudf_tools.o $(OBJDIR)/cudf.l.o: $(OBJDIR)/cudf.l.c $(CCC) -c $(INC) -fPIC $(OBJDIR)/cudf.l.c -o $(OBJDIR)/cudf.l.o $(OBJDIR)/cudf.tab.o: $(OBJDIR)/cudf.tab.c $(SRCLIB)/cudf.h $(CCC) -c $(INC) -fPIC $(OBJDIR)/cudf.tab.c -o $(OBJDIR)/cudf.tab.o $(OBJDIR)/cudf.l.c: $(SRCLIB)/cudf.l $(OBJDIR)/cudf.tab.h # flex -f -8 --prefix=cudf --outfile=$(OBJDIR)/cudf.l.c $(SRCLIB)/cudf.l flex -f -8 --prefix=cudf --outfile=$(OBJDIR)/cudf.l.c -i $(SRCLIB)/cudf.l $(OBJDIR)/cudf.tab.c: $(SRCLIB)/cudf.y # bison --verbose --report=state --debug --name-prefix=cudf --file-prefix=$(OBJDIR)/cudf $(SRCLIB)/cudf.y bison -v --name-prefix=cudf --file-prefix=$(OBJDIR)/cudf $(SRCLIB)/cudf.y $(OBJDIR)/cudf.tab.h: $(SRCLIB)/cudf.y # bison --verbose --report=state --debug --name-prefix=cudf --defines --file-prefix=$(OBJDIR)/cudf $(SRCLIB)/cudf.y bison --name-prefix=cudf --defines --file-prefix=$(OBJDIR)/cudf $(SRCLIB)/cudf.y clean: rm -f *~ rm -f $(SRCLIB)/*~ rm -f $(SRCDIR)/*~ rm -f $(OBJDIR)/* rm -f mccs rm -f libccudf.a rm -f libccudf.so rm -f *.lp rm -f pblib.opb rm -f ctpblib.opb rm -f lppbs.out rm -f pbsolver.out rm -f lpsolver.out rm -f installed.txt removed.txt rm -f sol rm -f cplex.log clone0.log rm -f */*~ mccs-1.1/make.local0000600017777601777760000000511111616261533014044 0ustar nobodynogroup #====================================================== # GLPK settings (required) # see http://www.gnu.org/software/glpk/ #====================================================== # if you want to use cplex uncomment next line (or use USEGLPK=1 as make parameter) #USEGLPK=1 ifeq ($(USEGLPK),1) # Path to GLPK main dir GLPKDIR=$(PWD)/../glpk # Path to the GPLK include files GLPKINC=$(GLPKDIR)/include/ # GPLK library path and options GLPKLD=-L${GLPKDIR}/lib -lglpk -Wl,-rpath,${GLPKDIR}/lib endif #====================================================== # LPSOLVE settings (required) # see http://lpsolve.sourceforge.net/ #====================================================== # if you want to use cplex uncomment next line (or use USELPSOLVE=1 as make parameter) #USELPSOLVE=1 ifeq ($(USELPSOLVE),1) # Path to the LPSOLVE main dir LPSOLVEDIR=$(PWD)/../lpsolve/dev # Path to the LPSOLVE include files LPSOLVEINC=${LPSOLVEDIR} # LPSOLVE library path and options LPSOLVELD=-L${LPSOLVEDIR} -llpsolve55 -Wl,-rpath,${LPSOLVEDIR} endif #====================================================== # CPLEX settings (optional) # see http://www-01.ibm.com/software/integration/optimization/cplex/ #====================================================== # if you want to use cplex uncomment next line (or use USECPLEX=1 as make parameter) #USECPLEX=1 ifeq ($(USECPLEX),1) # Path to the CPLEX main dir CPXDIR=/usr/local/ilog_academic/cplex_studio_12.2 # path to cplex include directory CPXINC=$(CPXDIR)/cplex/include/ # path to cplex library CPXLIB=$(CPXDIR)/cplex/lib/x86-64_sles10_4.1/static_pic # cplex ld flags CPXLD=-L$(CPXLIB) -lcplex -lm -lpthread endif #====================================================== # Gurobi settings (optional) # see http://www.gurobi.com #====================================================== # if you want to use gurobi uncomment next line (or use USEGUROBI=1 as make parameter) #USEGUROBI=1 ifeq ($(USEGUROBI),1) # Path to the main GUROBI dir GUROBIDIR=/usr/local/gurobi/gurobi451/linux64 # path to gurobi include directory GUROBIINC=$(GUROBIDIR)/include/ # path to gurobi library GUROBILIB=$(GUROBIDIR)/lib/ # gurobi ld flags GUROBILD=-L$(GUROBILIB) -lgurobi45 -lpthread -lm -Wl,-rpath,$(GUROBILIB) endif ##################################################################### # compiler setting (must be compiled using a C++ compiler (only tested with g++)) ##################################################################### SRCLIB=libsrcs SRCDIR=sources OBJDIR=objs INC=-I$(OBJDIR) -I$(SRCDIR) -I$(SRCLIB) #CCCOPT=-g -Wall CCCOPT=-Wall -O6 CCC=g++ $(CCCOPT) mccs-1.1/examples/legacy.cudf0000600017777601777760000000370411574427503016052 0ustar nobodynogrouppreamble: property: suite: enum[stable,testing,unstable] = [stable], bugs: int = [0], description: string = ["no description"] univ-checksum: 8c6d8b4d0cf7027cd523ad095d6408b4901ac31c status-checksum: 6936ce910eb716ad97190393f80c14ab04d95b3d req-checksum: 17259225eaf63642f9ab99a627b9857a5b27c5f7 package: car version: 1 depends: engine, wheel, door, battery installed: true description: 4-wheeled, motor-powered vehicle package: bicycle version: 7 description: 2-wheeled, "pedal-powered" vehicle package: gasoline-engine version: 1 depends: turbo provides: engine conflicts: engine, gasoline-engine installed: true package: gasoline-engine version: 2 provides: engine conflicts: engine, gasoline-engine suite: testing package: electric-engine version: 1 depends: solar-collector | huge-battery provides: engine conflicts: engine, electric-engine bugs: 12 package: electric-engine version: 2 depends: solar-collector | huge-battery provides: engine conflicts: engine, electric-engine suite: unstable bugs: 180 package: solar-collector version: 1 package: battery version: 3 provides: huge-battery installed: true package: wheel version: 2 conflicts: wheel installed: true suite: stable package: wheel version: 3 conflicts: wheel suite: testing package: door version: 1 conflicts: door installed: true package: door version: 2 depends: window conflicts: door suite: unstable package: turbo version: 1 installed: true package: tire version: 1 conflicts: tire package: tire version: 2 conflicts: tire suite: testing package: window version: 1 conflicts: window package: window version: 2 depends: glass = 1 conflicts: window suite: testing package: window version: 3 depends: glass = 2 conflicts: window suite: unstable package: glass version: 1 conflicts: glass package: glass version: 2 conflicts: glass, tire = 2 suite: testing request: http://www.example.org/8f46e388-042f-415e-8aab-df4eeb974444.dudf install: bicycle, electric-engine = 1 upgrade: door, wheel > 2 mccs-1.1/README0000600017777601777760000001461511574427503013010 0ustar nobodynogroup mccs (which stands for Multi Criteria CUDF Solver) provides a mean to solve cudf problems as defined in the MANCOOSI european project (http://www.mancoosi.org) and was partially supported by the European Community's 7th Framework Programme (FP7/2007-2013), MANCOOSI project, grant agreement n. 214898. mccs has been developed under linux and has not been tested on other platforms. The provided mccs is statically linked and run under linux 32 bits. mccs translate the cudf problem into an integer linear program which is then solved by an underlying solver. Using mccs: ================= mccs -h gives a small help and displays the available solvers and solver interfaces for the current version. To run mccs, you need a cudf problem description written in cudf 2.0 like the legacy.cudf provided in the examples directory. The most simple way to test mccs is to type: mccs -i examples/legacy.cudf which print out the solution on stdout. With such a call mccs will resort to the default underlying solver and use a default criteria to solve the problem. example 2: mccs -i examples/legacy.cudf -o sol -lexagregate[-removed,-changed] -lpsolve Here, mccs put the solution in file "sol" and solve the problem using lpsolve solver with paranoid criteria (a variation of a stability criteria). example 3: mccs -i examples/legacy.cudf -o sol -lexsemiagregate[-removed,-notuptodate,-nunsat[recommends:,true],-new] The criteria used here is the trendy criteria. Note that, due to the lack of the recommends: property in the legacy.cudf example, the nunsat criteria will be ignored. Using file based solvers: ========================= mccs can also be used with solvers which are either lp compliant (see cplex documentation) or pblib (pseudo boolean library) compliant. It has been tested with cbc and scip for the lp interface and wbo for the pblib interface. Note that none of these solvers are provided. Three small batch files are provided to handle these solvers. For example, to solve a problem using cbc, use the lp interface with the cbclp script: mccs -i examples/legacy.cudf -o sol -lexagregate[-removed,-changed] -lp cbclp To allow such calls, the user will first have to edit the related batch files (cbclp, sciplp and/or wbopb) and change the path which point to the solver. Other batch files: ================== solverparanoid and solvertrendy are two batch files which solve a cudf problem according to the criteria defined for the MANCOOSI competition (see http://www.mancoosi.org for more information). Compiling mccs: ===================== mccs can be compiled with the following underlying solvers: - glpk (see http://www.gnu.org/software/glpk/) - lpsolve (see http://lpsolve.sourceforge.net/) - cplex (see http://www-01.ibm.com/software/integration/optimization/cplex/) - gurobi (see http://www.gurobi.com) Depending of its configuration, it can be compiled with all these solvers, a subset of these solvers, or none of these solvers. mccs can also use external pseudo boolean solvers through the pblib interface. It has been tested with: - wbo (see http://sat.inesc-id.pt/~vmm/research/index.html) mccs can also use external (cplex) lp compliant solvers through the lp interface. It has been tested with: - scip (see http://scip.zib.de/) - cbc (see https://projects.coin-or.org/Cbc) These two last interfaces are always compiled whatever your choosen options are. Note that mccs compilation relies on g++, bison and flex which are supposed to be available on your platform. To compile mccs, you must first edit make.local and modify the options, pathes and variables according to your needs and available libraries. This file is self explained. Once make.local has been modified, a call to make will produce mccs (a dynamically linked version of mccs). Note that running this version might need the setting of LD_LIBRARY_PATH and other shell variables. A statically linked version of mccs can be obtain by make cudf-static (provided the availability of the required static libraries). Licence: ======== Read the LICENCE file (a modified BSD licence). Solver sources: ================= libsrcs: CUDF reader and tools sources -------------------------------------- cudf.h : main include file (CUDF classes and function templates) cudf.l : a lexical analyser for CUDF problems cudf.y : a syntactic analyser for CUDF problems cudf_tools.c : class implementations and CUDF printing functions sources: CUDF solver sources ---------------------------- cudf.c : main function cudf_types.h : a few common types shared by most files constraint_generation.h & constraint_generation.c : translate a CUDF problem into a MILP problem cudf_reductions.h & cudf_reductions.c : simplify the problem whenever possible abstract_solver.h : abstract class interface for underlying solver scoeff_solver.h : template to ease handling solver coefficients cplex_solver.h & cplex_solver.c : cplex solver interface lpsolve_solver.h & lpsolve_solver.c : lpsolve solver interface glpk_solver.h & glpk_solver.c : glpk solver interface gurobi_solver.h & gurobi_solver.c : gurobi solver interface pblib_solver.h & pblib_solver.c : pblib compliant solvers interface lp_solver.h & lp_solver.c : cplex lp compliant solvers interface abstract_combiner.h : abstract class for combiners combiner.h : gather all combiner definitions agregate_combiner.h & agregate_combiner.c : implements an agregate combiner lexagregate_combiner.h & lexagregate_combiner.c : implements a lexicographic agregate combiner lexicographic_combiner.h & lexicographic_combiner.c : implements a lexicographic combiner leximax_combiner.h & leximax_combiner.c : implements a leximax order leximin_combiner.h & leximin_combiner.c : implements a leximin order lexleximax_combiner.h & lexleximax_combiner.c : implements a lexleximax combiner lexleximin_combiner.h & lexleximin_combiner.c : implements a lexleximin combiner lexsemiagregate_combiner.h & lexsemiagregate_combiner.c : implements a lexsemiagregate combiner abstract_criteria.h : abstract class for criteria criteria.h : gather all criteria definition changed_criteria.h & changed_criteria.c : implements the changed criteria count_criteria.h & count_criteria.c : implements the count criteria new_criteria.h & new_criteria.c : implements the new criteria notuptodate_criteria.h & notuptodate_criteria.c : implements the notuptodate criteria nunsat_criteria.h & nunsat_criteria.c : implements the nunsat criteria removed_criteria.h & removed_criteria.c : implements the removed criteria mccs-1.1/LICENCE0000600017777601777760000000277011574427503013114 0ustar nobodynogroup Copyright (c) 2009-2011, Claude Michel, I3S (UNS-CNRS). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the I3S, UNS or CNRS nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mccs-1.1/CHANGES0000600017777601777760000000026511613557046013117 0ustar nobodynogroup mccs 1.1 (26/07/11): * add unaligned criteria mccs 1.01 (24/05/11): * correct some bugs in lp_solver.c: there was some troubleshot in reading solutions from underlying solvers mccs-1.1/cbclp0000700017777601777760000000014711574427503013132 0ustar nobodynogroup#!/bin/sh ( echo "import $1" echo "solve" echo "solution \$" ) | ../cbc/Cbc-2.6.4/build/bin/cbc mccs-1.1/sciplp0000700017777601777760000000007411574427503013340 0ustar nobodynogroup#!/bin/sh ../scip/scip-2.0.1.linux.x86_64.gnu.opt.spx -f $1 mccs-1.1/wbopb0000700017777601777760000000005711574427503013160 0ustar nobodynogroup#!/bin/sh ../PB/wbo-static -file-format=opb $* mccs-1.1/solveparanoid0000700017777601777760000000026211574427503014713 0ustar nobodynogroup#!/bin/sh # solving CUDF problems with paranoid criteria # first parameter = CUDF problem # second parameter = solution file mccs -i $1 -o $2 -lexagregate[-removed,-changed] mccs-1.1/solvetrendy0000700017777601777760000000032511574427503014423 0ustar nobodynogroup#!/bin/sh # solving CUDF problems with trendy criteria # first parameter = CUDF problem # second parameter = solution file mccs -i $1 -o $2 -lexsemiagregate[-removed,-notuptodate,-nunsat[recommends:,true],-new] mccs-1.1/objs/0000700017777601777760000000000011625174621013051 5ustar nobodynogroup