fill in the basic definitions to make the draft test compile
This commit is contained in:
parent
b789c110fa
commit
3e2b78b670
4 changed files with 241 additions and 12 deletions
|
|
@ -23,6 +23,47 @@
|
|||
|
||||
/** @file advice.hpp
|
||||
** Expecting Advice and giving Advice: a cross-cutting collaboration of loosely coupled participants.
|
||||
** This header exposes the basics of the advice system and the public access points. The advice system
|
||||
** is a system wide singleton service, but clients never talk directly to this singleton; rather they
|
||||
** use advice::Provision and advice::Request as access point.
|
||||
**
|
||||
** \par Advice collaboration pattern
|
||||
** Advice collaboration is a special pattern of interaction extracted from multiple use cases within
|
||||
** Lumiera. Creating this abstraction was partially inspired by aspect oriented programming, especially
|
||||
** the idea of cross-cutting the primary dependency hierarchy. Another source of inspiration where the
|
||||
** various incarnations of properties with dynamic binding. For defining the actual binding, we rely
|
||||
** on predicate notation and matching (later unification) as known from rule based systems.
|
||||
**
|
||||
** <b>Definition</b>: Advice is an optional, mediated collaboration between entities taking on
|
||||
** the roles of advisor and advised, thereby passing a custom piece of advice data, managed by
|
||||
** the advice support system. The possibility of advice is created by both of the collaborators
|
||||
** entering the system, where the advised entity exposes a point of advice, while the advising
|
||||
** entity provides an actual advice value.
|
||||
**
|
||||
** \par Collaborators
|
||||
** - the advised entity
|
||||
** - the advisor
|
||||
** - point of advice
|
||||
** - advice system
|
||||
** - the binding
|
||||
** - the advice
|
||||
**
|
||||
** Usually, the \em advised entity opens the collaboration by requesting an advice. The \em advice itself
|
||||
** is a piece of data of a custom type, which needs to be copyable. Obviously, both the advised and the
|
||||
** advisor need to share knowledge about the meaning of this advice data. The actual advice collaboration
|
||||
** happens at a \em point-of-advice, which needs to be derived first. To this end, the advised puts up an
|
||||
** \em request by providing his \em binding, which is a pattern for matching. An entity about to give advice
|
||||
** opens possible \advice \em channels by putting up an advisor binding, which similarly is a pattern. The
|
||||
** advice \em system as mediator resolves both sides, by matching (which in the most general case could be
|
||||
** an unification). This process creates an advice point \em solution -- allowing the advisor to fed the
|
||||
** piece of advice into the advice channel, causing it to be placed into the point of advice. After passing
|
||||
** a certain (implementation defined) break point, the advice leaves the influence of the advisor and gets
|
||||
** exposed to the advised entities. Especially this involves copying the advice data into a location managed
|
||||
** by the advice system. In the standard case, the advised entity accesses the advice synchronously and
|
||||
** non-blocking. Typically, the advice data type is default constructible and thus there is always a basic
|
||||
** form of advice available, thereby completely decoupling the advised entity from the timings related
|
||||
** to this collaboration.
|
||||
**
|
||||
** TODO WIP-WIP
|
||||
**
|
||||
** @note as of 4/2010 this is an experimental setup and implemented just enough to work out
|
||||
|
|
@ -46,6 +87,7 @@
|
|||
//#include "lib/hash-indexed.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/advice/binding.hpp"
|
||||
|
||||
//#include <boost/operators.hpp>
|
||||
//#include <tr1/memory>
|
||||
|
|
@ -58,8 +100,49 @@ namespace advice {
|
|||
/**
|
||||
* TODO type comment
|
||||
*/
|
||||
template<class TY>
|
||||
class PointOfAdvice;
|
||||
template<class AD>
|
||||
class PointOfAdvice
|
||||
{
|
||||
public:
|
||||
/** define or re-define the binding
|
||||
* specifically designating this attachment to the advice system.
|
||||
* @note issuing this on an existing connection is equivalent
|
||||
* to re-connecting with the new binding.
|
||||
*/
|
||||
void defineBinding (Binding const& binding);
|
||||
|
||||
/** access the \em current piece of advice */
|
||||
AD const& getAdvice();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Access point for the advised entity (client).
|
||||
* TODO type comment
|
||||
*/
|
||||
template<class AD>
|
||||
class Request
|
||||
: public PointOfAdvice<AD>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Access point for the advised entity (client).
|
||||
* TODO type comment
|
||||
*/
|
||||
template<class AD>
|
||||
class Provision
|
||||
: public PointOfAdvice<AD>
|
||||
{
|
||||
|
||||
public:
|
||||
void setAdvice (AD const& pieceOfAdvice);
|
||||
void retractAdvice();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
111
src/lib/advice/binding.hpp
Normal file
111
src/lib/advice/binding.hpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
BINDING.hpp - pattern defining a specific attachment to the Advice system
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2010, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
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 2 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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file binding.hpp
|
||||
** A pattern to define and identify a specific attachment to the Advice system.
|
||||
** This pattern is comprised of a predicate list and intended to be matched or unified
|
||||
** against a similar pattern associated with the attachment of a possible collaboration partner.
|
||||
** Semantically, this list of atoms forms an conjunction of predicates to be resolved against
|
||||
** similar predicates of the partner. Informally, when two entities attach to the Advice system,
|
||||
** each specifying a binding, they can be paired up if, when combining, the expressions in their
|
||||
** bindings all evaluate to true.
|
||||
**
|
||||
** Typically, a binding includes a \em type-guard predicate \c adviceType(xx) where \c xx is an
|
||||
** identifier denoting a type used within an instantiation of the Advice collaboration, i.e. a type
|
||||
** used as advice value in a instantiation of the PointOfAdvice<AD> template. Besides the type guard,
|
||||
** a binding may narrow down the topic of the advice by providing further predicates. This allows for
|
||||
** Advice collaborations targeted at a more specific topic. The goal and intention behind this Advice
|
||||
** system is to allow collaboration of entities without requiring them to be tightly coupled. Indeed,
|
||||
** the only dependency besides the common type used as advice is to know any specific topic used
|
||||
** within the binding. Thus, and advisor entity could put up a piece of advice, i.e. a value of
|
||||
** the advice type, and another client entity (the advised entity) could pick up this value
|
||||
** without the need to now anything about the advisor.
|
||||
**
|
||||
** Any binding can be normalised into a hash value, which plays a crucial role within the
|
||||
** implementation of the advice system.
|
||||
**
|
||||
** TODO WIP-WIP
|
||||
**
|
||||
** @note as of 4/2010 this is an experimental setup and implemented just enough to work out
|
||||
** the interfaces. Ichthyo expects this collaboration service to play a central role
|
||||
** at various places within proc-layer.
|
||||
**
|
||||
** @see configrules.hpp
|
||||
** @see typed-lookup.cpp corresponding implementation
|
||||
** @see typed-id-test.cpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_ADVICE_BINDING_H
|
||||
#define LIB_ADVICE_BINDING_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
//#include "proc/asset.hpp"
|
||||
//#include "proc/asset/struct-scheme.hpp"
|
||||
//#include "lib/hash-indexed.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
||||
//#include <boost/operators.hpp>
|
||||
//#include <tr1/memory>
|
||||
//#include <iostream>
|
||||
//#include <string>
|
||||
|
||||
namespace lib {
|
||||
namespace advice {
|
||||
|
||||
/**
|
||||
* Conjunction of predicates to be matched
|
||||
* against a collaboration partner for establishing
|
||||
* an Advice connection.
|
||||
* TODO type comment
|
||||
*/
|
||||
class Binding
|
||||
{
|
||||
public:
|
||||
/** create the empty binding, equivalent to \c true */
|
||||
Binding();
|
||||
|
||||
/** create the binding as defined by the given textual definition.
|
||||
* @note implicit type conversion deliberately intended */
|
||||
Binding (Literal spec);
|
||||
|
||||
/*-- Binding is default copyable --*/
|
||||
|
||||
/** extend the definition of this binding
|
||||
* by adding a predicate according to the
|
||||
* given textual definition */
|
||||
void addPredicate (Literal spec);
|
||||
};
|
||||
|
||||
|
||||
////TODO define the hash function here, to be picked up by ADL
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::advice
|
||||
#endif
|
||||
|
|
@ -64,17 +64,52 @@ namespace test {
|
|||
: private advice::Request<int>
|
||||
{
|
||||
public:
|
||||
bool got(int val) { return val == getAdvice(); }
|
||||
TheAdvised (Literal topic =0)
|
||||
{
|
||||
rebind (topic);
|
||||
}
|
||||
|
||||
void
|
||||
rebind (Literal topic)
|
||||
{
|
||||
defineBinding (topic);
|
||||
}
|
||||
|
||||
bool
|
||||
got(int val)
|
||||
{
|
||||
return val == getAdvice();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class TheAdvisor
|
||||
{
|
||||
advice::Provision link_;
|
||||
advice::Provision<int> link_;
|
||||
|
||||
public:
|
||||
void publish (int val) { link_.setAdvice (val); }
|
||||
void clear() { link_.retractAdvice(); }
|
||||
TheAdvisor (Literal topic =0)
|
||||
{
|
||||
rebind (topic);
|
||||
}
|
||||
|
||||
void
|
||||
rebind (Literal topic)
|
||||
{
|
||||
link_.defineBinding (topic);
|
||||
}
|
||||
|
||||
void
|
||||
publish (int val)
|
||||
{
|
||||
link_.setAdvice (val);
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
link_.retractAdvice();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,12 +514,12 @@ ColorPalette
|
|||
|
||||
SiteUrl</pre>
|
||||
</div>
|
||||
<div title="Advice" modifier="Ichthyostega" modified="201004100320" created="200910311755" tags="Concepts def spec img" changecount="20">
|
||||
<div title="Advice" modifier="Ichthyostega" modified="201004110126" created="200910311755" tags="Concepts def spec img" changecount="27">
|
||||
<pre>{{red{WIP 11/09}}}...//about to explicate a pattern which I'm aiming at within the design almost since the beginning//
|
||||
Expecting Advice and giving Advice &mdash; this collaboration ranges somewhere between messaging and dynamic properties, but cross-cutting the primary, often hierarchical relation of dependencies. Always happening at a certain //point of advice,// which creates a distinct, static nature different of being just a convention, on the other hand, Advice is deliberately kept optional and received synchronously, albeit possibly within an continuation.
|
||||
|
||||
!Specification
|
||||
''Definition'': Advice is an optional, mediated collaboration between entities taking on the roles of advisor and advised, thereby passing a custom piece of advice data, managed by the advice support system. The possibility of advice is created by the advised entity by exposing a point of advice, while the advising entity can discover this advice possibility.
|
||||
''Definition'': Advice is an optional, mediated collaboration between entities taking on the roles of advisor and advised, thereby passing a custom piece of advice data, managed by the advice support system. The possibility of advice is created by both of the collaborators entering the system, where the advised entity exposes a point of advice, while the advising entity provides an actual advice value.
|
||||
[>img[Entities for Advice collaboration|uml/fig141445.png]]
|
||||
|
||||
|
||||
|
|
@ -531,17 +531,17 @@ Expecting Advice and giving Advice &mdash; this collaboration ranges somewhe
|
|||
* ''advice system''
|
||||
* the ''binding''
|
||||
* the ''advice''
|
||||
The ''advised'' entity opens the collaboration by requsting an advice. The ''advice'' itself is a piece of data of a custom type, which needs to be //copyable.// Obviously, both the advised and the advisor need to share knowledge about the meaning of this advice data. (in a more elaborate version we might allow the advisor to provide a subclass of the advice interface type). The actual advice colaboration happens at a ''point of advice'', which needs to be derived first. To this end, the advised puts up an request by providing his ''binding'', which is a pattern for matching. An entity willing to give advice //discovers//&nbsp; possible ''advice channels'' by putting up an advisor binding, which similarily is a pattern. The ''advice system'' as mediator resolves both sides, by matching (which in the most general case could be an unification). This process creates an ''advice point solution'' &mdash; and in the most general case even multiple solutions. If we allow such, there needs to be a scheme for both sides to handle this (unexpected) multiplicity of advice points. Anyway, now the actual colaboration takes place by the advisor placing the piece of advice into the advice channel, causing it to be placed into the point of advice. After passing a certain (implementation defined) break point, the advice leaves the influence of the advisor and gets exposed to the advised entitie(s). Typically this involves copying the advice data into a location managed by the advice system. In the most simple case, the advised entity accesses the advice synchronously (an non-blocking). Of course, there could be a status flag to find out if there is new advice. Moreover, typically the advice data type is default constructible and thus there is always a basic form of advice available, thereby completely decoupling the advised entity from the timings related to this colaboration.
|
||||
Usually, the ''advised'' entity opens the collaboration by requesting an advice. The ''advice'' itself is a piece of data of a custom type, which needs to be //copyable.// Obviously, both the advised and the advisor need to share knowledge about the meaning of this advice data. (in a more elaborate version we might allow the advisor to provide a subclass of the advice interface type). The actual advice collaboration happens at a ''point of advice'', which needs to be derived first. To this end, the advised puts up an request by providing his ''binding'', which is a pattern for matching. An entity about to give advice //opens//&nbsp; possible ''advice channels'' by putting up an advisor binding, which similarly is a pattern. The ''advice system'' as mediator resolves both sides, by matching (which in the most general case could be an unification). This process creates an ''advice point solution'' &mdash; allowing the advisor to fed the piece of advice into the advice channel, causing it to be placed into the point of advice. After passing a certain (implementation defined) break point, the advice leaves the influence of the advisor and gets exposed to the advised entities. Especially, this involves copying the advice data into a location managed by the advice system. In the standard case, the advised entity accesses the advice synchronously (an non-blocking). Of course, there could be a status flag to find out if there is new advice. Moreover, typically the advice data type is default constructible and thus there is always a basic form of advice available, thereby completely decoupling the advised entity from the timings related to this collaboration.
|
||||
|
||||
!!extensions
|
||||
In a more elaborate scheme, the advised entiy could provide a signal to be invoked either in the thread context of the advisor (being still blocked in the advice providing call), or in a completely separate thread. A third solution would be to allow the advised entity to block until recieving new advice. Both of these more elaborate schemes would also allow to create an advice queue &mdash; thereby developing the advice colaboration into a kind of messaging system. Following this route seems questionable though.
|
||||
In a more elaborate scheme, the advised entity could provide a signal to be invoked either in the thread context of the advisor (being still blocked in the advice providing call), or in a completely separate thread. A third solution would be to allow the advised entity to block until receiving new advice. Both of these more elaborate schemes would also allow to create an advice queue &mdash; thereby developing the advice collaboration into a kind of messaging system. Following this route seems questionable though.
|
||||
|
||||
&rarr; AdviceSituations
|
||||
&rarr; AdviceRequirements
|
||||
&rarr; AdviceImplementation
|
||||
</pre>
|
||||
</div>
|
||||
<div title="AdviceImplementation" modifier="Ichthyostega" modified="201004100403" created="201004100056" tags="impl draft img" changecount="13">
|
||||
<div title="AdviceImplementation" modifier="Ichthyostega" modified="201004102033" created="201004100056" tags="impl draft img" changecount="14">
|
||||
<pre>[<img[Advice solution|uml/fig141573.png]]
|
||||
|
||||
|
||||
|
|
@ -556,7 +556,7 @@ In order to find matches and provide advice solutions, the advice system maintai
|
|||
This is the tricky part of the whole advice system implementation. A naive implementation will quickly degenerate in performance, as costs are of order ~AdviceProvisions * ~AdviceRequests * (average number of binding terms). But contrary to the standard solutions for rules based systems (either forward or backward chaining), in this case here always complete binding sets are to be matched, which allows to reduce the effort.
|
||||
|
||||
!!!solution idea
|
||||
The binding patterns are organised by //predicate symbol and the lists are normalised.// A simple normalisation could be lexicographic ordering of the predicates. Then the resulting representation can be //hashed.// When all predicates are constant, match can be found by hashtable lookup, otherwise, in case some predicates contain variable arguments ({{red{planned extension}}}), the lookup is followed by an unification.
|
||||
The binding patterns are organised by //predicate symbol and the lists are normalised.// A simple normalisation could be lexicographic ordering of the predicate symbols. Then the resulting representation can be //hashed.// When all predicates are constant, match can be found by hashtable lookup, otherwise, in case some predicates contain variable arguments ({{red{planned extension}}}), the lookup is followed by an unification.
|
||||
|
||||
Yet still we need to store a successful match, together with backlinks, in order to handle changing and retracting of advice.
|
||||
</pre>
|
||||
|
|
|
|||
Loading…
Reference in a new issue