1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker fad1b07018 Squashed 'software/minizinc/' content from commit 4f10c8205
git-subtree-dir: software/minizinc
git-subtree-split: 4f10c82056ffcb1041d7ffef29d77a7eef92cf76
2021-06-16 14:06:46 +10:00

116 lines
3.0 KiB
C++

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Guido Tack <guido.tack@monash.edu>
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#pragma once
#include <minizinc/flatten.hh>
#include <minizinc/hash.hh>
namespace MiniZinc {
class VarOccurrences {
public:
typedef std::unordered_set<Item*> Items;
IdMap<Items> itemMap;
IdMap<int> idx;
/// Add \a to the index
void addIndex(VarDeclI* i, int idx_i);
/// Add \a to the index
void addIndex(VarDecl* e, int idx_i);
/// Find index of \a vd
int find(VarDecl* vd);
/// Remove index of \a vd
void remove(VarDecl* vd);
/// Add \a i to the dependencies of \a v
void add(VarDecl* v, Item* i);
/// Remove \a i from map and return new number of occurrences
int remove(VarDecl* v, Item* i);
/// Remove all occurrences from map and return new number of occurrences
void removeAllOccurrences(VarDecl* v);
/// Return number of occurrences of \a v
int occurrences(VarDecl* v);
/// Return number of constraint usages of \a v and whether \a v is an output variable
std::pair<int, bool> usages(VarDecl* v);
/// Unify \a v0 and \a v1 (removing \a v0)
void unify(EnvI& env, Model* m, Id* id0, Id* id1);
/// Clear all entries
void clear();
};
class CollectOccurrencesE : public EVisitor {
public:
VarOccurrences& vo;
Item* ci;
CollectOccurrencesE(VarOccurrences& vo0, Item* ci0) : vo(vo0), ci(ci0) {}
void vId(const Id& id) {
if (id.decl() != nullptr) {
vo.add(id.decl(), ci);
}
}
};
class CollectOccurrencesI : public ItemVisitor {
public:
VarOccurrences& vo;
CollectOccurrencesI(VarOccurrences& vo0) : vo(vo0) {}
void vVarDeclI(VarDeclI* v);
void vConstraintI(ConstraintI* ci);
void vSolveI(SolveI* si);
};
class CollectDecls : public EVisitor {
public:
VarOccurrences& vo;
std::vector<VarDecl*>& vd;
Item* item;
CollectDecls(VarOccurrences& vo0, std::vector<VarDecl*>& vd0, Item* item0)
: vo(vo0), vd(vd0), item(item0) {}
static bool varIsFree(VarDecl* vd) {
if (vd->e() == nullptr || vd->ti()->domain() == nullptr || vd->ti()->computedDomain()) {
return true;
} /// TODO: test if id's domain is a superset of the right hand side
/// this currently only tests for equality, and for Boolean domains
if (Id* ident = vd->e()->dynamicCast<Id>()) {
if (Expression::equal(ident->decl()->ti()->domain(), vd->ti()->domain())) {
return true;
}
} else if (vd->e() == vd->ti()->domain()) {
return true;
}
return false;
}
void vId(Id& id) {
if ((id.decl() != nullptr) && vo.remove(id.decl(), item) == 0) {
if (varIsFree(id.decl())) {
vd.push_back(id.decl());
}
}
}
};
bool is_output(VarDecl* vd);
/// Simplyfy models in \a env
void optimize(Env& env, bool chain_compression = true);
} // namespace MiniZinc