transitive_closure.h

Back to Functional transitive closure

pastel/sys/graph/transitive_closure/

// Description: Transitive closure of a function

#ifndef PASTELSYS_TRANSITIVE_CLOSURE_H
#define PASTELSYS_TRANSITIVE_CLOSURE_H

#include "pastel/sys/graph/transitive_closure/transitive_closure_concepts.h"
#include "pastel/sys/output/output_concept.h"
#include "pastel/sys/hashing.h"

namespace Pastel
{

    //! Transitive closure of a function
    /*!
   Let X be a set, (Y, +) be a commutative monoid, f : X --> Y, 
   and ~ subset X^2. Then the transitive closure f^+ : X --> Y 
   of f is given by

       f^+(x) = +{f(x'): x ~^+ x'},

   where ~^+ is the transitive closure of ~ (i.e. the intersection
   of all transitive relations containing ~). We define +{} = I,
   where I is the identity of the monoid, and +{y} = y, for
   all y in Y.

   See 'transitive_closure_concepts.h' for the concepts.

   identity:
   The identity element I of the monoid Y.

   function:
   The function f : X --> Y. If the relation is reflexive, then
   the function will be evaluated exactly once at each x in X.
   Otherwise the function might be evaluated multiple times.

   codomainOperator:
   The monoid operator + : Y^2 --> Y.
   
   forEachRelated:
   For a given domain element x, calls the given function
   on all x' such that x ~ x'. Specifies implicitly the 
   relation ~ in X^2.

   forEachDomain:
   For each domain element, calls the given function.
   Specifies implicitly the domain-set X. Will be called
   twice: once to compute the transitive closure, and 
   once to report the results.

   report:
   Reports the transitive closure function f^+ : X --> Y to the user 
   one (x, y)-pair at a time by report(x, std::move(y)). Only 
   the elements in the domain will be reported, even if some elements 
   might be related to elements outside the domain.

   reflexiveClosure:
   Extends the relation ~ to be reflexive, i.e. takes
   a reflexive-transitive closure instead.

   domainHash:
   Specifies the hash function to use for the domain
   elements.
   */
    template <
        typename Domain, 
        typename Codomain,
        typename ForEachDomain,
        typename ForEachRelated,
        typename Function,
        typename CodomainOperator, 
        typename Closure_Output,
        typename Domain_Hash>
    void transitiveClosure(
        const NoDeduction<Codomain>& identity,
        const ForEachDomain& forEachDomain,
        const ForEachRelated& forEachRelated,
        const Function& function,
        const CodomainOperator& codomainOperator,
        const Closure_Output& report,
        bool reflexiveClosure,
        const Domain_Hash& domainHash);

    //! Transitive closure of a function
    /*!
   This is a convenience function which calls
       
   transitiveClosure<Domain, Codomain>(
       identity,
       forEachDomain,
       forEachRelated,
       function,
       codomainOperator,
       report,
       reflexiveClosure,
       std::hash<Domain>())
   */
    template <
        typename Domain, 
        typename Codomain,
        typename ForEachDomain,
        typename ForEachRelated,
        typename Function,
        typename CodomainOperator, 
        typename Closure_Output>
    void transitiveClosure(
        const NoDeduction<Codomain>& identity,
        const ForEachDomain& forEachDomain,
        const ForEachRelated& forEachRelated,
        const Function& function,
        const CodomainOperator& codomainOperator,
        const Closure_Output& report,
        bool reflexiveClosure = false);

}

#include "pastel/sys/graph/transitive_closure/transitive_closure.hpp"

#endif