Commit e31a4cff authored by Florent Jacquemard's avatar Florent Jacquemard
Browse files

proactive const of Runs in KeyX classes

abstract classes (type erasure) for templates InnerRun and Record for application of Visitor Pattern for Runs
parent 9f1ca721
......@@ -488,6 +488,8 @@
435F72D51FC8164600F0CC45 /* ViterbiWeight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3218827B1EB1EE3100C712CA /* ViterbiWeight.cpp */; };
435F72D61FC8165000F0CC45 /* FloatWeight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43E1147B1F8A1260001B81C2 /* FloatWeight.cpp */; };
4361318624F8EB24004EC4DE /* Inner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4361318424F8EB24004EC4DE /* Inner.cpp */; };
43631EB126186DAF004CC60F /* Recordo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43631EAF26186DAF004CC60F /* Recordo.cpp */; };
43631ECA26186E7C004CC60F /* RunInnero.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43631EC826186E7C004CC60F /* RunInnero.cpp */; };
436441EB24238F6A00BA1DF1 /* VoicingMono.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 436441E924238F6A00BA1DF1 /* VoicingMono.cpp */; };
436441EE2423CECA00BA1DF1 /* VMusPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 436441EC2423CECA00BA1DF1 /* VMusPoint.cpp */; };
436491B720F4F4C500AFAAFB /* Spiral.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 436F3C0B20ED62F000AC0C65 /* Spiral.cpp */; };
......@@ -1319,6 +1321,10 @@
436308761F9E1FC200A99524 /* QDate.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = QDate.hpp; path = ../V1/segment/QDate.hpp; sourceTree = "<group>"; };
436308791F9E320200A99524 /* InputSegment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputSegment.cpp; sourceTree = "<group>"; };
4363087A1F9E320200A99524 /* InputSegment.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = InputSegment.hpp; sourceTree = "<group>"; };
43631EAF26186DAF004CC60F /* Recordo.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Recordo.cpp; sourceTree = "<group>"; };
43631EB026186DAF004CC60F /* Recordo.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Recordo.hpp; sourceTree = "<group>"; };
43631EC826186E7C004CC60F /* RunInnero.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RunInnero.cpp; sourceTree = "<group>"; };
43631EC926186E7C004CC60F /* RunInnero.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RunInnero.hpp; sourceTree = "<group>"; };
4363620E1FDDAF22003C053F /* squant1 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = squant1; sourceTree = BUILT_PRODUCTS_DIR; };
436362101FDDAF22003C053F /* squant1.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = squant1.cpp; path = V1/targets/quant/squant1.cpp; sourceTree = "<group>"; };
436441E924238F6A00BA1DF1 /* VoicingMono.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VoicingMono.cpp; sourceTree = "<group>"; };
......@@ -2235,10 +2241,14 @@
430046E42604CF3F000E9898 /* RunTerm.cpp */,
430046F22604CF97000E9898 /* RunInner.hpp */,
430046F12604CF97000E9898 /* RunInner.tpp */,
43631EC926186E7C004CC60F /* RunInnero.hpp */,
43631EC826186E7C004CC60F /* RunInnero.cpp */,
434F406422FB198300C3940E /* RunRanked.hpp */,
434F406322FB198300C3940E /* RunRanked.tpp */,
431864B123099B5900940ECB /* RunCompare.hpp */,
4313D8DD2613231800702519 /* RunCompare.cpp */,
43631EB026186DAF004CC60F /* Recordo.hpp */,
43631EAF26186DAF004CC60F /* Recordo.cpp */,
4315C87522FAD873003F66AF /* Recordey.hpp */,
4315C87422FAD873003F66AF /* Recordey.tpp */,
4315C87222FAD583003F66AF /* RecordOne.hpp */,
......@@ -3314,11 +3324,13 @@
43169949242AA6B6006EA6BE /* MIDIOutput.cpp in Sources */,
43E272902315696C000D2DF4 /* TreePosition.cpp in Sources */,
43C67A3325879A2C00FE7724 /* Ambitus.cpp in Sources */,
43631EB126186DAF004CC60F /* Recordo.cpp in Sources */,
43F2B534248658A30035F5BA /* Clef.cpp in Sources */,
43E7604E237475B4004426E6 /* Event.cpp in Sources */,
43552EBD22A69BAF00C557BA /* Pitch.cpp in Sources */,
43E76055237475B4004426E6 /* MeterSig.cpp in Sources */,
43F2B53824866F7B0035F5BA /* KeySig.cpp in Sources */,
43631ECA26186E7C004CC60F /* RunInnero.cpp in Sources */,
43E76058237475B4004426E6 /* Score.cpp in Sources */,
43E76054237475B4004426E6 /* MeasureStack.cpp in Sources */,
4309FF4D24388C3F00A5E402 /* MeasureStacked.cpp in Sources */,
......
......@@ -24,7 +24,7 @@ _state(s)
KeyS::KeyS(const KeyS& k,
const RunInner<KeyS>& r,
RunInner<KeyS>& r,
const ParsingEnv& env)
{
assert(r.inner());
......
......@@ -105,9 +105,9 @@ public:
/// k is the parent of k0 in this case.
/// - if r is partial but not empty, construct the next sibling kn to add
/// to r. k is the parent of kn in this case.
/// - if r is inner and complete, construct a complete instance of k
/// - if r is complete, construct a complete instance of k
/// that will be the (complete) target of run r.
KeyS(const KeyS& k, const RunInner<KeyS>& r, const ParsingEnv& env);
KeyS(const KeyS& k, RunInner<KeyS>& r, const ParsingEnv& env);
/// @brief constructor of an instance of a key targeting a terminal run.
/// @param k target key for the run in 2 cases below. must be partial.
......
......@@ -40,8 +40,8 @@ _barlen(len)
// successor key (fs or ns or instance)
KeySI::KeySI(const KeySI& k, const RunInner<KeySI>& r, const ParsingEnv& env):
KeyS(k, (const RunInner<KeyS>&) r, env),
KeySI::KeySI(const KeySI& k, RunInner<KeySI>& r, const ParsingEnv& env):
KeyS(k, (RunInner<KeyS>&) r, env),
_barlen(k._barlen) // k is the parent (fs, ns) or matcher (instanciate)
{
assert(r.inner());
......
......@@ -58,7 +58,7 @@ public:
/// to r. k is the parent of kn in this case.
/// - if r is inner and complete, construct a complete instance of k
/// that will be the (complete) target of run r.
KeySI(const KeySI& k, const RunInner<KeySI>& r, const ParsingEnv& env);
KeySI(const KeySI& k, RunInner<KeySI>& r, const ParsingEnv& env);
// @brief constructor of an instance of a key targeting a terminal run.
// @param k target key for the run in 2 cases below. must be partial.
......@@ -104,8 +104,8 @@ public:
/// - a complete terminal run targeting r'
/// All the runs in stacks must be deallocate elsewhere.
void runs(std::stack<RunInner<KeySI>*>& si,
std::stack<std::pair<const KeySI*, RunTerm*>>& st,
ParsingEnv& env) const;
std::stack<std::pair<const KeySI*, RunTerm*>>& st,
ParsingEnv& env) const;
/// allocate and return a special Run representing a parse failure for this key.
/// @param env parsing environment.
......
......@@ -52,9 +52,9 @@ _post(post)
// successor key (fs or ns or instance)
KeySIP::KeySIP(const KeySIP& k,
const RunInner<KeySIP>& r,
RunInner<KeySIP>& r,
const ParsingEnv& env):
KeySI(k, (const RunInner<KeySI>&) r, env),
KeySI(k, (RunInner<KeySI>&) r, env),
_pre(k._pre), // k is the parent (fs, ns) or matcher (instanciate)
_post(k._post)
{
......
......@@ -70,7 +70,7 @@ public:
/// to r. k is the parent of kn in this case.
/// - if r is inner and complete, construct a complete instance of k
/// that will be the (complete) target of run r.
KeySIP(const KeySIP& k, const RunInner<KeySIP>& r, const ParsingEnv& env);
KeySIP(const KeySIP& k, RunInner<KeySIP>& r, const ParsingEnv& env);
/// @brief copy
KeySIP(const KeySIP& k);
......
......@@ -37,11 +37,16 @@ public:
/// deleting a RecordOne frees the best run contained.
virtual ~RecordOne();
virtual Recordo* clone() const;
/// @brief add a run to the record or delete.
/// Visitor of Runs dispatching over two Run types.
/// @param r candidate run to add.
/// @warning the key of this record must be set.
/// @warning if r is not added, it is deleted.
virtual size_t add(const Run* r);
virtual size_t addTerm(const RunTerm* r);
virtual size_t addInner(const RunInnero* r);
/// @brief returns the 1-th best run of the record.
/// @param n rank, must be 1 for RecordOne.
......@@ -56,7 +61,14 @@ protected:
/// best run for the associated state.
const Run* _best;
private:
/// Common code to addTerm and addInner
/// In this class of Recoreds, there is no distinction between the 2 types
/// of Runs.
size_t generic_add(const Run* r);
};
......
......@@ -35,6 +35,13 @@ RecordOne<K>::~RecordOne()
}
template<class K>
Recordo* RecordOne<K>::clone() const
{
return new RecordOne<K>(*this);
}
//Run* RecordOne<K>::best(TableParse<K,Record<K,H>,H>* table, size_t n)
template<class K>
const Run* RecordOne<K>::best(size_t n)
......@@ -74,7 +81,21 @@ const Run* RecordOne<K>::best(size_t n)
template<class K>
size_t RecordOne<K>::add(const Run* r)
size_t RecordOne<K>::addTerm(const RunTerm* r)
{
return generic_add(r);
}
template<class K>
size_t RecordOne<K>::addInner(const RunInnero* r)
{
return generic_add(r);
}
template<class K>
size_t RecordOne<K>::generic_add(const Run* r)
{
assert(this->_key);
const K& thiskey = *(this->_key);
......@@ -111,7 +132,7 @@ size_t RecordOne<K>::add(const Run* r)
{
assert(r->complete());
// r is the new best
if( r->filter() )
if ( r->filtered() )
{
if (_best)
{
......
......@@ -36,13 +36,19 @@ public:
/// in the candidate queue and the best list.
virtual ~RecordQueue();
/// @brief add a run to the record.
/// @param r run to add. must be complete.
virtual Recordo* clone() const;
/// @brief add a run to the record or delete.
/// Visitor of Runs dispatching over two Run types.
/// @param r candidate run to add. must be complete.
/// r is ignored (not added) if it is NULL,
/// its weight is unknown, or zero. @see Record::valid
/// @warning ignored runs are deleted.
virtual size_t add(const Run* r);
/// @warning the key of this record must be set.
/// @warning if r is not added, it is deleted.
virtual size_t addTerm(const RunTerm* r);
virtual size_t addInner(const RunInnero* r);
virtual size_t addInner(const RunInner<K>* r);
/// @brief n-th best run of the record.
/// @param n (as in n-best) is the rank of the run
/// with target to the key of the record.
......@@ -52,11 +58,10 @@ public:
/// If less than k best can be constructed (table is complete),
/// return a fail run or NULL run (weight unknown),
/// otherwise, the weight of the returned run is known.
virtual const Run* best(size_t n=1);
virtual const Run* best(size_t n=1);
virtual bool empty() const;
protected:
/// heap of candidate runs for the associated state.
......@@ -66,8 +71,8 @@ protected:
RunCompare> _cand;
/// ordered list of best runs for the associated state.
std::vector<RunRanked<K>*> _best;
std::vector<Run*> _best;
// std::vector<RunRanked<K>*> _best;
/// add Run r to the queue of candidates
/// after some filtering based on optimisation flags.
......@@ -110,6 +115,14 @@ protected:
/// the nexts Run (new candidates) will be of unknown weight
/// and with incomplete filters (initial state).
void addNext(RunRanked<K>* r);
private:
/// common code to addTerm and addInner.
size_t generic_add(RunRanked<K>* r);
};
......
......@@ -31,14 +31,16 @@ RecordQueue<K>::~RecordQueue()
while (! _cand.empty())
{
Run* r = _cand.top();
const RunRanked<K>* r = _cand.top();
_cand.pop();
assert (r);
delete r;
}
// no clear() for priority_queues
_cand = std::priority_queue<RunRanked<K>*, std::vector<RunRanked<K>*>, RunCompare>();
_cand = std::priority_queue<RunRanked<K>*,
std::vector<RunRanked<K>*>,
RunCompare>();
// std::priority_queue<RunRanked<K>*,
// vector<RunRanked<K>*>,
// std::function<bool(const Run*, const Run*)>>().swap(_cand);
......@@ -50,7 +52,7 @@ RecordQueue<K>::~RecordQueue()
TRACE("delete RecordQueue[NULL] best list (size={})",
_best.size());
for (typename std::vector<RunRanked<K>*>::iterator i = _best.begin();
for (typename std::vector<Run*>::iterator i = _best.begin();
i != _best.end(); ++i)
{
assert(*i);
......@@ -61,6 +63,13 @@ RecordQueue<K>::~RecordQueue()
}
template<class K>
Recordo* RecordQueue<K>::clone() const
{
return new RecordQueue<K>(*this);
}
template<class K>
bool RecordQueue<K>::empty() const
{
......@@ -163,9 +172,55 @@ const Run* RecordQueue<K>::best(size_t n)
//}
template<class K>
size_t RecordQueue<K>::addTerm(const RunTerm* r)
{
if (r == nullptr)
return generic_add((RunRanked<K>*) nullptr);
else
{
RunRanked<K>* rr = new RunRanked<K>(*r);
delete r;
return generic_add(rr);
}
}
template<class K>
size_t RecordQueue<K>::addInner(const RunInnero* r)
{
if (r == nullptr)
return generic_add((RunRanked<K>*) nullptr);
else
{
const RunInner<K>* ri = dynamic_cast<const RunInner<K>*>(r);
assert(ri);
RunRanked<K>* rr = new RunRanked<K>(*ri);
delete r;
// if (ri) delete ri;
return generic_add(rr);
}
}
template<class K>
size_t RecordQueue<K>::addInner(const RunInner<K>* r)
{
if (r == nullptr)
return generic_add((RunRanked<K>*) nullptr);
else
{
RunRanked<K>* rr = new RunRanked<K>(*r);
delete r;
return generic_add(rr);
}
}
// external add
template<class K>
size_t RecordQueue<K>::add(const Run* r)
size_t RecordQueue<K>::generic_add(RunRanked<K>* r)
{
assert(this->_key);
const K& thiskey = *(this->_key);
......@@ -184,14 +239,11 @@ size_t RecordQueue<K>::add(const Run* r)
assert (r->inner() || r->terminal());
assert(r);
// add 'best-index'=1 to all children
RunRanked<K>* rr = new RunRanked<K>(*r);
assert(this->valid(rr));
return addCand(rr);
return addCand(r);
}
else
{
TRACE("RecordQueue[{}].add: ignore run with unknown or zero weight {}",
thiskey, *r);
TRACE("RecordQueue[{}].add: ignore invalid run {}", thiskey, *r);
delete r;
return 3;
}
......@@ -209,7 +261,7 @@ size_t RecordQueue<K>::addCand(RunRanked<K>* r)
assert(this->_key);
const K& thiskey = *(this->_key);
if (r->weight().unknown() || r->filter())
if (r->weight().unknown() || r->filtered())
{
TRACE("RecordQueue[{}] push candidate {} run {}",
thiskey,
......@@ -264,11 +316,26 @@ void RecordQueue<K>::addBest(RunRanked<K>* r)
assert(r->complete()); // weight is evaluated
assert(this->_key);
const K& thiskey = *(this->_key);
if (r->filter())
if (r->filtered())
{
TRACE("RecordQueue[{}] add best run {}", thiskey, *r);
_best.push_back(r);
/// @todo
/// if inner, push best
/// if termimal, cast to RunTerm and push
if (r->terminal())
{
// cast back to RunTerm
RunTerm* rt = new RunTerm(r->origin(), r->length());
delete r;
_best.push_back(rt);
}
else
{
assert(r->inner());
_best.push_back(r);
}
}
else
{
......@@ -284,11 +351,13 @@ Run* RecordQueue<K>::getBest(size_t n)
{
assert(n > 0);
assert(_best.size() >= n);
Run* best = _best[n-1];
Run* best = _best[n-1]; /// @todo RunRanked<K>*
assert(best);
assert(best->complete());
assert(! best->weight().unknown());
/// @todo if inner, return best
/// if termimal, cast to RunTerm and return
return best;
}
......
......@@ -16,8 +16,10 @@
#include "trace.hpp"
#include "Runey.hpp"
#include "RunTerm.hpp"
//#include "RunTerm.hpp"
//#include "RunInner.hpp"
#include "RunCompare.hpp"
#include "Recordo.hpp"
namespace Parsing{
......@@ -26,6 +28,10 @@ namespace Parsing{
//template<class K> class RunCompare;
//template<class K, class R, class H> class TableParse;
class RunTerm;
class RunInnero;
template<class K> class RunInner;
/// @brief abstract class describing the basic functionalities of a record.
///
......@@ -42,8 +48,9 @@ namespace Parsing{
/// [update] the runs with weight zero (still invalid) can be added to records
/// but an error message is displayed (for debugging).
template<class K>
class Record
class Record : public Recordo
{
public:
Record() { assert(false); }
......@@ -58,9 +65,7 @@ public:
virtual ~Record();
/// @brief add a run to the record.
virtual size_t add(const Run* r) = 0;
/// @brief n-th best run of the record.
// @param table may be completed with new runs (lazy evaluation of candidates).
/// @param n (as in n-best) is the rank of the run with target the key of the record.
......
//
// Recordo.cpp
// squant2
//
// Created by Florent Jacquemard on 03/04/2021.
// Copyright © 2021 Florent Jacquemard. All rights reserved.
//
#include "Recordo.hpp"
namespace Parsing{
Recordo::~Recordo()
{ }
} // end namespace Parsing
//
// Recordo.hpp
// squant2
//
// Created by Florent Jacquemard on 03/04/2021.
// Copyright © 2021 Florent Jacquemard. All rights reserved.
//
/// @addtogroup parsing
/// @{
#ifndef Recordo_hpp
#define Recordo_hpp
#include <stdio.h>
#include <assert.h>
#include "trace.hpp"
#include "Runey.hpp"
//#include "RunTerm.hpp"
//#include "RunInner.hpp"
namespace Parsing{
//template<class K> class Run;
//template<class K> class RunCompare;
//template<class K, class R, class H> class TableParse;
class RunTerm;
class RunInnero;
template<class K> class RunInner;
/// Visitor of Runs
/// type erasure for a Record
class Recordo
{
public:
virtual ~Recordo();
virtual Recordo* clone() const=0;
/// @brief add a run to the record.
/// Visitor of Runs dispatching over two Run types.
virtual size_t addTerm(const RunTerm* r) = 0;
virtual size_t addInner(const RunInnero* r) = 0;
};
} // end namespace Parsing
#endif /* Recordo_hpp */
/// @}
......@@ -32,14 +32,14 @@ std::function<bool(const Run*, const Run*)>;
/// where partial run or run with unknown weight
/// is considered to be the best
/// (highest priority for unevaluated candidates)
//RunCompare weightMax;
extern RunCompare weightMax;
/// weightMin is one ordering for k-best to rank Runs
/// from worse weight to best weight,
/// where partial runs and runs with unknown weight
/// is considered to be the worst.
/// (highest priority for unevaluated candidates)
//RunCompare weightMin;
extern RunCompare weightMin;
} // end namespace
......
......@@ -21,23 +21,25 @@
#include "Weight.hpp"
#include "Transition.hpp"
#include "Runey.hpp"
#include "RunInnero.hpp"
#include "Recordey.hpp"
namespace Parsing{
template<class K>
class RunInner;
//template<class K>
//class RunInner;
//template<class K>
//std::ostream& operator<<(std::ostream& o, const RunInner<K>& r);
/// An inner run is a particular case of run with at least one subrun.
/// An inner run is complete when the length of the list of children is the arity.
/// It is partial otherwise.
/// param K = class of Key in parse table
template<class K>
class RunInner : public Run
class RunInner : public RunInnero
{
public:
......@@ -54,11 +56,15 @@ public:
/// @param w weight must not be unknown. can be updated afterwards.
/// The constructed run is partial (empty list of subruns).
RunInner(const Transition& tr, label_t lab, const Weight& w);
/// partial copy of terminal run.
/// empty list of children.
RunInner(const RunTerm& r);
/// copy constructor