  
  [1m[4m[31m12. [1msimpcomp[1m[4m[31m internals[0m
  
  The  package [1msimpcomp[0m works with simplicial complexes for which a [1mGAP[0m object
  type  [22m[32mSCSimplicialComplex[0m  is  defined  and  calculates  properties of these
  objects  via  so  called  property  handlers.  This chapter describes how to
  extend [1msimpcomp[0m by writing own property handlers.
  
  By   writing  own  property  handlers,  [1msimpcomp[0m  can  be  extended  in  its
  functionality.  If  you  extended  [1msimpcomp[0m and want to share your extension
  with  other  users  please  send your extension to one of the authors and we
  will  consider  including  it  (of  course  with  giving credit) in a future
  release of [1msimpcomp[0m.
  
  
  [1m[4m[31m12.1 Example of a common property handler[0m
  
  In  this  section  we  will have a look at the property handler [22m[32mSCFVector[0m in
  oder to explain the inner workings of property handlers. This is the code of
  the property handler for calculating the f-vector of a complex in [1msimpcomp[0m:
  
  [22m[35m---------------------------  Example  ----------------------------[0m
    [22m[35mInstallGlobalFunction(SCFVector,[0m
    [22m[35m	function(complex)[0m
    [22m[35m[0m
    [22m[35m	local f, faces;[0m
    [22m[35m	[0m
    [22m[35m	if(not SCIsSimplicialComplex(complex)) then[0m
    [22m[35m		SCError()("SCFVector: first argument must be of type[0m
    [22m[35m		SCSimplicialComplex.\n");[0m
    [22m[35m		return fail;[0m
    [22m[35m	fi;[0m
    [22m[35m[0m
    [22m[35m	f:=SCPropertyByName(complex,"F");[0m
    [22m[35m	if f<>fail and not SCIntFunc.ForceRecalcEnabled(complex) and  IsList(f)[0m
    [22m[35m		and	ForAll(f,x->IsInt(x) and x>=0) then[0m
    [22m[35m		return f;[0m
    [22m[35m	else[0m
    [22m[35m		SCPropertyDrop(complex,"F");[0m
    [22m[35m		faces:=SCFaceLatticeEx(complex);[0m
    [22m[35m		if faces=fail then[0m
    [22m[35m			return fail;[0m
    [22m[35m		fi;[0m
    [22m[35m		f:=List(faces,x->Size(x));[0m
    [22m[35m		SCPropertySet(complex,"F",f);[0m
    [22m[35m		return f;[0m
    [22m[35m	fi;[0m
    [22m[35mend);[0m
  [22m[35m------------------------------------------------------------------[0m
  
  When  looking  at the code one already see the structure that such a handler
  needs to have:
  
  (1)   The arguments are checked for validity -- in case of invalid arguments
        an  error  is  signaled  with [22m[32mSCError()("Error message")[0m. [22m[32mSCError[0m then
        displays the error message and optionally enters a break loop.
  
  (2)   It  is  checked  whether  the  property  was computed already with the
        function  [22m[32mSCPropertyByName[0m -- it takes a complex (as [22m[32mSCPropertyObject[0m)
        and  a property name (as [22m[32mString[0m) as arguments and returns the property
        or [22m[32mfail[0m if that property does not exist.
  
  (3)   If       [22m[32mSCPropertyByName[0m       did       not       return       [22m[32mfail[0m,
        [22m[32mSCIntFunc.ForceRecalcEnabled(complex)[0m  did return false and the cached
        property passes a validity check the cached property is returned.
  
  (4)   Otherwise   the   property   is   first   dropped   via  the  function
        [22m[32mSCPropertyDrop[0m  --  it  takes  a  complex  (as [22m[32mSCPropertyObject[0m) and a
        property  name (as [22m[32mString[0m) as arguments -- then recomputed and finally
        written back to the complex via the function [22m[32mSCPropertySet[0m (that takes
        a complex, a property name and a property as arguments) and returned.
  
  
  [1m[4m[31m12.2 Writing a property handler[0m
  
  This  section  provides  the skeleton of a property handler that can be used
  when writing own property handlers:
  
  [22m[35m---------------------------  Example  ----------------------------[0m
    [22m[35mDeclareGlobalFunction("SCMyPropertyHandler");[0m
    [22m[35m[0m
    [22m[35mInstallGlobalFunction(SCMyPropertyHandler,[0m
    [22m[35m	function(complex[, further arguments])[0m
    [22m[35m[0m
    [22m[35m	local myprop,....;[0m
    [22m[35m	[0m
    [22m[35m	# test arguments[0m
    [22m[35m	if(not SCIsSimplicialComplex(complex)) then[0m
    [22m[35m		SCError()("SCMyPropertyHandler: first argument must be of type[0m
    [22m[35m					SCSimplicialComplex.\n");[0m
    [22m[35m		return fail;[0m
    [22m[35m	fi;[0m
    [22m[35m[0m
    [22m[35m	# check if the property that you want to compute is cached[0m
    [22m[35m	myprop:=SCPropertyByName(complex,"MyProperty");[0m
    [22m[35m[0m
    [22m[35m	if myprop<>fail and not SCIntFunc.ForceRecalcEnabled(complex) and [0m
    [22m[35m		[check for validity of myprop here] then[0m
    [22m[35m		#return the cached property[0m
    [22m[35m		return myprop;[0m
    [22m[35m	else[0m
    [22m[35m		# first drop the property[0m
    [22m[35m		SCPropertyDrop(complex,"MyProperty");[0m
    [22m[35m		[0m
    [22m[35m		# now (re)compute the property  [0m
    [22m[35m		[ do property computation here][0m
    [22m[35m		[0m
    [22m[35m		# set the newly created property and return it[0m
    [22m[35m		SCPropertySet(complex,"MyProperty",myprop);[0m
    [22m[35m		return myprop;[0m
    [22m[35m	fi;[0m
    [22m[35mend);[0m
  [22m[35m------------------------------------------------------------------[0m
  
