Commit 4041b831 authored by Alvarez, Gonzalo's avatar Alvarez, Gonzalo
Browse files

Predicates: added files

parent 4b6283fe
Loading
Loading
Loading
Loading

src/PredicateAnd.h

0 → 100644
+45 −0
Original line number Diff line number Diff line
#ifndef PREDICATEAND_H
#define PREDICATEAND_H
#include "Vector.h"
#include "PredicateSimple.h"
#include "PsimagLite.h"

namespace Dmrg {

/* PSIDOC PredicateAnd
 PredicateAnd is a semicolon-separated list of simple predicates,

 SimplePredicate0;SimplePredicate1;...

 where ; means to AND the predicates.
 */
class PredicateAnd {

public:

	typedef PsimagLite::Vector<PredicateSimple>::Type VectorPredicateSimpleType;

	PredicateAnd(PsimagLite::String pred)
	    : pred_(pred)
	{
		PsimagLite::split(tokens, str, ";");
		for (SizeType i = 0; i < n; ++i)
			vPredicateSimple_.push_back(PredicateSimple(str[i]));
	}

	template<typename T>
    bool isTrue(PsimagLite::String name, T val)
	{
		SizeType n = vPredicateSimple_.size();
		for (SizeType i = 0; i < n; ++i)
			if (!vPredicateSimple_[i].isTrue(name, val)) return false;
		return true;
	}

private:

	PsimagLite::String pred_;
	VectorPredicateSimpleType vPredicateSimple_;
};
}
#endif // PREDICATEAND_H

src/PredicateAwesome.h

0 → 100644
+87 −0
Original line number Diff line number Diff line
#ifndef PREDICATE_AWESOME_H
#define PREDICATE_AWESOME_H

#include "Vector.h"
#include "PredicateAnd.h"

namespace Dmrg {

/* PSIDOC PredicateAwesome
 Comma-separated list of items, don't leave spaces:
 item0,item1,item2,...

 Each item is either a setting or a predicate

 At least one item is a predicate

 If multiple predicates are present, they are ORed.

 Setting item is of the form
 S1   /\[a-zA-Z]+/
 S2  /\[a-zA-Z]+=\[a-zA-Z\d\.\-]/

 Predicate is a semicolon-separated list of simple predicates,

 SimplePredicate0;SimplePredicate1;...

 where ; means to AND the predicates.

 where SimplePredicate is of the form
 word operator word
 where operator is in {==, <, >, <=, >=, %}
 with the expected meaning, and % means divisible by.
 So l%2 means that the simple predicate is true if l is divisible by 2.

 From this rules, the list of items
 M=2,l%2;l!=0,l=7..11

 will set M=2 and define a predicate that is true if l
 is in the set {2, 4, 6, 7, 8, 9, 10, 12, 14, 16, 18 ...}
 and false otherwise.
 Had we used
 M=2,l%2;l!=0,l=7...11
 the range would have included 11.

 API via SpecType

 S1 calls SpecType::set(String word)
 S2 calls SpecType::set(String word1, String word2)

 The predicate call is
 bool SpecType::isPredicateTrue(const VectorStringType& variables,
                                const VectorSizeType& values)
 Only variables of type SizeType are supported for now.

 In the future we could use
 template<typename T>
 bool SpecType::isPredicateTrue(String name, T val)

 template<typename T1, typename T2>
 bool SpecType::isPredicateTrue(String name1, T1 val2, String name2, T2 val2)

 etc.
 */

template<typename SpecType>
class PredicateAwesome {

public:

	typedef PsimagLite::Vector<PredicateAnd>::Type VectorPredicateAndType;

	template<typename T>
    bool isTrue(PsimagLite::String name, T val)
	{
		SizeType n = predicateAnd_.size();
		for (SizeType i = 0; i < n; ++i)
			if (predicateAnd_[i].isTrue(name, val)) return true;
		return false;
	}

private:

	VectorPredicateAndType predicateAnd_;

};
}
#endif // PREDICATE_AWESOME_H
+7 −0
Original line number Diff line number Diff line
#include "PredicateSimple.h"

namespace PsimagLite {
PredicateSimple::VectorStringType PredicateSimple::ops_ =
{"==", "<=", ">=", ">", "<", "%"};

}

src/PredicateSimple.h

0 → 100644
+126 −0
Original line number Diff line number Diff line
#ifndef PREDICATE_SIMPLE_H
#define PREDICATE_SIMPLE_H
#include "Vector.h"
#include "PsimagLite.h"
#include "ExpressionCalculator.h"

/* PSIDOC PredicateSimple
 PredicateSimple is of the form
 word operator word
 where operator is in {==, <, >, <=, >=, %}
 with the usual meaning, and % means divisible by.
 So l%2 means that the simple predicate is true if l is divisible by 2.
 */
namespace PsimagLite {

class PredicateSimple {

public:

	typedef Vector<String>::Type VectorStringType;

	PredicateSimple(String pred)
	    : pred_(pred)
	{
		SizeType length = 0;
		size_t location = String::npos;

		SizeType n = pred.length();
		if (n < 3) err("PredicateSimple: pred must have at least 3 characters\n");

		for (SizeType i = 0; i < n - 1; ++i) {
			String maybeOp = pred.substr(i, 1);
			if (operatorLength(maybeOp) == 1) {
				location = i;
				length = 1;
				break;
			}

			maybeOp = pred.substr(i, 2);
			if (operatorLength(maybeOp) == 2) {
				location = i;
				length = 2;
				break;
			}
		}

		lhs_ = pred.substr(0, location);
		op_ = pred.substr(location, length);
		rhs_ = pred.substr(location + length, n - location - length);
	}

	template<typename T>
	bool isTrue(String name, T val)
	{

		T lv = getValue(lhs_, name, val);
		T rv = getValue(rhs_, name, val);
		return compareOnOp(lv, op_, rv);
	}

private:

	template<typename T>
	static bool compareOnOp(T lv, String op, T rv)
	{
		// {==, <, >, <=, >=, %}
		if (op == "==")
			return (lv == rv);
		if (op == "<")
			return (lv < rv);
		if (op == ">")
			return (lv > rv);
		if (op == "<=")
			return (lv <= rv);
		if (op == ">=")
			return (lv >= rv);
		if (op == "%")
			return ((lv % rv) == 0);
		throw RuntimeError("Unknown operator " + op + "\n");
	}

	static SizeType operatorLength(String op)
	{
		const SizeType n = ops_.size();
		for (SizeType i = 0; i < n; ++i)
			if (op == ops_[i]) return op.length();

		return 0;
	}

	template<typename T>
	static T getValue(String hs, String name, T val)
	{
		String numericHs = replaceVariable(hs, name, val);
		VectorStringType tokens;
		split(tokens, numericHs, "|");
		typedef ExpressionCalculator<T> ExpressionCalculatorType;
		ExpressionCalculatorType expressionCalculator(tokens);
		return expressionCalculator();
	}

	template<typename T>
	static String replaceVariable(String hs,
	                              String name,
	                              T val)
	{
		String buffer;
		const SizeType n = hs.length();
		for (SizeType i = 0; i < n; ++i) {
			if (hs[i] == name[0])
				buffer += ttos(val);
			else
				buffer += hs[i];
		}

		return buffer;
	}

	static VectorStringType ops_;
	String pred_;
	String lhs_;
	String op_;
	String rhs_;
};
}
#endif // PREDICATE_SIMPLE_H