From 6dd18a83a1f2c89c5bca435090c80d72cb8716e3 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Wed, 17 Dec 2014 11:44:36 +0100 Subject: First draft of Cardinality. There are still semantic improvements to be made, though. --- src/core/model/Cardinality.hpp | 181 +++++++++++++++++++++++++++++++++++++++++ src/core/model/Domain.hpp | 55 +++++++------ 2 files changed, 211 insertions(+), 25 deletions(-) create mode 100644 src/core/model/Cardinality.hpp (limited to 'src/core/model') diff --git a/src/core/model/Cardinality.hpp b/src/core/model/Cardinality.hpp new file mode 100644 index 0000000..aad5891 --- /dev/null +++ b/src/core/model/Cardinality.hpp @@ -0,0 +1,181 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program 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. + + This program 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 this program. If not, see . +*/ + +/** + * @file Cardinality.hpp + * + * A Cardinality in this term here is some arbitrary subset of natural numbers + * (including zero), that specifies the permits size of some other set. + * + * We define Cardinalities in a constructive process, meaning constructive + * operators on elementary sets (either single numbers or ranges of numbers). + * + * Examples for such constructions are: + * + * {1} + * {1,...,4} + * {1,...,4} union {9,...,12} union {16} + * {0,...,infinity} + * + * Note that the only construction operator needed is union (or +). + * + * @author Benjamin Paaßen (bpaassen@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_MODEL_CARDINALITY_HPP_ +#define _OUSIA_MODEL_CARDINALITY_HPP_ + +namespace ousia { +namespace model { + +/** + * This class is an abstract interface for Cardinality implementations, meaning + * either a Union of two other Cardinalities or elementary Cardinalities. + */ +class Cardinality { +public: + /** + * Returns true if and only if the given size is permits according to this + * Cardinality. + * + * @param is some natural number (size). + * @return true if and only if that size is permits. + */ + virtual bool permits(const size_t &size) const = 0; + + virtual bool operator==(const Cardinality &rhs) const = 0; +}; + +/** + * A UnionCardinality is in fact just the binary or applied to the + * permits-criteria of two other cardinalities. + */ +class UnionCardinality : public Cardinality { +private: + const Cardinality &left; + const Cardinality &right; + +public: + UnionCardinality(const Cardinality &left, const Cardinality &right) + : left(left), right(right) + { + } + + bool permits(const size_t &size) const override + { + return left.permits(size) || right.permits(size); + } + + bool operator==(const Cardinality &obj) const override + { + const UnionCardinality *o = + dynamic_cast(&obj); + if (o == NULL) + return false; + return left == o->left && right == o->right; + } +}; + +/** + * The unite function is basically just a wrapper for constructing a + * UnionCardinality. + */ +inline UnionCardinality unite(const Cardinality &lhs, const Cardinality &rhs) +{ + return std::move(UnionCardinality(lhs, rhs)); +} + +/** + * A SingleCardinality permits exactly one number. + */ +class SingleCardinality : public Cardinality { +private: + size_t num; + +public: + SingleCardinality(size_t num) : num(std::move(num)) {} + + bool permits(const size_t &size) const override { return size == num; } + + bool operator==(const Cardinality &obj) const override + { + const SingleCardinality *o = + dynamic_cast(&obj); + if (o == NULL) + return false; + return num == o->num; + } +}; + +/** + * A RangeCardinality permits all numbers between the two bounds (lo and hi), + * inclusively. + */ +class RangeCardinality : public Cardinality { +private: + size_t lo; + size_t hi; + +public: + RangeCardinality(size_t lo, size_t hi) + : lo(std::move(lo)), hi(std::move(hi)) + { + } + + bool permits(const size_t &size) const override + { + return size >= lo && size <= hi; + } + + bool operator==(const Cardinality &obj) const override + { + const RangeCardinality *o = + dynamic_cast(&obj); + if (o == NULL) + return false; + return lo == o->lo && hi == o->hi; + } +}; + +/** + * An OpenRangeCardinality permits all numbers higher or equal than the lower + * bound. + */ +class OpenRangeCardinality : public Cardinality { +private: + size_t lo; + +public: + OpenRangeCardinality(size_t lo) : lo(std::move(lo)) {} + + bool permits(const size_t &size) const override { return size >= lo; } + + bool operator==(const Cardinality &obj) const override + { + const OpenRangeCardinality *o = + dynamic_cast(&obj); + if (o == NULL) + return false; + return lo == o->lo; + } +}; +} +} + +#endif /* _OUSIA_MODEL_CARDINALITY_HPP_ */ + diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index 50c0bb1..65b9b1d 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -85,6 +85,7 @@ #include #include +#include "Cardinality.hpp" #include "Typesystem.hpp" namespace ousia { @@ -181,10 +182,9 @@ public: * Descriptor to be valid. */ FieldDescriptor(Manager &mgr, std::string name, Handle parent, - FieldType fieldType, - ManagedVector children, bool optional) + FieldType fieldType, bool optional) : Node(mgr, std::move(name), parent), - children(children), + children(this), fieldType(fieldType), // TODO: What would be a wise initialization of the primitiveType? optional(optional) @@ -194,6 +194,11 @@ public: // TODO: Is returning a ManagedVector alright? ManagedVector &getChildren() { return children; } + const ManagedVector &getChildren() const + { + return children; + } + FieldType getFieldType() const { return fieldType; } bool isPrimitive() const { return fieldType == FieldType::PRIMITIVE; } @@ -236,11 +241,10 @@ private: public: Descriptor(Manager &mgr, std::string name, Handle parent, // TODO: What would be a wise default value for attributes? - Handle attributesDescriptor, - ManagedVector fieldDescriptors) + Handle attributesDescriptor) : Node(mgr, std::move(name), parent), attributesDescriptor(acquire(attributesDescriptor)), - fieldDescriptors(fieldDescriptors) + fieldDescriptors(this) { } @@ -261,10 +265,6 @@ public: } }; -// TODO: Implement -class Cardinality { -}; - /** * A StructuredClass specifies nodes in the StructureTree of a document that * implements this domain. For more information on the StructureTree please @@ -342,7 +342,7 @@ class Cardinality { */ class StructuredClass : public Descriptor { private: - const Cardinality cardinality; + const Cardinality& cardinality; Owned isa; ManagedVector parents; @@ -351,16 +351,13 @@ public: StructuredClass(Manager &mgr, std::string name, Handle parent, Handle attributesDescriptor, - ManagedVector fieldDescriptors, const Cardinality &cardinality, // TODO: What would be a wise default value for isa? - Handle isa, - ManagedVector parents, bool transparent) - : Descriptor(mgr, std::move(name), parent, attributesDescriptor, - fieldDescriptors), + Handle isa, bool transparent) + : Descriptor(mgr, std::move(name), parent, attributesDescriptor), cardinality(cardinality), isa(acquire(isa)), - parents(parents), + parents(this), transparent(transparent) { } @@ -370,7 +367,7 @@ public: Rooted getIsA() const { return isa; } // TODO: Is returning a ManagedVector alright? - ManagedVector& getParents() { return parents; } + ManagedVector &getParents() { return parents; } const ManagedVector &getParents() const { return parents; } }; @@ -396,23 +393,31 @@ private: ManagedVector annotationClasses; public: - Domain(Manager &mgr, std::string name, - ManagedVector rootStructures, - ManagedVector annotationClasses) + Domain(Manager &mgr, std::string name) // TODO: Can a domain have a parent? : Node(mgr, std::move(name), nullptr), - rootStructures(rootStructures), - annotationClasses(annotationClasses) + rootStructures(this), + annotationClasses(this) { } // TODO: Is returning a ManagedVector alright? - ManagedVector getRootStructures() + ManagedVector &getRootStructures() + { + return rootStructures; + } + + const ManagedVector &getRootStructures() const { return rootStructures; } - ManagedVector getAnnotationClasses() + ManagedVector &getAnnotationClasses() + { + return annotationClasses; + } + + const ManagedVector &getAnnotationClasses() const { return annotationClasses; } -- cgit v1.2.3