diff --git a/PackageInfo.g b/PackageInfo.g
index 1b6d196..56c2650 100644
--- a/PackageInfo.g
+++ b/PackageInfo.g
@@ -30,7 +30,7 @@ Persons := [
IsMaintainer := true,
FirstNames := "Markus",
LastName := "Baumeister",
- WWWHome := "https://www.mathb.rwth-aachen.de/cms/MATHB/Der-Lehrstuhl/Team/Wissenschaftliche-Beschaeftigte/~rsbs/Markus-Baumeister/",
+ WWWHome := "https://www.mathb.rwth-aachen.de",
Email := "baumeister@momo.math.rwth-aachen.de",
PostalAddress := "TODO",
Place := "Aachen",
diff --git a/gap/AttributeScheduler.gd b/gap/AttributeScheduler.gd
index 8ea3692..ab4c446 100644
--- a/gap/AttributeScheduler.gd
+++ b/gap/AttributeScheduler.gd
@@ -5,27 +5,93 @@
## Copyright 2017, Markus Baumeister, RWTH Aachen
## Sebastian Gutsche, Siegen University
##
-##! @Chapter Attribute scheduler Graph
-##! @Section TODO
##
#############################################################################
DeclareGlobalFunction( "__ATTRIBUTESCHEDULER_evaluate_recursive" );
DeclareCategory( "IsAttributeSchedulerGraph", IsObject );
+#! @Chapter Introduction
+#! @Section Overview
+#! This manual describes the AttributeScheduler package, a GAP package for constructing
+#! a graph to compute attributes with dependencies. The graph describes which
+#! attribute implies other attributes. That means in detail that the nodes of the graph are the
+#! attributes and the edges describe the dependencies. The graph can be constructed with
+#! the method and
+#! edges can be added with .
+#! @Section Example
+#! To understand how an attribute scheduler graph works consider an example.
+#! Think about three attributes A, B and C.
+#! @BeginExample
+#! gap> DeclareAttribute( "A", IsAttributeStoringRep );
+#! gap> DeclareAttribute( "B", IsAttributeStoringRep );
+#! gap> DeclareAttribute( "C", IsAttributeStoringRep );
+#! @EndExample
+#! Where an attribute of an object can be calculated if the object has a certain other attribute.
+#! @BeginExample
+#! gap> InstallMethod( A, [ HasB ], i -> B( i )*2 );
+#! gap> InstallMethod( B, [ HasC ], i -> C( i )*5 );
+#! @EndExample
+#! Construct now the attribute scheduler graph with this three attributes.
+#! @BeginExample
+#! gap> graph := AttributeSchedulerGraph( [ "A", "B", "C"] );
+#! @EndExample
+#! The goal of the graph is to describe dependencies of the attributes.
+#! For example, if attribute B is known for an object and one uses that to calculate attribute A
+#! for this object. This is represented as adding an incidence between the two attributes in the graph.
+#! Analogously add an incidence for the attribute B which can be calculated if attribute C is known for the object.
+#! @BeginExampleSession
+#! gap> AddPropertyIncidence( graph, "A", "B" );
+#! gap> AddPropertyIncidence( graph, "B", "C" );
+#! @EndExampleSession
+#! Look at an example, where the attribute A is tried to calculate by knowing attribute C:
+#! @BeginExampleSession
+#! gap> S := SymmetricGroup( 3 );;
+#! gap> SetC( S, 1 );
+#! gap> ComputeProperty( graph, A, S );
+#! 10
+#! @EndExampleSession
+#! Because of the dependencies it is possible to calculate attribute A by knowing attribute C.
+#! The attribute B stores the value 5 because it calculates 5*1, since the value of C for S is 1.
+#! With this the result is 10 since the value of attribute A can be computed for S which is 2*5=10.
+#!
+#! Another way to calculate this is to use the method AddAttribute.
+#! This offers a way to compute the value of A for some known property.
+#! Internally, it calls the method ComputeProperty described above.
+#! For the example above this method offers the opportunity to compute the attribute A for the object S.
+#! @BeginExampleSession
+#! gap> S := SymmetricGroup( 3 );;
+#! gap> SetC( S, 1 );
+#! gap> AddAttribute(graph, A, IsAttributeStoringRep,"example");
+#! gap> A(S);
+#! 10
+#! @EndExampleSession
+#!
+#! The attribute scheduler can be imagine like a graph.
+#! Where the nodes are the attributes and an edge goes from X to Y
+#! if the value of attribute Y can be calculated if the value attribute X is known.
+#! In this example we have three nodes A, B and C, an edge from C to B and an edge from B to A.
+#! In this sense the method ComputeProperty tries to find a path from a known attribute to the attribute that we want to compute.
+#! If there are different paths resp. different ways to compute the attribute, the method returns just the first solution it finds.
+#! That mean the order of adding property incidences can leads to different results.
-#! @BeginGroup
+#! @Chapter Attribute Scheduler Graph
+#!
+#! @Section Construction
+#! @BeginGroup Section_AttributeSchedulerGraph
#! @Description
-#! Constructor for the attribute scheduler graph.
-#! Takes an optional argument list, which is a list of
-#! strings and serves as nodes for the graph. Nodes can always be added
-#! by adding edges via AddPropertyIncidence.
-#! @Returns An attribute scheduling graph
+#! Constructor for the attribute scheduler graph.
+#! Takes an optional argument list, which is a list of
+#! strings that are attributes and serves as nodes for the graph.
+#! Nodes can be added later by adding edges via AddPropertyIncidence.
+#! @Returns An attribute scheduler graph
#! @Arguments [list]
-DeclareOperation( "AttributeSchedulerGraph", [ ] );
DeclareOperation( "AttributeSchedulerGraph", [ IsList ] );
#! @EndGroup
+#
+#DeclareOperat( "AttributeSchedulerGraph", [ ] );
+#! @BeginGroup AddAttribute
#! @Description
#! Add an attribute to the attribute scheduler graph. This method will
#! install a method for the attribute that calls the attribute
@@ -35,28 +101,31 @@ DeclareOperation( "AttributeSchedulerGraph", [ IsList ] );
#! is a filter.
#! @Arguments graph, attribute, filter, description
DeclareOperation( "AddAttribute", [IsAttributeSchedulerGraph, IsObject, IsObject, IsString] );
+#! @EndGroup
-#! @BeginGroup
+#! @BeginGroup AddPropertyIncidence
#! @Description
-#! Adds an edge to graph. Tells the graph that the property
-#! property can be computed if the properties in requirements
-#! are computed and the properties in dependencies are true (the
-#! dependencies are not computed by the graph).
+#! Adds an edge to graph. Tells the graph that the property
+#! property can be computed if the properties in requirements
+#! are computed and the properties in dependencies are true (the
+#! dependencies are not computed by the graph).
#!
-#! Here, requirements can be a list of strings naming required
-#! properties, or a single string naming a single required property. The
-#! argument dependencies has to be list of strings.
+#! Here, requirements can be a list of strings naming required
+#! properties, or a single string naming a single required property. The
+#! argument dependencies has to be a list of strings.
#!
-#! @Arguments graph, property, requirements
-DeclareOperation( "AddPropertyIncidence", [ IsAttributeSchedulerGraph, IsString, IsList ] );
-#! @Arguments graph, property, requirements, dependencies
+#! @Arguments graph, property, requirements[, dependencies]
DeclareOperation( "AddPropertyIncidence", [ IsAttributeSchedulerGraph, IsString, IsList, IsList ] );
#! @EndGroup
-#! @Arguments graph,attribute,object
-#! @Returns Value for attribute
+#! @Section Computation of properties
+#!
+#! @BeginGroup ComputeProperty
#! @Description
-#! Checks the attribute scheduler graph graph if there is a way to compute
-#! attribute for object. If so, the value is returned. If not, an error
+#! Checks the attribute scheduler graph graph if there is a way to compute
+#! attribute for object. If so, the value is returned. If not, an error
#! is raised.
+#! @Returns Value for attribute
+#! @Arguments graph, attribute, object
DeclareOperation( "ComputeProperty", [ IsAttributeSchedulerGraph, IsFunction, IsObject ] );
+#! @EndGroup
diff --git a/gap/AttributeScheduler.gi b/gap/AttributeScheduler.gi
index a95908b..bb48d25 100644
--- a/gap/AttributeScheduler.gi
+++ b/gap/AttributeScheduler.gi
@@ -19,7 +19,7 @@ BindGlobal( "TheTypeAttributeSchedulerGraph",
IsAttributeSchedulerGraphRep ) );
##
-InstallMethod( AttributeSchedulerGraph,
+InstallOtherMethod( AttributeSchedulerGraph,
[ ],
function( )
@@ -36,7 +36,11 @@ InstallMethod( AttributeSchedulerGraph,
graph := rec( );
for i in methods do
- graph.(i) := [ ];
+ #if IsBound(i) and IsAttribute(i) then
+ graph.(i) := [ ];
+ #else
+ # Error(Concatenation("The entries in the list ", String(methods), " must be attributes"));
+ #fi;
od;
Objectify( TheTypeAttributeSchedulerGraph, graph );
@@ -45,7 +49,7 @@ InstallMethod( AttributeSchedulerGraph,
end );
-InstallMethod( AddPropertyIncidence,
+InstallOtherMethod( AddPropertyIncidence,
[ IsAttributeSchedulerGraph, IsString, IsList ],
function( graph, property_to_compute, property_depends_on )
@@ -77,7 +81,7 @@ InstallMethod( AddPropertyIncidence,
end );
-InstallMethod( AddPropertyIncidence,
+InstallOtherMethod( AddPropertyIncidence,
[ IsAttributeSchedulerGraph, IsString, IsString ],
function( graph, property_to_compute, property_depends_on )