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 )