/*
Copyright (c) 2017, UT-Battelle, LLC
evendim, Version 0.
This file is part of evendim.
evendim is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
evendim is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with evendim. If not, see .
*/
#ifndef GENE_H
#define GENE_H
#include "Vector.h"
#include "TypeToString.h"
namespace Gep {
template
class Gene {
typedef typename EvolutionType::PrimitivesType::NodeType NodeType;
typedef typename TreeType::VectorValueType VectorValueType;
typedef typename NodeType::ValueType ValueType;
typedef typename PsimagLite::Vector::Type VectorTreeType;
typedef Gene GeneType;
public:
Gene(SizeType head,
bool isCell,
const EvolutionType& evolution,
const PsimagLite::String& str)
: head_(head),
tail_(evolution.tail(head)),
str_(str)
{
if (!isCell) evolution.checkStringNonCell(str_,head);
SizeType headPlusTail = head_ + tail_;
fromString(vt_,evolution,str,headPlusTail,isCell);
}
~Gene()
{
deleteAll();
}
static void fromString(VectorTreeType& vt,
const EvolutionType& evolution,
const PsimagLite::String& str,
SizeType effectiveSize,
bool isCell)
{
PsimagLite::Vector::Type va;
PsimagLite::String dc = str.substr(effectiveSize);
SizeType sumOfA = 1;
SizeType dcIndex = 0;
char dcChar = (dc.length() > 0) ? dc[dcIndex] : '0';
assert(dcChar >= 48);
SizeType dcNumber = dcChar - 48;
const VectorValueType& dcArray = evolution.primitives().dcValues();
assert(dc.length() ==0 || dcNumber < dcArray.size());
ValueType dcValue = (dc.length() > 0) ? dcArray[dcNumber] : 0;
for (SizeType i = 0; i < effectiveSize; i++) {
char c = str[i];
const NodeType& node = evolution.findNodeWithCode(c,dcValue,isCell);
if (c == '?') {
assert(dc.length() > 0);
dcIndex++;
assert(dcIndex < dc.length());
dcChar = dc[dcIndex];
dcNumber = dcChar - 48;
assert(dcNumber < dcArray.size());
dcValue = dcArray[dcNumber];
}
SizeType a = node.arity();
sumOfA += (a - 1);
TreeType* tree = new TreeType(evolution.primitives(),
node,
evolution.verbose());
va.push_back(a);
vt.push_back(tree);
if (sumOfA == 0) break;
}
SizeType k = 0;
for (SizeType i = 0; i < vt.size(); i++) {
SizeType a = va[i];
if (a == 0 || !vt[i]) continue;
for (SizeType j = k+1; j < k+a+1; j++) {
if (j>=vt.size()) continue;
vt[i]->setDescendants(*vt[j]);
}
k += a;
}
}
const PsimagLite::String& string() const
{
return str_;
}
const TreeType& getExpression() const
{
return *vt_[0];
}
const SizeType head() const { return head_; }
PsimagLite::String effectiveString() const
{
SizeType index = vt_.size();
return str_.substr(0,index);
}
private:
void deleteAll()
{
for (SizeType i = 0; i < vt_.size(); i++) {
if (vt_[i]) delete vt_[i];
vt_[i] = 0;
}
}
SizeType head_;
SizeType tail_;
PsimagLite::String str_;
VectorTreeType vt_;
}; // class Gene
} // namespace Gep
#endif // GENE_H