diff --git a/doc/ref/create.xml b/doc/ref/create.xml
index 8a82fb7e5f8..daee91fc762 100644
--- a/doc/ref/create.xml
+++ b/doc/ref/create.xml
@@ -1177,6 +1177,12 @@ avoid their being overwritten accidentally.
See also Section .
<#Include Label="DeclareCategory">
+<#Include Label="ClassOfOperation">
+<#Include Label="IsCategory">
+<#Include Label="IsRepresentation">
+<#Include Label="IsProperty">
+<#Include Label="IsAttribute">
+<#Include Label="CategoryByName">
<#Include Label="DeclareRepresentation">
<#Include Label="DeclareAttribute">
<#Include Label="DeclareProperty">
@@ -1188,6 +1194,7 @@ See also Section .
<#Include Label="InstallValue">
<#Include Label="DeclareSynonym">
<#Include Label="FlushCaches">
+<#Include Label="FilterByName">
diff --git a/lib/filter.g b/lib/filter.g
index de702e8a001..fdcc378ffe2 100644
--- a/lib/filter.g
+++ b/lib/filter.g
@@ -342,6 +342,86 @@ BIND_GLOBAL("NICE_FLAGS",QUO_INT(SUM_FLAGS,30));
BIND_GLOBAL( "CANONICAL_BASIS_FLAGS", QUO_INT(SUM_FLAGS,5) );
+
+#############################################################################
+##
+#V IdOfFilter
+##
+## <#GAPDoc Label="IdOfFilter">
+##
+##
+##
+##
+##
+## finds the id of the filter filter, or the id of the filter
+## with name name respectively.
+## The id of a filter is equal to the
+## position of this filter in the global FILTERS list.
+##
+## Note that not every filter for which IsFilter(filter)
+## returns true has an ID, only elementary filters do.
+##
+##
+## <#/GAPDoc>
+##
+## Note that the filter ID is stored in FLAG1_FILTER for most filters,
+## testers have the ID stored in FLAG2_FILTER, so the code below is
+## more efficient than just iterating over the FILTERS list.
+##
+##
+BIND_GLOBAL( "IdOfFilter",
+function(filter)
+ local fid;
+ fid := FLAG1_FILTER(filter);
+ if fid > 0 and FILTERS[fid] = filter then
+ return fid;
+ fi;
+ fid := FLAG2_FILTER(filter);
+ if fid > 0 and FILTERS[fid] = filter then
+ return fid;
+ fi;
+ return fail;
+end);
+
+BIND_GLOBAL( "IdOfFilterByName",
+function(name)
+ local fid;
+ for fid in [1..LEN_LIST(FILTERS)] do
+ if NAME_FUNC(FILTERS[fid]) = name then
+ return fid;
+ fi;
+ od;
+ return fail;
+end);
+
+
+#############################################################################
+##
+#V FilterByName
+##
+## <#GAPDoc Label="FilterByName">
+##
+##
+##
+##
+## finds the filter with name name in the global FILTERS list. This
+## is useful to find filters that were created but not bound to a global
+## variable.
+##
+##
+## <#/GAPDoc>
+##
+BIND_GLOBAL( "FilterByName",
+function(name)
+ local fid;
+ fid := IdOfFilterByName(name);
+ if fid <> fail then
+ return FILTERS[fid];
+ else
+ return fail;
+ fi;
+end);
+
#############################################################################
##
#E
diff --git a/lib/function.g b/lib/function.g
index 2a966650b47..d44f5701e06 100644
--- a/lib/function.g
+++ b/lib/function.g
@@ -636,79 +636,6 @@ InstallMethod( ViewObj, "for a function", true, [IsFunction], 0,
Print(" ) ... end");
end);
-BIND_GLOBAL( "VIEW_STRING_OPERATION", function ( op )
- local class, flags, types, catok, repok, propok, seenprop,
- t, res;
- class := "Operation";
- if IS_IDENTICAL_OBJ(op,IS_OBJECT) then
- class := "Filter";
- elif IS_CONSTRUCTOR(op) then
- class := "Constructor";
- elif IsFilter(op) then
- class := "Filter";
- flags := FLAGS_FILTER(op);
- if flags <> false then
- flags := TRUES_FLAGS(flags);
- else
- flags := [];
- fi;
- types := INFO_FILTERS{flags};
- catok := true;
- repok := true;
- propok := true;
- seenprop := false;
- for t in types do
- if not t in FNUM_REPS then
- repok := false;
- fi;
- if not t in FNUM_CATS then
- catok := false;
- fi;
- if not t in FNUM_PROS and not t in FNUM_TPRS then
- propok := false;
- fi;
- if t in FNUM_PROS then
- seenprop := true;
- fi;
- od;
- if seenprop and propok then
- class := "Property";
- elif catok then
- class := "Category";
- elif repok then
- class := "Representation";
- fi;
- elif Tester(op) <> false then
- # op is an attribute
- class := "Attribute";
- fi;
-
- # Horrible.
- res := "<";
- APPEND_LIST(res, class);
- APPEND_LIST(res, " \"");
- APPEND_LIST(res, NAME_FUNC(op));
- APPEND_LIST(res, "\">");
- return res;
-end);
-
-BIND_GLOBAL( "PRINT_OPERATION",
-function ( op )
- Print(VIEW_STRING_OPERATION(op));
-end);
-
-InstallMethod( ViewObj,
- "for an operation",
- [ IsOperation ],
- PRINT_OPERATION );
-
-InstallMethod( ViewString,
- "for an operation",
- [ IsOperation ],
-function(op)
- return VIEW_STRING_OPERATION(op);
-end);
-
#############################################################################
##
#E
diff --git a/lib/function.gi b/lib/function.gi
index 5fe0b4c605e..7ee9cdcf481 100644
--- a/lib/function.gi
+++ b/lib/function.gi
@@ -60,25 +60,49 @@ function(func)
return result;
end);
-
-InstallMethod(DisplayString, "for a function, using string stream", [IsFunction],
+InstallMethod(DisplayString, "for a function, using string stream", [IsFunction],
function(fun)
local s, stream;
s := "";
stream := OutputTextString(s, true);
PrintTo(stream, fun);
CloseStream(stream);
- Add(s, '\n');
+ Add(s, '\n');
return MakeImmutable(s);
end);
-InstallMethod(String, "for a function, with whitespace reduced", [IsFunction],
+InstallMethod(String, "for a function, with whitespace reduced", [IsFunction],
function(fun)
local s, str;
s := ShallowCopy(DisplayString(fun));
- Remove(s);
+ Remove(s);
NormalizeWhitespace(s);
return MakeImmutable(s);
end);
-
+BIND_GLOBAL( "VIEW_STRING_OPERATION",
+function ( op )
+ return STRINGIFY("<", ClassOfOperation(op),
+ " \"", NAME_FUNC(op), "\">");
+end);
+
+BIND_GLOBAL( "PRINT_OPERATION",
+function ( op )
+ Print(VIEW_STRING_OPERATION(op));
+end);
+
+InstallMethod( ViewObj,
+ "for an operation",
+ [ IsOperation ],
+ PRINT_OPERATION );
+
+InstallMethod( ViewString,
+ "for an operation",
+ [ IsOperation ],
+function(op)
+ return VIEW_STRING_OPERATION(op);
+end);
+
+#############################################################################
+##
+#E
diff --git a/lib/type.gd b/lib/type.gd
index bf50fde282e..768bf8b92e0 100644
--- a/lib/type.gd
+++ b/lib/type.gd
@@ -36,3 +36,117 @@
##
DeclareOperation( "FiltersType", [ IsType ] );
DeclareOperation( "FiltersObj", [ IsObject ] );
+
+
+#############################################################################
+##
+#F ClassOfOperation( )
+##
+## Determine the class of the operation op.
+##
+## <#GAPDoc Label="ClassOfOperation">
+##
+##
+##
+##
+## returns a string from the list [ "Attribute", "Operation", "Property",
+## "Category", "Representation", "Filter"] reflecting which type of
+## operation op is.
+##
+##
+## <#/GAPDoc>
+DeclareGlobalFunction( "ClassOfOperation" );
+
+
+#############################################################################
+##
+#F IsCategory(