utils-0.86/000755 000765 000024 00000000000 14621610515 015714 5ustar00christopherwensleystaff000000 000000 utils-0.86/PackageInfo.g000644 000765 000024 00000014150 14621444241 020235 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## ## PackageInfo.g file for the package Utils ## SetPackageInfo( rec( PackageName := "utils", Subtitle := "Utility functions in GAP", Version := "0.86", Date := "16/05/2024", # dd/mm/yyyy format License := "GPL-2.0-or-later", Persons := [ rec( LastName := "Breuer", FirstNames := "Thomas", IsAuthor := true, IsMaintainer := false, Email := "sam@math.rwth-aachen.de", WWWHome := "https://www.math.rwth-aachen.de/~Thomas.Breuer", Place := "Aachen", Institution := "Lehrstuhl für Algebra und Zahlentheorie, RWTH Aachen" ), rec( LastName := "Gutsche", FirstNames := "Sebastian", IsAuthor := true, IsMaintainer := false, Email := "gutsche@mathematik.uni-siegen.de", WWWHome := "https://sebasguts.github.io/", Place := "Siegen", Institution := "University of Siegen" ), rec( LastName := "Horn", FirstNames := "Max", IsAuthor := true, IsMaintainer := false, Email := "mhorn@rptu.de", WWWHome := "https://github.com/mhorn", ), rec( LastName := "Hulpke", FirstNames := "Alexander", IsAuthor := true, IsMaintainer := false, Email := "hulpke@math.colostate.edu", WWWHome := "https://www.math.colostate.edu/~hulpke", ), rec( LastName := "García-Sánchez", FirstNames := "Pedro", IsAuthor := true, IsMaintainer := false, WWWHome := "http://www.ugr.es/local/pedro", Email := "pedro@ugr.es", ), rec( LastName := "Jefferson", FirstNames := "Christopher", IsAuthor := true, IsMaintainer := false, WWWHome := "https://caj.host.cs.st-andrews.ac.uk/", Email := "caj21@st-andrews.ac.uk", ), rec( LastName := "Kohl", FirstNames := "Stefan", IsAuthor := true, IsMaintainer := false, Email := "stefan@mcs.st-and.ac.uk", WWWHome := "https://www.gap-system.org/DevelopersPages/StefanKohl/" ), rec( LastName := "Lübeck", FirstNames := "Frank", IsAuthor := true, IsMaintainer := false, Email := "Frank.Luebeck@Math.RWTH-Aachen.De", WWWHome := "https://www.math.rwth-aachen.de/~Frank.Luebeck", ), rec( LastName := "Wensley", FirstNames := "Chris", IsAuthor := true, IsMaintainer := true, Email := "cdwensley.maths@btinternet.com", WWWHome := "https://github.com/cdwensley", Place := "Llanfairfechan", Institution := "" ) ], Status := "deposited", ## CommunicatedBy := " ", ## AcceptDate := " ", SourceRepository := rec( Type := "git", URL := "https://github.com/gap-packages/utils" ), IssueTrackerURL := "https://github.com/gap-packages/utils/issues", PackageWWWHome := "https://gap-packages.github.io/utils", README_URL := Concatenation( ~.PackageWWWHome, "/README.md" ), PackageInfoURL := Concatenation( ~.PackageWWWHome, "/PackageInfo.g" ), ArchiveURL := Concatenation( ~.SourceRepository.URL, "/releases/download/v", ~.Version, "/", ~.PackageName, "-", ~.Version ), ArchiveFormats := ".tar.gz .zip", AbstractHTML := "The Utils package provides a collection \ of utility functions gleaned from many packages.", PackageDoc := rec( BookName := "Utils", ArchiveURLSubset := ["doc"], HTMLStart := "doc/chap0_mj.html", PDFFile := "doc/manual.pdf", SixFile := "doc/manual.six", LongTitle := "Utility functions in GAP", Autoload := true ), Dependencies := rec( GAP := ">=4.10.1", NeededOtherPackages := [ ], SuggestedOtherPackages := [ [ "curlInterface", ">= 2.3.0" ] ], ExternalConditions := [ ] ), AvailabilityTest := ReturnTrue, Autoload := false, Keywords := [ ], BannerString := Concatenation( "Loading Utils ", String( ~.Version ), " for GAP 4.13.0", " - a collection of utility functions.\n" ), TestFile := "tst/testall.g", AutoDoc := rec( TitlePage := rec( Copyright := Concatenation( "©right; 2015-2024, The GAP Group.

\n", "The &Utils; package is free software; you can redistribute it ", "and/or modify it under the terms of the GNU General ", "Public License as published by the Free Software Foundation; ", "either version 2 of the License, or (at your option) ", "any later version.\n" ), Abstract := Concatenation( "The &Utils; package provides a space for utility functions ", "in a variety of ⪆ packages to be collected together ", "into a single package. In this way it is hoped that they will ", "become more visible to package authors.\n", "

\n", "Any package author who transfers a function to &Utils; ", "will become an author of &Utils;.\n", "

\n", "If deemed appropriate, functions may also be transferred ", "from the main library.\n", "

\n", "Bug reports, suggestions and comments are, of course, welcome.\n", "Please contact the last author at ", "cdwensley.maths@btinternet.com ", "or submit an issue at the GitHub repository ", "https://github.com/gap-packages/utils/issues/.\n" ), Acknowledgements := Concatenation( "This documentation was prepared using the ", "&GAPDoc; and ", "&AutoDoc; packages.

\n", "The procedure used to produce new releases uses the package ", "GitHubPagesForGAP ", " ", "and the package ReleaseTools.

" ), ) ), )); utils-0.86/README.md000644 000765 000024 00000003471 14621444241 017201 0ustar00christopherwensleystaff000000 000000 [![Build Status](https://github.com/gap-packages/utils/workflows/CI/badge.svg?branch=master)](https://github.com/gap-packages/utils/actions?query=workflow%3ACI+branch%3Amaster) [![Code Coverage](https://codecov.io/github/gap-packages/utils/coverage.svg?branch=master&token=)](https://codecov.io/gh/gap-packages/utils) # The GAP 4 package `Utils` ## Introduction This package collects together utility functions from a selection of GAP packages in order to make them more widely visible to other package authors. Other generally useful functions, which are not deemed suitable for the main library, and also welcome. For example, recent additions are functions to convert certain types of group to Magma format. ## Distribution * The GitHub package repository is at * and the latest release is available at ## Copyright The `Utils` package is Copyright {\copyright} The GAP Group, 2015-2024. `Utils` is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. For details, see ## Installation * unpack `utils-.tar.gz` in the `pkg` subdirectory of the GAP root directory. * From within GAP load the package with: gap> LoadPackage("utils"); * The file `manual.pdf` is in the `doc` subdirectory. ## Contact If you have a question relating to `Utils`, encounter any problems, or wish to suggest other functions to be transferred to the package, please * email * or report an issue on the GitHub issue tracker at: utils-0.86/makedoc.g000644 000765 000024 00000002261 14621444241 017471 0ustar00christopherwensleystaff000000 000000 ## makedoc.g for the package Utils ## This builds the documentation of the Utils package. ## Needs: GAPDoc & AutoDoc packages, latex, pdflatex, mkindex ## call this with GAP from within the package root directory ## LoadPackage( "GAPDoc" ); LoadPackage( "AutoDoc" ); AutoDoc( rec( scaffold := rec( ## MainPage := false, includes := [ "intro.xml", "print.xml", "lists.xml", "number.xml", "groups.xml", "matrix.xml", "iterator.xml", "record.xml", "download.xml", "others.xml", "obsolete.xml", "transfer.xml" ], bib := "bib.xml", entities := rec( AutoDoc := "AutoDoc", ResClasses := "ResClasses", RCWA := "RCWA", XMod := "XMod", Home := "Home", Magma := "{\\sf Magma}", MathJax := "{\\sf MathJax}" ) ) )); utils-0.86/lib/000755 000765 000024 00000000000 14621444241 016463 5ustar00christopherwensleystaff000000 000000 utils-0.86/CHANGES.md000644 000765 000024 00000016317 14621444241 017317 0ustar00christopherwensleystaff000000 000000 # CHANGES log for the 'Utils' package ## Version 0.86 for GAP 4.13.1 (16/05/24) * (16/05/24) there have been just two minor adjustments since version 0.85 ## Version 0.85 for GAP 4.12.2 (23/01/24) * (08/01/24) avoid trivial function wrappers in List and ForAll ## Version 0.84 for GAP 4.12.2 (11/09/23) * (11/09/23) changed manual and test for DirectSumDecompositionMatrices ## Version 0.83 for GAP 4.12.2 (29/06/23) * (29/06/23) added DirectSumDecompositionMatrices ## Version 0.82 for GAP 4.12.2 (09/02/23) * (23/12/22) changed email address, deleted institution ## Version 0.81 for GAP 4.12.1 (04/12/22) * (17/11/22) removed (the dead) pcp option from PcGroupToMagmaFormat so that the dependency on Polycyclic could be removed * (21/10/22) added OptionRecordWithDefaults in 7.2 from Christopher Jefferson * (04/10/22) declared PreImagesRepresentativeNC in init.g ## Version 0.77 for GAP 4.12.0 (25/09/22) * (25/09/22) added Download operation by Thomas Breuer - new Chapter 8 ## Version 0.76 for GAP 4.12.0 (06/08/22) * (06/08/22) added LeftCoset operations ## Version 0.74 for GAP 4.11.1 (09/07/22) * (07/07/22) Max Horn replaced BIND_GLOBAL with BindGlobal (transfer process) * (05/07/22) CentralProduct added by Thomas Breuer ## Version 0.72 for GAP 4.10.1 (16/11/21) * (06/04/21) Switch CI to use GitHub Actions: PR#37 ## Version 0.69 for GAP 4.10.2 (29/11/19) * (22/11/19) added DirectProductOfAutomorphismGroups * (19/11/19) added DirectProductOfFunctions ## Version 0.67 for GAP 4.10.2 (04/09/19) * (04/09/19) accepted PR34 - changed example in 6.2.1 * (25/08/19) fixed typos with UnorderedPairsIterator in manual ## Version 0.65 for GAP 4.10.2 (11/07/19) * (11/07/19) groups.tst fails in gapdev - temporary(?) fix ## Version 0.64 for GAP 4.10.1 (17/06/19) * (14/06/19) added Iterators chapter: AllSubgroupsIterator CartesianIterator, UnorderedPairsIterator ## Version 0.63 for GAP 4.10.1 (29/05/19) * (28/05/19) added IdempotentEndomorphisms, IdempotentEndomorphismsData * (17/05/19) + AllIsomorphismsIterator, AllIsomorphismsNumber, AllIsomorphisms * (16/02/19) added License field in PackageInfo.g ## Version 0.61 for GAP 4.10.0 (28/11/18) * (28/11/18) made ExponentOfPrime obsolete * (27/11/18) made several AutoDoc functions obsolete (they remain in AutoDoc): FindMatchingFiles; CreateDirIfMissing; StringDotSuffix; SetIfMissing ## Version 0.59 for GAP 4.9.3 (04/10/18) * (04/10/18) made PrintApplicableMethod obsolete ## Version 0.58 for GAP 4.9.3 (12/09/18) * (08/09/18) marked PrintOneItemPerLine as obsolete: use Perform(L,Display); * (07/09/18) marked ExponentOfPrime as obsolete: use PValuation * (05/09/18) transferred code in combinat.g{d,i} to end of lists.g{d,i} * (04/09/18) removed all "if OKtoReadFomUtils( "RCWA" / "ResClasses" )" ## Version 0.57 for GAP 4.9.1 (02/06/18) * (02/06/18) new PrintSelection example due to diff with all packages loaded removed XMod from list of packages to be loaded * (27/03/18) revised file tst/testing.g ## Version 0.54 for GAP 4.9.0 (12/02/18) * (22/01/18) PrintOneItemPerLine plus alternative method for iterators; added function PrintSelection(L,first,step,last) for lists/iterators * (06/01/18) rebuilt the manual using the AutoDoc package * (22/12/17) removed examples/ folder ## Version 0.49 for GAP 4.8.8 (05/12/17) * (05/12/17) removed QPA functions PositionsNonzero and NullList * (21/11/17) changed record.tst so that 4r8 and dev give the same result ## Version 0.48 for GAP 4.8.8 (14/09/17) * (14/09/17) fixes to the gh-pages folder so that README.md is displayed * (12/09/17) corrected web addresses for Stefan and Frank * (04/07/17) README and CHANGES converted to README.md and CHANGES.md ## Version 0.46 for GAP 4.8.6 (08/02/17) * (08/02/17) added Polycyclic as a needed package * (07/02/17) added code for converting matrix groups to Magma strings * (03/02/17) added code for converting perm- and pc-groups to Magma strings * (02/02/17) copied `gaplog.css` to `utils/doc/` from RCWA archive ## Version 0.44 for GAP 4.8.6 (17/01/17) * (08/12/16) added PositionsNonzero and NullList from QPA * (05/12/16) added `tst/loadall.g` and adjusted `tst/testall.g`, `tst/*.tst` * (14/11/16) issue #2 reopened by Max: EpimorphismByGeneratorsNC removed ## Version 0.43 for GAP 4.8.5 (20/10/16) * (18/10/16) now using bibliography file `bib.xml` of type `bibxmlext.dtd` ## Version 0.41 for GAP 4.8.3 (25/05/16) * (25/05/16) fixed issue #8 : `git rm doc/appendix.xml` * (17/03/16) added function PrintApplicableMethod ## Version 0.40 for GAP 4.8.3 (17/03/16) * (17/03/16) moved transfer procedure to a new chapter in the manual * (15/03/16) added fix to QuotientList requested by Stefan added many manual examples supplied by Stefan ## Version 0.39 for GAP 4.8.2 (04/03/16) * (04/03/16) corrected repeated "//" in `PackageInfo.g` * (03/03/16) updated transfers from RCWA and ResClasses (Stefan's input) * (26/02/16) updated README to show the release URL * (25/02/16) New release to GitHub using ReleaseTools (GitHubPagesForGAP) `makedocrel.g` renamed `makedoc.g` * (17/02/16) Removed date/version information from file headers. * (16/02/16) Moved PackageWWWHome to GitHub; added OKtoReadFromUtilsSpec to deal with fns taken out early * (12/02/16) Added warning to manual about the need to load packages. * (11/02/16) BindInRecordIfMissing -> SetIfMissing (from AutoDoc) moved a number of functions to `pending.g{d,i}` * (10/02/16) adjustments due to new RCWA 4.0.0 and ResClasses 4.1.1 ## Version 0.22 for GAP 4.8.1 (04/02/16) * (04/02/16) repository moved to gap-packages ## Version 0.21 for GAP 4.8.1 (03/02/16) * (03/02/16) added several more functions from RCWA * (29/01/16) switching to a protocol based on Frank's suggestion: if TestPackageAvailability("Bla", ">=x.(y+1)") = fail then ... ## Version 0.17 for GAP 4.8.1 (12/01/16) * (12/01/16) more edits to `oper.g` and `global.g` suggested by Chris J. ## Version 0.15 for GAP 4.8.0 (18/12/15) * (17/12/15) added more documentation to `global.g` and `oper.g` ## Version 0.14 for GAP 4.8.0 (16/12/15) * (16/12/15) changed global lists in oper.g to GLOBAL_REDECLARATION_LIST, GLOBAL_REDECLARATION_COUNT and GLOBAL_REINSTALLATION_LIST; added functions (in `oper.g`) AllowGlobalRedeclaration and AllowGlobalReinstallation; added GLOBAL_REBINDING_LIST and AllowGlobalRebinding (in `global.g`) to cope with BIND_GLOBAL. ## Version 0.13 for GAP 4.8.0 (15/12/15) * (15/12/15) added some functions from AutoDoc; packed up version 0.13 * (14/12/15) library file `oper.g` edited to prevent repeat declarations etc. * (14/12/15) `names.g{d,i}` now `first.g{d,i}` with `last.gd` added, containing UTILS_FUNCTION_NAMES and UTILS_FUNCTION_OPERS ## Version 0.11 for GAP 4.8.0 (30/11/15) * (30/11/15) added tests and documentation for ResClasses functions * (25/11/15) added `names.g{d,i}`, `tests.g{d,i}` * (25/11/15) added `sebastian.gi` to `lib/` * (24/11/15) added `rwca.g{d,i}` and `resclasses.g{d,i}` to `lib/` * (24/11/15) added `combinat.g{d,i}` to `lib/` utils-0.86/doc/000755 000765 000024 00000000000 14621610515 016461 5ustar00christopherwensleystaff000000 000000 utils-0.86/tst/000755 000765 000024 00000000000 14621444241 016527 5ustar00christopherwensleystaff000000 000000 utils-0.86/init.g000644 000765 000024 00000002373 14621444241 017035 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W init.g GAP package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2023, The GAP Group, ## if not IsBound( PreImagesRepresentativeNC ) then BindGlobal( "PreImagesRepresentativeNC", PreImagesRepresentative ); fi; if not IsBound( IsMatrixOrMatrixObj ) then BindGlobal( "IsMatrixOrMatrixObj", IsMatrix ); fi; if not IsBound( MutableCopyMatrix ) then BindGlobal( "MutableCopyMatrix", ShallowCopy ); fi; ## read the function declarations ReadPackage( "utils", "lib/start.gd" ); ReadPackage( "utils", "lib/files.gd" ); ReadPackage( "utils", "lib/groups.gd" ); ReadPackage( "utils", "lib/iterator.gd" ); ReadPackage( "utils", "lib/latex.gd" ); ReadPackage( "utils", "lib/lcset.gd" ); ReadPackage( "utils", "lib/lists.gd" ); ReadPackage( "utils", "lib/magma.gd" ); ReadPackage( "utils", "lib/maps.gd" ); ReadPackage( "utils", "lib/matrix.gd" ); ReadPackage( "utils", "lib/number.gd" ); ReadPackage( "utils", "lib/print.gd" ); ReadPackage( "utils", "lib/record.gd" ); ReadPackage( "utils", "lib/string.gd" ); if not IsBound( Download ) then ReadPackage( "utils", "lib/download.gd" ); BindGlobal("DOWNLOAD_FROM_UTILS", true); fi; utils-0.86/LICENSE.txt000644 000765 000024 00000043103 14621444241 017541 0ustar00christopherwensleystaff000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. utils-0.86/read.g000644 000765 000024 00000001526 14621444241 017004 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W read.g The Utils package Chris Wensley ## #Y Copyright (C) 2015-2023, The GAP Group, ## ## read the actual code ReadPackage( "utils", "lib/files.gi" ); ReadPackage( "utils", "lib/groups.gi" ); ReadPackage( "utils", "lib/iterator.gi" ); ReadPackage( "utils", "lib/latex.gi" ); ReadPackage( "utils", "lib/lcset.gi" ); ReadPackage( "utils", "lib/lists.gi" ); ReadPackage( "utils", "lib/magma.gi" ); ReadPackage( "utils", "lib/maps.gi" ); ReadPackage( "utils", "lib/matrix.gi" ); ReadPackage( "utils", "lib/number.gi" ); ReadPackage( "utils", "lib/print.gi" ); ReadPackage( "utils", "lib/record.gi" ); ReadPackage( "utils", "lib/string.gi" ); if IsBound(DOWNLOAD_FROM_UTILS) then ReadPackage( "utils", "lib/download.gi" ); fi; utils-0.86/tst/lists.tst000644 000765 000024 00000007676 14621444241 020441 0ustar00christopherwensleystaff000000 000000 #@local C, c4, d16, gens, i, J, K, L, n, P, trans ############################################################################## ## #W lists.tst Utils Package ## #Y Copyright (C) 2015-2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 3.1.1 gap> List( [1..12], n->n^3 ); [ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728 ] gap> DifferencesList( last ); [ 7, 19, 37, 61, 91, 127, 169, 217, 271, 331, 397 ] gap> DifferencesList( last ); [ 12, 18, 24, 30, 36, 42, 48, 54, 60, 66 ] gap> DifferencesList( last ); [ 6, 6, 6, 6, 6, 6, 6, 6, 6 ] gap> L := [ 0 ];; gap> DifferencesList( L ); [ ] gap> L := [ ];; gap> DifferencesList( L ); [ ] ## SubSection 3.1.2 gap> List( [0..10], n -> Factorial(n) ); [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ] gap> QuotientsList( last ); [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] gap> L := [ 1, 3, 5, -1, -3, -5 ];; gap> QuotientsList( L ); [ 3, 5/3, -1/5, 3, 5/3 ] gap> FloatQuotientsList( L ); [ 3., 1.66667, -0.2, 3., 1.66667 ] gap> QuotientsList( [ 2, 1, 0, -1, -2 ] ); [ 1/2, 0, fail, 2 ] gap> FloatQuotientsList( [1..10] ); [ 2., 1.5, 1.33333, 1.25, 1.2, 1.16667, 1.14286, 1.125, 1.11111 ] gap> Product( last ); 10. ## SubSection 3.1.3 gap> L := [1..20];; L[1]:=13;; gap> for i in [1..19] do > if IsOddInt(L[i]) then L[i+1]:=3*L[i]+1; else L[i+1]:=L[i]/2; fi; > od; gap> L; [ 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4 ] gap> SearchCycle( L ); [ 1, 4, 2 ] gap> n := 1;; L := [n];; gap> for i in [1..100] do n:=(n^2+1) mod 1093; Add(L,n); od; gap> L; [ 1, 2, 5, 26, 677, 363, 610, 481, 739, 715, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004 ] gap> C := SearchCycle( L ); [ 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754 ] gap> P := Positions( L, 157 ); [ 14, 26, 38, 50, 62, 74, 86, 98 ] gap> Length( C ); DifferencesList( P ); 12 [ 12, 12, 12, 12, 12, 12, 12 ] ## SubSection 3.1.4 ## this manual example not tested as answers vary from run to run ## gap> RandomCombination( [1..49], 6 ); ## [ 3, 5, 21, 24, 27, 31 ] ## SubSection 3.2.1 gap> J := [ [1,2,3], [3,4], [3,4], [1,2,4] ];; gap> DistinctRepresentatives( J ); [ 1, 3, 4, 2 ] gap> K := [ [3,4], [1,2], [2,3], [2,3,4] ];; gap> CommonRepresentatives( J, K ); [ [ 3, 3, 3, 1 ], [ 1, 3, 4, 2 ] ] gap> d16 := DihedralGroup( IsPermGroup, 16 ); SetName( d16, "d16" ); Group([ (1,2,3,4,5,6,7,8), (2,8)(3,7)(4,6) ]) gap> c4 := Subgroup( d16, [ d16.1^2 ] ); SetName( c4, "c4" ); Group([ (1,3,5,7)(2,4,6,8) ]) gap> RightCosets( d16, c4 ); [ RightCoset(c4,()), RightCoset(c4,(2,8)(3,7)(4,6)), RightCoset(c4,(1,8,7,6,5, 4,3,2)), RightCoset(c4,(1,8)(2,7)(3,6)(4,5)) ] gap> trans := CommonTransversal( d16, c4 ); [ (), (2,8)(3,7)(4,6), (1,2,3,4,5,6,7,8), (1,2)(3,8)(4,7)(5,6) ] gap> IsCommonTransversal( d16, c4, trans ); true ## SubSection 3.3.1 gap> gens := GeneratorsOfGroup( DihedralGroup(12) ); [ f1, f2, f3 ] gap> String( gens ); "[ f1, f2, f3 ]" gap> BlankFreeString( gens ); "[f1,f2,f3]" ############################################################################# ## #E lists.tst . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/tst/print.tst000644 000765 000024 00000002027 14621444241 020420 0ustar00christopherwensleystaff000000 000000 #@local L, s5 ############################################################################## ## #W print.tst Utils Package ## #Y Copyright (C) 2015-2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 2.1.1 gap> L := List( [1..20], n -> n^5 );; gap> PrintSelection( L, [18..20] ); 18 : 1889568 19 : 2476099 20 : 3200000 gap> PrintSelection( L, 2, 9 ); 2 : 32 11 : 161051 20 : 3200000 gap> PrintSelection( L, 2, 3, 11 ); 2 : 32 5 : 3125 8 : 32768 11 : 161051 gap> s5 := SymmetricGroup( 5 );; gap> PrintSelection( s5, [30,31,100,101] ); 30 : (1,5)(3,4) 31 : (1,5,2) 100 : (1,4,3) 101 : (1,4)(3,5) gap> PrintSelection( s5, 1, 30 ); 1 : () 31 : (1,5,2) 61 : (1,2,3) 91 : (1,3,5,2,4) gap> PrintSelection( s5, 9, 11, 43 ); 9 : (2,5,3) 20 : (2,4) 31 : (1,5,2) 42 : (1,5,2,3,4) ############################################################################# ## #E print.tst . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/tst/iterator.tst000644 000765 000024 00000005250 14621444241 021116 0ustar00christopherwensleystaff000000 000000 #@local c3c3, cart, G, h, it1, it2, iter, iter0, iter4, iterL #@local L, n, pairs0, pairs4, pairsL, s3, s4 ############################################################################## ## #W iterator.tst Utils Package ## #Y Copyright (C) 2015-2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 7.1.1 gap> G := SmallGroup( 6,1);; gap> s3 := Group( (5,6), (6,7) );; gap> iter := AllIsomorphismsIterator( G, s3 );; gap> NextIterator( iter ); [ f1, f2 ] -> [ (6,7), (5,6,7) ] gap> n := AllIsomorphismsNumber( G, s3 ); 6 gap> AllIsomorphisms( G, s3 ); [ [ f1, f2 ] -> [ (6,7), (5,6,7) ], [ f1, f2 ] -> [ (5,7), (5,6,7) ], [ f1, f2 ] -> [ (5,6), (5,7,6) ], [ f1, f2 ] -> [ (6,7), (5,7,6) ], [ f1, f2 ] -> [ (5,7), (5,7,6) ], [ f1, f2 ] -> [ (5,6), (5,6,7) ] ] gap> iter := AllIsomorphismsIterator( G, s3 );; gap> for h in iter do Print( ImageElm( h, G.1 ) = (6,7), ", " ); od; true, false, false, true, false, false, gap> s4 := Group( (1,2),(2,3),(3,4) );; gap> AllIsomorphismsNumber( s3, s4 ); 0 gap> AllIsomorphisms( s3, s4 ); [ ] ## SubSection 7.1.2 gap> c3c3 := Group( (1,2,3), (4,5,6) );; gap> iter := AllSubgroupsIterator( c3c3 ); gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od; Group( () ) Group( [ (4,5,6) ] ) Group( [ (1,2,3) ] ) Group( [ (1,2,3)(4,5,6) ] ) Group( [ (1,3,2)(4,5,6) ] ) Group( [ (4,5,6), (1,2,3) ] ) ## Subsection 7.2.1 gap> it1 := Iterator( [ 1, 2, 3 ] );; gap> it2 := Iterator( [ 4, 5, 6 ] );; gap> iter := CartesianIterator( it1, it2 );; gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od; [ 1, 4 ] [ 1, 5 ] [ 1, 6 ] [ 2, 4 ] [ 2, 5 ] [ 2, 6 ] [ 3, 4 ] [ 3, 5 ] [ 3, 6 ] gap> ## try some trivial cases gap> iter0 := IteratorList( [ ] );; gap> iter4 := IteratorList( [ 4 ] );; gap> cart := CartesianIterator( iter0, iter0 );; gap> IsDoneIterator( cart ); true gap> cart := CartesianIterator( iter0, iter4 );; gap> IsDoneIterator( cart ); true gap> cart := CartesianIterator( iter4, iter0 );; gap> IsDoneIterator( cart ); true ## Subsection 6.2.2 gap> L := [6,7,8,9];; gap> iterL := IteratorList( L );; gap> pairsL := UnorderedPairsIterator( iterL );; gap> while not IsDoneIterator(pairsL) do Print(NextIterator(pairsL),"\n"); od; [ 6, 6 ] [ 6, 7 ] [ 7, 7 ] [ 6, 8 ] [ 7, 8 ] [ 8, 8 ] [ 6, 9 ] [ 7, 9 ] [ 8, 9 ] [ 9, 9 ] gap> iter4 := IteratorList( [ 4 ] ); gap> pairs4 := UnorderedPairsIterator(iter4); gap> NextIterator( pairs4 ); [ 4, 4 ] gap> IsDoneIterator( pairs4 ); true gap> pairs0 := UnorderedPairsIterator( iter0 );; gap> IsDoneIterator( pairs0 ); true utils-0.86/tst/groups.tst000644 000765 000024 00000021266 14621444241 020611 0ustar00christopherwensleystaff000000 000000 #@local A, a, ac9, aq8, b, c, c1, c2, c2c6, c3, c4, c4c3, c6, c9 #@local cp1, cp2, cp3, d, D12, d8, data, dp, epi, f, f1, f2, G, g #@local g1, g2, g3, genA, gens, i, idcopy, idem, idemc2, idemim, idemim2 #@local im2, image2, images, imi, info, info2, info3, lc1, lc2, lc3, lc4 #@local len, lfs, ok, Pfi, phi, q8, rc1, rc4, s3, S4, s4, UFS, ufs ############################################################################## ## #W groups.tst Utils Package ## #Y Copyright (C) 2015-2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 5.1.1 gap> Comm( [ (1,2), (2,3) ] ); (1,2,3) gap> Comm( [(1,2),(2,3),(3,4),(4,5),(5,6)] ); (1,5,6) gap> Comm(Comm(Comm(Comm((1,2),(2,3)),(3,4)),(4,5)),(5,6)); ## the same (1,5,6) ## SubSection 5.1.2 gap> D12 := DihedralGroup( 12 ); gap> SetName( D12, "D12" ); gap> a := D12.1;; b := D12.2;; gap> IsCommuting( a, b ); false ## SubSection 5.1.3 gap> ListOfPowers( 2, 20 ); [ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576 ] gap> ListOfPowers( (1,2,3)(4,5), 12 ); [ (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), (), (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), () ] gap> ListOfPowers( D12.2, 6 ); [ f2, f3, f2*f3, f3^2, f2*f3^2, of ... ] ## SubSection 5.1.4 gap> GeneratorsAndInverses( D12 ); [ f1, f2, f3, f1, f2*f3^2, f3^2 ] gap> GeneratorsAndInverses( SymmetricGroup(5) ); [ (1,2,3,4,5), (1,2), (1,5,4,3,2), (1,2) ] ## SubSection 5.1.5 gap> UFS := UpperFittingSeries( D12 );; gap> Set( GeneratorsOfGroup( UFS[2] ) ); [ f3, f2*f3 ] gap> Set( GeneratorsOfGroup( UFS[3] ) ); [ f1, f3, f2*f3 ] gap> LowerFittingSeries( D12 ); [ D12, Group([ f3 ]), Group([ ]) ] gap> FittingLength( D12 ); 2 gap> S4 := SymmetricGroup( 4 );; gap> ufs := UpperFittingSeries( S4 );; gap> List( ufs, StructureDescription ); [ "1", "C2 x C2", "A4", "S4" ] gap> lfs := LowerFittingSeries( S4 );; gap> List( lfs, StructureDescription ); [ "S4", "A4", "C2 x C2", "1" ] gap> FittingLength( S4); 3 ## SubSection 5.2.1 gap> lc1 := LeftCoset( (1,2,3), Group( [ (1,2), (3,4) ] ) ); LeftCoset((1,2,3),Group([ (1,2), (3,4) ])) gap> Representative( lc1 ); (1,2,3) gap> ActingDomain( lc1 ); Group([ (1,2), (3,4) ]) gap> AsSet( lc1 ); [ (2,3), (2,4,3), (1,2,3), (1,2,4,3) ] gap> (1,2,3) in lc1; true gap> lc2 := (2,4,3) * lc1; LeftCoset((1,2,4),Group([ (1,2), (3,4) ])) gap> lc3 := lc1^(2,3,4);; gap> lc2 = lc3; true ## SubSection 5.2.2 gap> rc1 := Inverse( lc1 ); RightCoset(Group([ (1,2), (3,4) ]),(1,3,2)) gap> rc4 := RightCoset( Group( (1,2), (2,3) ), (3,4) ); RightCoset(Group([ (1,2), (2,3) ]),(3,4)) gap> lc4 := Inverse( rc4 ); LeftCoset((3,4),Group([ (1,2), (2,3) ])) gap> Intersection( lc2, lc4 ); [ (2,3,4), (1,2,3,4) ] ## SubSection 5.3.1 gap> G := Group( (1,2,3), (3,4,5), (5,6,7), (7,8,9) );; gap> phi := EpimorphismByGenerators( FreeGroup("a","b","c","d"), G ); [ a, b, c, d ] -> [ (1,2,3), (3,4,5), (5,6,7), (7,8,9) ] gap> PreImagesRepresentativeNC( phi, (1,2,3,4,5,6,7,8,9) ); d*c*b*a gap> a := G.1;; b := G.2;; c := G.3;; d := G.4;; gap> d*c*b*a; (1,2,3,4,5,6,7,8,9) gap> ## note that it is easy to produce nonsense: gap> epi := EpimorphismByGenerators( Group((1,2,3)), Group((8,9)) ); Warning: calling GroupHomomorphismByImagesNC without checks [ (1,2,3) ] -> [ (8,9) ] gap> IsGroupHomomorphism( epi ); true gap> Image(epi,(1,2,3)); () gap> Image(epi,(1,3,2)); (8,9) ## SubSection 5.3.2 gap> s4 := Group( (1,2),(2,3),(3,4) );; gap> s3 := Group( (5,6),(6,7) );; gap> c3 := Subgroup( s3, [ (5,6,7) ] );; gap> f := GroupHomomorphismByImages( s4, s3, > [(1,2),(2,3),(3,4)], [(5,6),(6,7),(5,6)] );; gap> i := GroupHomomorphismByImages( c3, s3, [(5,6,7)], [(5,6,7)] );; gap> Pfi := Pullback( f, i ); Group([ (2,3,4)(5,7,6), (1,2)(3,4) ]) gap> StructureDescription( Pfi ); "A4" gap> info := PullbackInfo( Pfi ); rec( directProduct := Group([ (1,2), (2,3), (3,4), (5,6,7) ]), projections := [ [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (2,3,4), (1,2)(3,4) ], [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (5,7,6), () ] ] ) gap> g := (1,2,3)(5,6,7);; gap> ImageElm( info!.projections[1], g ); (1,2,3) gap> ImageElm( info!.projections[2], g ); (5,6,7) gap> dp := info!.directProduct;; gap> a := ImageElm( Embedding( dp, 1 ), (1,4,3) );; gap> b := ImageElm( Embedding( dp, 2 ), (5,7,6) );; gap> a*b in Pfi; true ## SubSection 5.3.3 gap> g1 := DihedralGroup( 8 ); gap> c1 := Centre( g1 ); Group([ f3 ]) gap> cp1 := CentralProduct( g1, g1, c1, IdentityMapping( c1 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp1 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> g2 := QuaternionGroup( 8 ); gap> c2 := Centre( g2 ); Group([ y2 ]) gap> cp2 := CentralProduct( g2, g2, c2, IdentityMapping( c2 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp2 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> info2 := CentralProductInfo( cp2 ); rec( phi := IdentityMapping( Group([ y2 ]) ), projection := [ f1, f2, f3, f4, f5, f6 ] -> [ f1, f2, f5, f3, f4, f5 ] ) gap> Source( Embedding( Source( info2.projection ), 1 ) ) = g2; true gap> g3 := SymmetricGroup( 3 ); Sym( [ 1 .. 3 ] ) gap> c3 := TrivialSubgroup( g3 ); Group(()) gap> cp3 := CentralProduct( g3, g3, c3, IdentityMapping( c3 ) ); Group([ (1,2,3), (1,2), (4,5,6), (4,5) ]) gap> info3 := CentralProductInfo( cp3 ); rec( phi := IdentityMapping( Group(()) ), projection := IdentityMapping( Group([ (1,2,3), (1,2), (4,5,6), (4,5) ]) ) ) gap> Source( Embedding( Source( info3.projection ), 1 ) ) = g3; true ## SubSection 5.3.4 gap> gens := [ (1,2,3,4), (1,2)(3,4) ];; gap> d8 := Group( gens );; gap> SetName( d8, "d8" ); gap> c2 := Subgroup( d8, [ (2,4) ] );; gap> idemc2 := IdempotentEndomorphismsWithImage( gens, c2 );; gap> idcopy := [ [ (), (2,4) ], [ (2,4), () ] ];; gap> Sort( idemc2 ); gap> Sort( idcopy ); gap> idemc2 = idcopy; true gap> ## depending on packages loaded, the order of images can vary gap> ## so we introduce a convoluted way of checking the images gap> data := IdempotentEndomorphismsData( d8 );; gap> data!.gens; [ (1,2,3,4), (1,2)(3,4) ] gap> images := data!.images;; gap> len := Length( images ); 6 gap> image2 := [ [ [ (), () ] ], [ [ (), (2,4) ], [ (2,4), () ] ], > [ [ (), (1,3) ], [ (1,3), () ] ], > [ [ (), (1,2)(3,4) ], [ (1,2)(3,4), (1,2)(3,4) ] ], > [ [ (), (1,4)(2,3) ], [ (1,4)(2,3), (1,4)(2,3) ] ], > [ [ (1,2,3,4), (1,2)(3,4) ] ] ];; gap> ok := true;; gap> ## new in gapdev - the test 'im in im2' is parsed before the for loop gap> ## so that im2 is an 'unbound global variable' if not declared first gap> im2 := [ ];; gap> for i in [1..len] do > imi := images[i]; > im2 := image2[i]; > if not ForAll( imi, im -> ( im in im2 ) ) then > ok := false; > fi; > od; gap> ok; true gap> List( images, L -> Length(L) ); [ 1, 2, 2, 2, 2, 1 ] gap> idem := IdempotentEndomorphisms( d8 );; gap> idemim := List( idem, m -> MappingGeneratorsImages(m)[2] );; gap> idemim2 := > [ [ (), () ], [ (), (2,4) ], [ (2,4), () ], [ (), (1,3) ], [ (1,3), () ], > [ (), (1,2)(3,4) ], [ (1,2)(3,4), (1,2)(3,4) ], [ (), (1,4)(2,3) ], > [ (1,4)(2,3), (1,4)(2,3) ], [ (1,2,3,4), (1,2)(3,4) ] ];; gap> ForAll( idemim, m -> ( m in idemim2 ) ); true ## SubSection 5.3.5 gap> c4 := Group( (1,2,3,4) );; gap> c2 := Group( (5,6) );; gap> f1 := GroupHomomorphismByImages( c4, c2, [(1,2,3,4)], [(5,6)] );; gap> c3 := Group( (1,2,3) );; gap> c6 := Group( (1,2,3,4,5,6) );; gap> f2 := GroupHomomorphismByImages( c3, c6, [(1,2,3)], [(1,3,5)(2,4,6)] );; gap> c4c3 := DirectProduct( c4, c3 ); Group([ (1,2,3,4), (5,6,7) ]) gap> c2c6 := DirectProduct( c2, c6 ); Group([ (1,2), (3,4,5,6,7,8) ]) gap> f := DirectProductOfFunctions( c4c3, c2c6, f1, f2 ); [ (1,2,3,4), (5,6,7) ] -> [ (1,2), (3,5,7)(4,6,8) ] gap> ImageElm( f, (1,4,3,2)(5,7,6) ); (1,2)(3,7,5)(4,8,6) ## SubSection 5.3.6 gap> c9 := Group( (1,2,3,4,5,6,7,8,9) );; gap> ac9 := AutomorphismGroup( c9 );; gap> q8 := QuaternionGroup( IsPermGroup, 8 );; gap> aq8 := AutomorphismGroup( q8 );; gap> A := DirectProductOfAutomorphismGroups( ac9, aq8 ); gap> genA := GeneratorsOfGroup( A );; gap> G := Source( genA[1] ); Group([ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13) (14,15,16,17) ]) gap> a := genA[1]*genA[5]; [ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)(14,15,16,17) ] -> [ (1,3,5,7,9,2,4,6,8), (10,16,12,14)(11,15,13,17), (10,11,12,13)(14,15,16,17) ] gap> ImageElm( a, (1,9,8,7,6,5,4,3,2)(10,14,12,16)(11,17,13,15) ); (1,8,6,4,2,9,7,5,3)(10,16,12,14)(11,15,13,17) utils-0.86/tst/loadall.g000755 000765 000024 00000001236 14621444241 020314 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W loadall.g Utils Package Chris Wensley ## #Y Copyright (C) 2015-2016, The GAP Group ## ## first make sure that, if the transferred code has not been read, ## then the appropriate packages are loaded. if not UtilsLoadingComplete then len := Length( UtilsPackageVersions ); j := 0; while ( j < len ) do j := j+1; name := UtilsPackageVersions[j]; if not OKtoReadFromUtils( name ) then LoadPackage( name ); fi; j := j+1; od; UtilsLoadingComplete := true; fi; utils-0.86/tst/download.tst000644 000765 000024 00000006232 14621444241 021075 0ustar00christopherwensleystaff000000 000000 #@local meths, i, urls, pair, url, expected, res1, good1, n, file, res2, good2, contents, r; ############################################################################ ## #W download.tst Utils Package Thomas Breuer ## #Y Copyright (C) 2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## Test the available Download methods gap> meths:= List( Filtered( Download_Methods, r -> r.isAvailable() ), > ShallowCopy );; gap> for i in [ 1 .. Length( meths ) ] do > meths[i].position:= String( i ); > od; gap> urls:= [ # a http url that gets redirected to https > [ "http://www.gap-system.org/Packages/utils.html", true ], > # a http url that works as such > [ "http://www.math.rwth-aachen.de/index.html", true ], > # a https url that exists > [ "https://www.gap-system.org/Packages/utils.html", true ], > # a https url that does not exist > [ "https://www.gap-system.org/Packages/utilsxxx.html", false ], > ];; ## The problem is that the methods do not behave consistently ## in the case of failure. ## (Well, they even do not agree what failure means.) ## The test results depend on which methods are available at runtime, ## which makes them useless as automatic tests. ## Thus we test only working http and https urls. gap> urls:= urls{ [ 2, 3 ] };; gap> for pair in urls do > url:= pair[1]; > expected:= pair[2]; > res1:= List( meths, r -> [ r.download( url, rec() ), r.position ] );; > good1:= Filtered( res1, r -> r[1].success = true );; > if expected = false and Length( good1 ) > 0 then > Print( "success for url ", url, "?\n" ); > fi; > n:= Length( Set( good1, r -> r[1].result ) ); > if n > 1 then > Print( "different results (", n, ") for url ", url, "\n" ); > fi; > file:= Filename( DirectoryTemporary(), "test" ); > res2:= List( meths, > r -> [ r.download( url, > rec( target:= Concatenation( file, r.position ) ) ), > r.position ] );; > good2:= Filtered( res2, r -> r[1].success = true );; > if expected = false and Length( good2 ) > 0 then > Print( "success for url ", url, "?\n" ); > fi; > if Length( good1 ) <> Length( good2 ) then > Print( "different success cases for url ", url, "\n" ); > fi; > if Length( good1 ) > 0 then > contents:= good1[1][1].result; > for r in good2 do > if contents <> StringFile( Concatenation( file, r[2] ) ) then > Print( "different files and contents for url ", url, "\n" ); > fi; > od; > fi; > od; ## the example 9.1.1 from the manual gap> url:= "https://www.gap-system.org/Packages/utils.html";; gap> res1:= Download( url );; gap> res1.success; true gap> IsBound( res1.result ) and IsString( res1.result ); true gap> res2:= Download( Concatenation( url, "xxx" ) );; gap> res2.success; false gap> IsBound( res2.error ) and IsString( res2.error ); true ############################################################################# ## #E utils-0.86/tst/number.tst000644 000765 000024 00000005423 14621444241 020557 0ustar00christopherwensleystaff000000 000000 #@local i, iter, n, p, sum ############################################################################## ## #W number.tst Utils Package Stefan Kohl ## #Y Copyright (C) 2015-2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 4.1.1 gap> AllSmoothIntegers( 3, 1000 ); [ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96, 108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576, 648, 729, 768, 864, 972 ] gap> AllSmoothIntegers( [5,11,17], 1000 ); [ 1, 5, 11, 17, 25, 55, 85, 121, 125, 187, 275, 289, 425, 605, 625, 935 ] gap> Length( last ); 16 gap> List( [3..20], n -> Length( AllSmoothIntegers( [5,11,17], 10^n ) ) ); [ 16, 29, 50, 78, 114, 155, 212, 282, 359, 452, 565, 691, 831, 992, 1173, 1374, 1595, 1843 ] ## SubSection 4.1.2 gap> AllProducts([1..4],3); [ 1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16, 2, 4, 6, 8, 4, 8, 12, 16, 6, 12, 18, 24, 8, 16, 24, 32, 3, 6, 9, 12, 6, 12, 18, 24, 9, 18, 27, 36, 12, 24, 36, 48, 4, 8, 12, 16, 8, 16, 24, 32, 12, 24, 36, 48, 16, 32, 48, 64 ] gap> Set(last); [ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 64 ] gap> AllProducts( [(1,2,3),(2,3,4)], 2 ); [ (2,4,3), (1,2)(3,4), (1,3)(2,4), (1,3,2) ] ## SubSection 4.1.3 gap> RestrictedPartitions( 20, [4..10] ); [ [ 4, 4, 4, 4, 4 ], [ 5, 5, 5, 5 ], [ 6, 5, 5, 4 ], [ 6, 6, 4, 4 ], [ 7, 5, 4, 4 ], [ 7, 7, 6 ], [ 8, 4, 4, 4 ], [ 8, 6, 6 ], [ 8, 7, 5 ], [ 8, 8, 4 ], [ 9, 6, 5 ], [ 9, 7, 4 ], [ 10, 5, 5 ], [ 10, 6, 4 ], [ 10, 10 ] ] gap> RestrictedPartitionsWithoutRepetitions( 20, [4..10] ); [ [ 10, 6, 4 ], [ 9, 7, 4 ], [ 9, 6, 5 ], [ 8, 7, 5 ] ] gap> RestrictedPartitionsWithoutRepetitions( 10^2, List([1..10], n->n^2 ) ); [ [ 100 ], [ 64, 36 ], [ 49, 25, 16, 9, 1 ] ] ## SubSection 4.1.4 gap> n := 2^251;; gap> NextProbablyPrimeInt( n ); 3618502788666131106986593281521497120414687020801267626233049500247285301313 ## SubSection 4.1.6 gap> iter := PrimeNumbersIterator();; gap> for i in [1..100] do p := NextIterator(iter); od; gap> p; 541 gap> sum := 0;; gap> ## "prime number race" 1 vs. 3 mod 4 gap> for p in PrimeNumbersIterator() do > if p <> 2 then sum := sum + E(4)^(p-1); fi; > if sum > 0 then break; fi; > od; gap> p; 26861 ## this final example takes quite a while: use examples/number.g ## gap> sum := 0;; ## gap> ## "prime number race" 1 vs. 5 mod 8 ## gap> for p in PrimeNumbersIterator() do ## > if p mod 8 in [1,5] then sum := sum + E(4)^((p-1)/2); fi; ## > if sum > 0 then break; fi; ## > od; ## gap> p; ## 588067889 ############################################################################# ## #E number.tst . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/tst/record.tst000644 000765 000024 00000004541 14621444241 020545 0ustar00christopherwensleystaff000000 000000 #@local r, defaults, PrintDimensions, mydim ############################################################################## ## #W record.tst Utils Package ## #Y Copyright (C) 2015-2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 8.1.1 gap> r := rec( a := 1, b := 2, c := 3 );; gap> AssignGlobals( r ); The following global variables have been assigned: [ "a", "b", "c" ] gap> [ a, b, c ]; [ 1, 2, 3 ] ## SubSection 8.2.1 gap> defaults := rec( a := 1, b := 2, c := 3 );; gap> OptionRecordWithDefaults( defaults, rec( a := 6) ); rec( a := 6, b := 2, c := 3 ) gap> OptionRecordWithDefaults( defaults, rec( b := 7, c := 8 ) ); rec( a := 1, b := 7, c := 8 ) gap> OptionRecordWithDefaults( defaults, [ ] ); rec( a := 1, b := 2, c := 3 ) gap> OptionRecordWithDefaults( defaults, [ rec( c := 8 ) ] ); rec( a := 1, b := 2, c := 8 ) gap> OptionRecordWithDefaults( defaults, rec( d := 9 ) ); Error, Unknown option: d gap> OptionRecordWithDefaults( defaults, [ rec( b := 7 ), rec( c := 8 ) ] ); Error, Too many arguments for function gap> OptionRecordWithDefaults( defaults, 5 ); Error, Options should be a record gap> OptionRecordWithDefaults( defaults, [6,7,8] ); Error, Too many arguments for function gap> PrintDimensions := function( arg ) > local nargs, dim, order, V, L, len, K, i; > nargs := Length( arg ); > dim := [ arg[1]!.height, arg[1]!.width, arg[1]!.depth ]; > order := rec( h := 1, w := 2, d := 3 ); > V := [ "height", "width", "depth" ]; > if ( nargs > 1 ) and IsRecord( arg[2] ) then > order := OptionRecordWithDefaults( order, arg[2] ); > fi; > L := [ order!.h, order!.w, order!.d ]; > len := Length( L ); > K := [ 1..len ]; > SortParallel( L, K ); > Print( "dimensions: " ); > Print( V[K[1]], " = ", dim[K[1]], ", " ); > Print( V[K[2]], " = ", dim[K[2]], ", " ); > Print( V[K[3]], " = ", dim[K[3]], "\n" ); > end;; gap> mydim := rec( height := 45, width := 31, depth := 17 ); rec( depth := 17, height := 45, width := 31 ) gap> PrintDimensions( mydim ); dimensions: height = 45, width = 31, depth = 17 gap> PrintDimensions( mydim, rec( h:=3, w:=1, d:=2 ) ); dimensions: width = 31, depth = 17, height = 45 utils-0.86/tst/matrix.tst000644 000765 000024 00000005130 14621444241 020566 0ustar00christopherwensleystaff000000 000000 #@local M6, L6, M4, L4, M8, L8, L, A, M3, L3, M5, L5; ############################################################################## ## #W matrix.tst Utils Package ## #Y Copyright (C) 2015-2023, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 9.1.1 gap> M6 := [ [1,2,0,0,0,0], [3,4,0,0,0,0], [5,6,0,0,0,0], > [0,0,9,0,0,0], [0,0,0,1,2,3], [0,0,0,4,5,6] ];; gap> Display( M6 ); [ [ 1, 2, 0, 0, 0, 0 ], [ 3, 4, 0, 0, 0, 0 ], [ 5, 6, 0, 0, 0, 0 ], [ 0, 0, 9, 0, 0, 0 ], [ 0, 0, 0, 1, 2, 3 ], [ 0, 0, 0, 4, 5, 6 ] ] gap> L6 := DirectSumDecompositionMatrices( M6 ); [ [ [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ], [ [ 9 ] ], [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] ] ] gap> M4 := [ [0,3,0,0], [0,0,0,0], [0,0,0,0], [0,0,4,0] ];; gap> Display( M4 ); [ [ 0, 3, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 4, 0 ] ] gap> L4 := DirectSumDecompositionMatrices( M4 ); [ [ [ [ 0, 3 ] ], [ [ 0, 0 ], [ 0, 0 ], [ 4, 0 ] ] ], [ [ [ 0, 3 ], [ 0, 0 ] ], [ [ 0, 0 ], [ 4, 0 ] ] ], [ [ [ 0, 3 ], [ 0, 0 ], [ 0, 0 ] ], [ [ 4, 0 ] ] ] ] gap> for L in L4 do > A := DirectSumMat( L );; > if ( A = M4 ) then Print( "yes, A = M4\n" ); fi; > od; yes, A = M4 yes, A = M4 yes, A = M4 gap> M8 := DirectSumMat( M4, M4 );; gap> Display( M8 ); [ [ 0, 3, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 4, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 3, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 4, 0 ] ] gap> L8 := DirectSumDecompositionMatrices( M8 );; gap> Length( L8 ); 16 gap> M3 := [ [0,0,0,7,0,0,0], [0,0,0,0,8,0,0], [0,0,0,0,0,9,0] ];; gap> Display( M3 ); [ [ 0, 0, 0, 7, 0, 0, 0 ], [ 0, 0, 0, 0, 8, 0, 0 ], [ 0, 0, 0, 0, 0, 9, 0 ] ] gap> L3 := DirectSumDecompositionMatrices( M3 ); [ [ [ [ 0, 0, 0, 7 ] ], [ [ 8 ] ], [ [ 9, 0 ] ] ] ] gap> M5 := [ [1,2,0,0,0], [3,4,0,0,0], [0,0,0,0,0], > [0,0,0,6,7], [0,0,0,8,9] ];; gap> Display(M5); [ [ 1, 2, 0, 0, 0 ], [ 3, 4, 0, 0, 0 ], [ 0, 0, 0, 0, 0 ], [ 0, 0, 0, 6, 7 ], [ 0, 0, 0, 8, 9 ] ] gap> L5 := DirectSumDecompositionMatrices( M5 ); [ [ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 0 ] ], [ [ 6, 7 ], [ 8, 9 ] ] ] ] ############################################################################# ## #E matrix.tst . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/tst/testall.g000755 000765 000024 00000001145 14621444241 020353 0ustar00christopherwensleystaff000000 000000 ############################################################################ ## #W testall.g Utils Package Chris Wensley ## #Y Copyright (C) 2015-2023, The GAP Group ## LoadPackage( "utils" ); ## first make sure that, if the transferred code has not been read, ## then the appropriate packages are loaded. if not UtilsLoadingComplete then ReadPackage( "utils", "tst/loadall.g" ); fi; dir := DirectoriesPackageLibrary( "utils", "tst" ); TestDirectory(dir, rec(exitGAP := true, testOptions:=rec(compareFunction := "uptowhitespace"))); FORCE_QUIT_GAP(1); utils-0.86/tst/others.tst000644 000765 000024 00000003546 14621444241 020577 0ustar00christopherwensleystaff000000 000000 #@local M, s1, n1, n2, N, s2; ############################################################################ ## #W others.tst Utils Package ## #Y Copyright (C) 2015-2022, The GAP Group ## gap> ReadPackage( "utils", "tst/loadall.g" );; gap> UtilsLoadingComplete; true ## SubSection 10.1.1 ## this manual example is not tested to avoid creating files triv.* ## gap> LogTo( "triv.log" ); ## gap> a := 33^5; ## 39135393 ## gap> LogTo(); ## gap> Log2HTML( "triv.log" ); ## SubSection 10.2.1 gap> IntOrInfinityToLaTeX( 10^3 ); "1000" gap> IntOrInfinityToLaTeX( infinity ); "\\infty" ## SubSection 10.2.2 gap> LaTeXStringFactorsInt( Factorial(12) ); "2^{10} \\cdot 3^5 \\cdot 5^2 \\cdot 7 \\cdot 11" ## SubSection 10.3.1 gap> ConvertToMagmaInputString( Group( (1,2,3,4,5), (3,4,5) ) ); "PermutationGroup<5|(1,2,3,4,5),\n(3,4,5)>;\n" gap> ConvertToMagmaInputString( Group( (1,2,3,4,5) ), "c5" ); "c5 := PermutationGroup<5|(1,2,3,4,5)>;\n" gap> ConvertToMagmaInputString( DihedralGroup( IsPcGroup, 10 ) ); "PolycyclicGroup< f1,f2 |\nf1^2,\nf2^5,\nf2^f1 = f2^4\n>;\n" gap> M := GL(2,5);; Size(M); 480 gap> s1 := ConvertToMagmaInputString( M ); "F := GF(5);\nP := GL(2,F);\ngens := [\nP![2,0,0,1],\nP![4,1,4,0]\n];\nsub

;\n" gap> Print( s1 ); F := GF(5); P := GL(2,F); gens := [ P![2,0,0,1], P![4,1,4,0] ]; sub

; gap> n1 := [ [ Z(9)^0, Z(9)^0 ], [ Z(9)^0, Z(9) ] ];; gap> n2 := [ [ Z(9)^0, Z(9)^3 ], [ Z(9)^4, Z(9)^2 ] ];; gap> N := Group( n1, n2 );; Size( N ); 5760 gap> s2 := ConvertToMagmaInputString( N, "gpN" );; gap> Print( s2 ); F := GF(3^2); P := GL(2,F); w := PrimitiveElement(F); gens := [ P![ 1, 1, 1,w^1], P![ 1,w^3, 2,w^2] ]; gpN := sub

; ############################################################################# ## #E others.tst . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/tst/lcset.tst000644 000765 000024 00000012266 14621444241 020404 0ustar00christopherwensleystaff000000 000000 #@local a, b, d, f, g, h, H1, H2, H3, K1, K2, K3, lc1, lc4, M, matcyc, rc5, s ############################################################################# ## adapted from gapdev/tst/tstinstall/cset.tst for left cosets ## ## test of group intersection and LeftCoset ## gap> START_TEST("lcset.tst"); # basic coset tests gap> LeftCoset( (1,2), Group([(1,2,3),(2,3,4)]) ) > = LeftCoset( (2,3), Group([(1,2,3),(2,3,4)]) ); true gap> () in LeftCoset( (1,2), Group([(1,2,3,4)]) ); false gap> (1,2) in LeftCoset( (5,6), SymmetricGroup(12) ); true gap> Length( LeftCosets( SymmetricGroup(5), AlternatingGroup(4) ) ); 10 gap> (1,2,3) * LeftCoset( (), AlternatingGroup(4) ) > = LeftCoset( (), AlternatingGroup(4) ); true gap> IsBiCoset( LeftCoset( (1,2), AlternatingGroup(6) ) ); true gap> IsBiCoset( LeftCoset( (1,7), AlternatingGroup(6) ) ); false gap> IsLeftCoset( LeftCoset( (1,2,3), MathieuGroup(12) ) ); true # test intersecting permutation cosets gap> H1 := Group( [ (), (2,7,6)(3,4,5), (1,2,7,5,6,4,3) ] );; gap> H2 := Group( [ (1,2,3,4,5,6,7), (5,6,7) ] );; gap> H3 := Group( [ (1,2,3,4,5,6,8), (1,3,2,6,4,5), (1,6)(2,3)(4,5)(7,8) ] );; gap> AsSet( LeftCoset( (1,5,7,3)(4,6), H1 ) ) = > Intersection( LeftCoset( (3,6)(4,7), H2 ), > LeftCoset( (1,5,3,8,6,7), H3 ) ); true gap> AsSet( LeftCoset( (1,2,5,6,7,4,3,8), Group(()) ) ) = > Intersection( LeftCoset( (1,5,6,7)(3,8,4), > Group( [ (1,4)(2,5), (1,3,5)(2,4,6), (1,5)(2,4)(3,6) ] ) ), > LeftCoset( (1,2,6,8)(3,7), > Group( [ (3,4), (5,6,7,8), (5,6) ] ) ) ); true gap> [] = Intersection( LeftCoset( (), SymmetricGroup(4) ), > LeftCoset( (4,7), SymmetricGroup([3..6]) ) ); true gap> [] = Intersection( LeftCoset( (4,5), Group( [ (1,2,3,4,5) ] ) ), > LeftCoset( (), AlternatingGroup(4) ) ); true gap> AsSet( LeftCoset( (7,9), SymmetricGroup([3..5]) ) ) = > Intersection( LeftCoset( (1,2)(7,9), SymmetricGroup(5) ), > LeftCoset( (7,9), SymmetricGroup([3..7]) ) ); true gap> [] = Intersection( LeftCoset( (1,4)(3,5), Group([(1,2,3,4,5)]) ), > LeftCoset( (), SymmetricGroup(3) ) ); true gap> AsSet( LeftCoset( (4,5), Group( [(5,6)] ) ) ) = > Intersection( LeftCoset( (), SymmetricGroup(6) ), > LeftCoset( (4,5), SymmetricGroup([5..8]) ) ); true gap> AsSet( LeftCoset( (1,4,5), SymmetricGroup(5) ) ) = > Intersection( LeftCoset( (), SymmetricGroup(5) ), > LeftCoset( (1,2), SymmetricGroup(5) ) ); true gap> [] = > Intersection( LeftCoset( (1,2), Group( (1,2,3,4,5) ) ), > LeftCoset( (), Group( (1,2,3,5,4) ) ) ); true gap> [] = > Intersection( LeftCoset( (1,2,3), Group( (1,2,3,4,5) ) ), > LeftCoset( (), Group( (1,2,3,5,4) ) ) ); true gap> AsSet( LeftCoset( (1,2), Group( [ (1,2,3,5,4) ] ) ) ) = > Intersection( LeftCoset( (), SymmetricGroup(7) ), > LeftCoset( (1,2), Group( (1,2,3,5,4) ) ) ); true gap> [] = > Intersection( LeftCoset( (), SymmetricGroup([3..7]) ), > LeftCoset( (1,2), Group( (1,2,3,5,4) ) ) ); true # test trivial cases gap> Intersection( LeftCoset( (), Group([],()) ), > LeftCoset( (1,2), Group([],()) ) ) = []; true gap> Intersection( LeftCoset( (), Group( (1,2,3) ) ), > LeftCoset( (1,2), Group( (1,2,3) ) ) ) = []; true gap> Intersection( LeftCoset( (), AlternatingGroup(6) ), > LeftCoset( (1,2), AlternatingGroup(6) ) ) = []; true gap> Intersection( LeftCoset( (1,2), AlternatingGroup([1..5]) ), > LeftCoset( (1,2), AlternatingGroup([6..10]) ) ) > = AsSet( LeftCoset( (1,2), Group(()) ) ); true #coset of pc-group gap> d := DihedralGroup( 24 ); gap> List( GeneratorsOfGroup(d), x -> Order(x) ); [ 2, 12, 6, 3 ] gap> s := Subgroup( d, [ d.1, d.4 ] );; gap> SetName( s, "s" ); gap> lc4 := LeftCoset( d.2, s ); LeftCoset(,s) gap> AsSet( lc4 ); [ f2, f2*f4, f1*f2*f3, f2*f4^2, f1*f2*f3*f4, f1*f2*f3*f4^2 ] gap> d.2 * d.4 in lc4; true # coset of fp-group gap> f := FreeGroup(2);; a := f.1;; b := f.2;; gap> g := f / [ a^5, b^4, a*b*a^2*b^3 ]; gap> Size(g); 20 gap> h := Subgroup( g, [g.1] );; gap> SetName( h, "C5" ); gap> rc5 := LeftCoset( g.2, h ); LeftCoset(,C5) gap> AsSet( rc5 ); [ f2, f2*f1, f2*f1^2, f2*f1^3, f2*f1^4 ] # test intersection non-permutation cosets gap> K1 := Group( [ [[-1,0],[0,-1]] ] );; gap> K2 := Group( [ [[-1,0],[0,1]], [[0,1],[1,0]] ] );; gap> K3 := Group( [ - IdentityMat(2) ] );; gap> AsSet( LeftCoset( [ [0,1],[1,0] ], K1 ) ) = > Intersection( LeftCoset( IdentityMat(2), K2 ), > LeftCoset( [[0,1],[1,0]], K1 ) ); true gap> AsSet( LeftCoset( [[0,1],[1,0]], K3 ) ) = > Intersection( LeftCoset( [[0,-1],[-1,0]], K3 ), > LeftCoset( [[0,1],[1,0]], K3 ) ); true gap> matcyc := CyclicGroup( IsMatrixGroup, GF(3), 4 );; gap> M := GeneratorsOfGroup( matcyc )[1];; gap> lc1 := LeftCoset( M^2, matcyc );; gap> Representative(lc1); [ [ 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3) ], [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0 ], [ Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3) ], [ 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3) ] ] # gap> STOP_TEST("lcset.tst", 1); utils-0.86/doc/chap9_mj.html000644 000765 000024 00000022604 14621610515 021045 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 9: Web Downloads
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

9 Web Downloads

The Download operation has been written by Thomas Breuer, incorporating a number of suggestions from Max Horn, for version 0.77 of Utils. It implements downloading a file from within GAP. It can use the IO or curlInterface packages, or wget or curl, if installed, and it can be extended with other download methods quite easily. It is envisaged that, once other packages have started to use it, and any problems have been addressed, that the functions will be transferred to the main GAP library.

9.1 Functions for downloading files from the web

9.1-1 Download
‣ Download( url[, opt] )( function )

This function downloads the file with the web address url, which must be a string.

The result is a record which has at least the component success, with value true if the download was successful and false otherwise. In the former case, the component result is bound, whose value is a string that contains the contents of the downloaded file. In the latter case, the component error is bound, whose value is a string that describes the problem.

The function calls the methods stored in the global list Download_Methods until one of them is successful. Currently there are methods based on the GAP functions DownloadURL (curl: DownloadURL) and SingleHTTPRequest (IO: SingleHTTPRequest), and methods based on the external programs wget and curl.

An optional record opt can be given. The following components are supported.

target

If this component is bound then its value must be a string that is a local filename, and the function writes the downloaded contents to this file; the returned record does not have a result component in this case.

verifyCert

If this component is bound and has the value false then those download methods that are based on curl or wget will omit the check of the server's certificate. The same effect is achieved for all Download calls by setting the user preference DownloadVerifyCertificate (see 9.1-2) to false and omitting the verifyCert component from opt.


gap> url:= "https://www.gap-system.org/Packages/utils.html";;
gap> res1:= Download( url );;
gap> res1.success;
true
gap> IsBound( res1.result ) and IsString( res1.result );
true
gap> res2:= Download( Concatenation( url, "xxx" ) );;
gap> res2.success;
false
gap> IsBound( res2.error ) and IsString( res2.error );
true

9.1-2 User preference DownloadVerifyCertificate

The value true (the default) means that the server's certificate is checked in calls of Download (9.1-1), such that nothing gets downloaded if the certificate is invalid.

If the value is false then download methods are supposed to omit the check of the server's certificate (this may not be supported by all download methods).

One can set the value of the preference to be val via SetUserPreference (Reference: SetUserPreference), by calling SetUserPreference( "utils", "DownloadVerifyCertificate", val ), and access the current value via UserPreference (Reference: UserPreference), by calling UserPreference( "utils", "DownloadVerifyCertificate" ).

We recommend leaving this preference at its default value true. Sometimes it can be necessary to change it, e.g. to work around issues with old operating systems which may not be able to correctly verify new certificates. In general it is better to update such a system, but if that is not an option, then disabling certificate checks may be a good last resort.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/manual.six000644 000765 000024 00000035615 14621610514 020474 0ustar00christopherwensleystaff000000 000000 #SIXFORMAT GapDocGAP HELPBOOKINFOSIXTMP := rec( encoding := "UTF-8", bookname := "Utils", entries := [ [ "Title page", "0.0", [ 0, 0, 0 ], 1, 1, "title page", "X7D2C85EC87DD46E5" ], [ "Abstract", "0.0-1", [ 0, 0, 1 ], 64, 2, "abstract", "X7AA6C5737B711C89" ] , [ "Copyright", "0.0-2", [ 0, 0, 2 ], 82, 2, "copyright", "X81488B807F2A1CF1" ], [ "Acknowledgements", "0.0-3", [ 0, 0, 3 ], 92, 2, "acknowledgements", "X82A988D47DFAFCFA" ], [ "Table of Contents", "0.0-4", [ 0, 0, 4 ], 101, 3, "table of contents", "X8537FEB07AF2BEC8" ], [ "\033[1X\033[33X\033[0;-2YIntroduction\033[133X\033[101X", "1", [ 1, 0, 0 ], 1, 5, "introduction", "X7DFB63A97E67C0A1" ], [ "\033[1X\033[33X\033[0;-2YInformation for package authors\033[133X\033[101X\ ", "1.1", [ 1, 1, 0 ], 71, 6, "information for package authors", "X8508AD637B79CEE8" ], [ "\033[1X\033[33X\033[0;-2YPrinting Lists and Iterators\033[133X\033[101X", "2", [ 2, 0, 0 ], 1, 7, "printing lists and iterators", "X83686EE47E4D4F66" ], [ "\033[1X\033[33X\033[0;-2YPrinting selected items\033[133X\033[101X", "2.1", [ 2, 1, 0 ], 4, 7, "printing selected items", "X7F6817927F86240F" ], [ "\033[1X\033[33X\033[0;-2YLists, Sets and Strings\033[133X\033[101X", "3", [ 3, 0, 0 ], 1, 9, "lists sets and strings", "X7AE6EFC086C0EB3C" ], [ "\033[1X\033[33X\033[0;-2YFunctions for lists\033[133X\033[101X", "3.1", [ 3, 1, 0 ], 4, 9, "functions for lists", "X7C3F1E7D878AAA65" ], [ "\033[1X\033[33X\033[0;-2YDistinct and Common Representatives\033[133X\033[\ 101X", "3.2", [ 3, 2, 0 ], 117, 11, "distinct and common representatives", "X82F443FF84B8FCE3" ], [ "\033[1X\033[33X\033[0;-2YFunctions for strings\033[133X\033[101X", "3.3", [ 3, 3, 0 ], 169, 12, "functions for strings", "X8033A2FE80FC2F2A" ], [ "\033[1X\033[33X\033[0;-2YNumber-theoretic functions\033[133X\033[101X", "4", [ 4, 0, 0 ], 1, 13, "number-theoretic functions", "X86E71C1687F2D0AD" ], [ "\033[1X\033[33X\033[0;-2YFunctions for integers\033[133X\033[101X", "4.1", [ 4, 1, 0 ], 4, 13, "functions for integers", "X7D33B5B17BF785CA" ], [ "\033[1X\033[33X\033[0;-2YGroups and homomorphisms\033[133X\033[101X", "5", [ 5, 0, 0 ], 1, 16, "groups and homomorphisms", "X8171DAF2833FF728" ], [ "\033[1X\033[33X\033[0;-2YFunctions for groups\033[133X\033[101X", "5.1", [ 5, 1, 0 ], 4, 16, "functions for groups", "X7E21E6D285E6B12C" ], [ "\033[1X\033[33X\033[0;-2YLeft Cosets for Groups\033[133X\033[101X", "5.2", [ 5, 2, 0 ], 120, 18, "left cosets for groups", "X7FE4848B7DE6B3FD" ], [ "\033[1X\033[33X\033[0;-2YInverse\033[133X\033[101X", "5.2-2", [ 5, 2, 2 ], 164, 19, "inverse", "X793E48267EF5FD77" ], [ "\033[1X\033[33X\033[0;-2YFunctions for group homomorphisms\033[133X\033[10\ 1X", "5.3", [ 5, 3, 0 ], 184, 19, "functions for group homomorphisms", "X80A512877F515DE7" ], [ "\033[1X\033[33X\033[0;-2YMatrices\033[133X\033[101X", "6", [ 6, 0, 0 ], 1, 24, "matrices", "X812CCAB278643A59" ], [ "\033[1X\033[33X\033[0;-2YSome operations for matrices\033[133X\033[101X", "6.1", [ 6, 1, 0 ], 4, 24, "some operations for matrices", "X802118FB7C94D6BA" ], [ "\033[1X\033[33X\033[0;-2YIterators\033[133X\033[101X", "7", [ 7, 0, 0 ], 1, 26, "iterators", "X85A3F00985453F95" ], [ "\033[1X\033[33X\033[0;-2YSome iterators for groups and their isomorphisms\\ 033[133X\033[101X", "7.1", [ 7, 1, 0 ], 4, 26, "some iterators for groups and their isomorphisms", "X7BB5350081B27D17" ], [ "\033[1X\033[33X\033[0;-2YOperations on iterators\033[133X\033[101X", "7.2", [ 7, 2, 0 ], 72, 27, "operations on iterators", "X85413EED812C6497" ], [ "\033[1X\033[33X\033[0;-2YRecords\033[133X\033[101X", "8", [ 8, 0, 0 ], 1, 29, "records", "X7AA1073C7E943DD7" ], [ "\033[1X\033[33X\033[0;-2YFunctions for records\033[133X\033[101X", "8.1", [ 8, 1, 0 ], 4, 29, "functions for records", "X82B3D1D583CDF0E5" ], [ "\033[1X\033[33X\033[0;-2YOption records for functions\033[133X\033[101X", "8.2", [ 8, 2, 0 ], 27, 29, "option records for functions", "X7E6207B47B9AA30C" ], [ "\033[1X\033[33X\033[0;-2YWeb Downloads\033[133X\033[101X", "9", [ 9, 0, 0 ], 1, 32, "web downloads", "X815B0C4B7EBE6E1E" ], [ "\033[1X\033[33X\033[0;-2YFunctions for downloading files from the web\033[\ 133X\033[101X", "9.1", [ 9, 1, 0 ], 12, 32, "functions for downloading files from the web", "X8758CB7F79EFB6ED" ], [ "\033[1X\033[33X\033[0;-2YUser preference \033[10XDownloadVerifyCertificat\ e\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "9.1-2", [ 9, 1, 2 ], 65, 33, "user preference downloadverifycertificate", "X85182BA486E3C2AA" ], [ "\033[1X\033[33X\033[0;-2YVarious other functions\033[133X\033[101X", "10", [ 10, 0, 0 ], 1, 34, "various other functions", "X83EFC3178180D918" ], [ "\033[1X\033[33X\033[0;-2YFile operations\033[133X\033[101X", "10.1", [ 10, 1, 0 ], 4, 34, "file operations", "X81A0A4FF842B039B" ], [ "\033[1X\033[33X\033[0;-2YLaTeX strings\033[133X\033[101X", "10.2", [ 10, 2, 0 ], 29, 34, "latex strings", "X84D2922D87EDE9E9" ], [ "\033[1X\033[33X\033[0;-2YConversion to \033[22XMagma\033[122X\033[101X\\ 027\033[1X\027 string\033[133X\033[101X", "10.3", [ 10, 3, 0 ], 65, 35, "conversion to magma string", "X7BDFFBC379DE83E6" ], [ "\033[1X\033[33X\033[0;-2YObsolete functions\033[133X\033[101X", "11", [ 11, 0, 0 ], 1, 37, "obsolete functions", "X7F561B1D803182FF" ], [ "\033[1X\033[33X\033[0;-2YOperations from AutoDoc\033[133X\033[101X", "11.1", [ 11, 1, 0 ], 4, 37, "operations from autodoc", "X7A6BB3D084912F35" ], [ "\033[1X\033[33X\033[0;-2YFunctions for printing\033[133X\033[101X", "11.2", [ 11, 2, 0 ], 21, 37, "functions for printing", "X86F322FC7DECE36F" ], [ "\033[1X\033[33X\033[0;-2YOther obsolete functions\033[133X\033[101X", "11.3", [ 11, 3, 0 ], 49, 38, "other obsolete functions", "X84A4F0B281FA0F94" ], [ "\033[1X\033[33X\033[0;-2YApplicable Methods\033[133X\033[101X", "11.3-1", [ 11, 3, 1 ], 52, 38, "applicable methods", "X78B7D1A982BE9866" ], [ "\033[1X\033[33X\033[0;-2YExponentOfPrime\033[133X\033[101X", "11.3-2", [ 11, 3, 2 ], 85, 38, "exponentofprime", "X7C1AF2467FB55D79" ], [ "\033[1X\033[33X\033[0;-2YThe transfer procedure\033[133X\033[101X", "12", [ 12, 0, 0 ], 1, 39, "the transfer procedure", "X84AC9613842F014C" ], [ "Bibliography", "bib", [ "Bib", 0, 0 ], 1, 41, "bibliography", "X7A6F98FD85F02BFE" ], [ "References", "bib", [ "Bib", 0, 0 ], 1, 41, "references", "X7A6F98FD85F02BFE" ], [ "Index", "ind", [ "Ind", 0, 0 ], 1, 42, "index", "X83A0356F839C696F" ], [ "GitHub repository", "1.0", [ 1, 0, 0 ], 1, 5, "github repository", "X7DFB63A97E67C0A1" ], [ "\033[2XPrintSelection\033[102X", "2.1-1", [ 2, 1, 1 ], 14, 7, "printselection", "X7997C991826D0191" ], [ "\033[2XPrintSelection\033[102X", "2.1-1", [ 2, 1, 1 ], 14, 7, "printselection", "X7997C991826D0191" ], [ "\033[2XDifferencesList\033[102X", "3.1-1", [ 3, 1, 1 ], 7, 9, "differenceslist", "X78B7C92681D2F13C" ], [ "\033[2XQuotientsList\033[102X", "3.1-2", [ 3, 1, 2 ], 29, 9, "quotientslist", "X7975371E865B89BC" ], [ "\033[2XFloatQuotientsList\033[102X", "3.1-2", [ 3, 1, 2 ], 29, 9, "floatquotientslist", "X7975371E865B89BC" ], [ "\033[2XSearchCycle\033[102X", "3.1-3", [ 3, 1, 3 ], 59, 10, "searchcycle", "X86096E73858CFABD" ], [ "\033[2XRandomCombination\033[102X", "3.1-4", [ 3, 1, 4 ], 101, 11, "randomcombination", "X7EF06CAD7F35245D" ], [ "distinct and common representatives", "3.2", [ 3, 2, 0 ], 117, 11, "distinct and common representatives", "X82F443FF84B8FCE3" ], [ "\033[2XDistinctRepresentatives\033[102X", "3.2-1", [ 3, 2, 1 ], 120, 11, "distinctrepresentatives", "X78105CAA847A888C" ], [ "\033[2XCommonRepresentatives\033[102X", "3.2-1", [ 3, 2, 1 ], 120, 11, "commonrepresentatives", "X78105CAA847A888C" ], [ "\033[2XCommonTransversal\033[102X", "3.2-1", [ 3, 2, 1 ], 120, 11, "commontransversal", "X78105CAA847A888C" ], [ "\033[2XIsCommonTransversal\033[102X", "3.2-1", [ 3, 2, 1 ], 120, 11, "iscommontransversal", "X78105CAA847A888C" ], [ "\033[2XBlankFreeString\033[102X", "3.3-1", [ 3, 3, 1 ], 172, 12, "blankfreestring", "X870C964E7804B266" ], [ "\033[2XAllSmoothIntegers\033[102X", "4.1-1", [ 4, 1, 1 ], 7, 13, "allsmoothintegers", "X802064F37D50F46A" ], [ "\033[2XAllSmoothIntegers\033[102X", "4.1-1", [ 4, 1, 1 ], 7, 13, "allsmoothintegers", "X802064F37D50F46A" ], [ "smooth integer", "4.1-1", [ 4, 1, 1 ], 7, 13, "smooth integer", "X802064F37D50F46A" ], [ "\033[2XAllProducts\033[102X", "4.1-2", [ 4, 1, 2 ], 37, 13, "allproducts", "X78BE6B8B878D250D" ], [ "\033[2XRestrictedPartitionsWithoutRepetitions\033[102X", "4.1-3", [ 4, 1, 3 ], 61, 14, "restrictedpartitionswithoutrepetitions", "X845F46E579CEA43F" ], [ "\033[2XNextProbablyPrimeInt\033[102X", "4.1-4", [ 4, 1, 4 ], 85, 14, "nextprobablyprimeint", "X81708BF4858505E8" ], [ "\033[2XPrimeNumbersIterator\033[102X", "4.1-5", [ 4, 1, 5 ], 111, 15, "primenumbersiterator", "X8021EEE5787FCA37" ], [ "\033[2XComm\033[102X", "5.1-1", [ 5, 1, 1 ], 7, 16, "comm", "X80761843831B468E" ], [ "\033[2XIsCommuting\033[102X", "5.1-2", [ 5, 1, 2 ], 27, 16, "iscommuting", "X803A050C7A183CCC" ], [ "\033[2XListOfPowers\033[102X", "5.1-3", [ 5, 1, 3 ], 46, 17, "listofpowers", "X87A8F01286548037" ], [ "\033[2XGeneratorsAndInverses\033[102X", "5.1-4", [ 5, 1, 4 ], 68, 17, "generatorsandinverses", "X820B71307E41BEE5" ], [ "\033[2XUpperFittingSeries\033[102X", "5.1-5", [ 5, 1, 5 ], 86, 17, "upperfittingseries", "X84CF95227F9D562F" ], [ "\033[2XLowerFittingSeries\033[102X", "5.1-5", [ 5, 1, 5 ], 86, 17, "lowerfittingseries", "X84CF95227F9D562F" ], [ "\033[2XFittingLength\033[102X", "5.1-5", [ 5, 1, 5 ], 86, 17, "fittinglength", "X84CF95227F9D562F" ], [ "Fitting series", "5.1-5", [ 5, 1, 5 ], 86, 17, "fitting series", "X84CF95227F9D562F" ], [ "\033[2XLeftCoset\033[102X", "5.2-1", [ 5, 2, 1 ], 123, 18, "leftcoset", "X8340B4537F17DCD3" ], [ "\033[2XEpimorphismByGenerators\033[102X", "5.3-1", [ 5, 3, 1 ], 187, 19, "epimorphismbygenerators", "X80C9A0B583FEA7B9" ], [ "\033[2XPullback\033[102X", "5.3-2", [ 5, 3, 2 ], 221, 20, "pullback", "X7C705F2A79F8E43C" ], [ "\033[2XPullbackInfo\033[102X", "5.3-2", [ 5, 3, 2 ], 221, 20, "pullbackinfo", "X7C705F2A79F8E43C" ], [ "\033[2XCentralProduct\033[102X", "5.3-3", [ 5, 3, 3 ], 272, 20, "centralproduct", "X78DD2C617B992BE2" ], [ "\033[2XCentralProductInfo\033[102X", "5.3-3", [ 5, 3, 3 ], 272, 20, "centralproductinfo", "X78DD2C617B992BE2" ], [ "\033[2XIdempotentEndomorphisms\033[102X", "5.3-4", [ 5, 3, 4 ], 323, 21, "idempotentendomorphisms", "X801038CB808FC956" ], [ "\033[2XIdempotentEndomorphismsData\033[102X", "5.3-4", [ 5, 3, 4 ], 323, 21, "idempotentendomorphismsdata", "X801038CB808FC956" ], [ "\033[2XIdempotentEndomorphismsWithImage\033[102X", "5.3-4", [ 5, 3, 4 ], 323, 21, "idempotentendomorphismswithimage", "X801038CB808FC956" ], [ "\033[2XDirectProductOfFunctions\033[102X", "5.3-5", [ 5, 3, 5 ], 391, 22, "directproductoffunctions", "X81FA9E6C7F3B9238" ], [ "\033[2XDirectProductOfAutomorphismGroups\033[102X", "5.3-6", [ 5, 3, 6 ], 418, 23, "directproductofautomorphismgroups", "X7CB2D5F27F4182AF" ], [ "\033[2XDirectSumDecompositionMatrices\033[102X", "6.1-1", [ 6, 1, 1 ], 7, 24, "directsumdecompositionmatrices", "X787B89237E1398B6" ], [ "Iterators", "7.1", [ 7, 1, 0 ], 4, 26, "iterators", "X7BB5350081B27D17" ] , [ "\033[2XAllIsomorphismsIterator\033[102X", "7.1-1", [ 7, 1, 1 ], 11, 26, "allisomorphismsiterator", "X7F8B54D1806C762D" ], [ "\033[2XAllIsomorphismsNumber\033[102X", "7.1-1", [ 7, 1, 1 ], 11, 26, "allisomorphismsnumber", "X7F8B54D1806C762D" ], [ "\033[2XAllIsomorphisms\033[102X", "7.1-1", [ 7, 1, 1 ], 11, 26, "allisomorphisms", "X7F8B54D1806C762D" ], [ "\033[2XAllSubgroupsIterator\033[102X", "7.1-2", [ 7, 1, 2 ], 46, 27, "allsubgroupsiterator", "X831DA5AE8437578F" ], [ "\033[2XCartesianIterator\033[102X", "7.2-1", [ 7, 2, 1 ], 80, 27, "cartesianiterator", "X87395A9181A35301" ], [ "\033[2XUnorderedPairsIterator\033[102X", "7.2-2", [ 7, 2, 2 ], 105, 28, "unorderedpairsiterator", "X7C95E27987A812EA" ], [ "\033[2XAssignGlobals\033[102X", "8.1-1", [ 8, 1, 1 ], 7, 29, "assignglobals", "X84D82EB579B2ACCD" ], [ "\033[2XOptionRecordWithDefaults\033[102X", "8.2-1", [ 8, 2, 1 ], 30, 29, "optionrecordwithdefaults", "X8322B9377CC590D2" ], [ "\033[2XDownload\033[102X", "9.1-1", [ 9, 1, 1 ], 15, 32, "download", "X7A7438AE8448635E" ], [ "\033[10XDownloadVerifyCertificate\033[110X", "9.1-2", [ 9, 1, 2 ], 65, 33, "downloadverifycertificate", "X85182BA486E3C2AA" ], [ "\033[2XLog2HTML\033[102X", "10.1-1", [ 10, 1, 1 ], 7, 34, "log2html", "X7B7ECADF85F748BE" ], [ "\033[2XIntOrOnfinityToLaTeX\033[102X", "10.2-1", [ 10, 2, 1 ], 32, 34, "intoronfinitytolatex", "X87DEB2B58266F858" ], [ "\033[2XLaTeXStringFactorsInt\033[102X", "10.2-2", [ 10, 2, 2 ], 49, 35, "latexstringfactorsint", "X7DC642B97CD02F4E" ], [ "\033[2XConvertToMagmaInputString\033[102X", "10.3-1", [ 10, 3, 1 ], 68, 35, "converttomagmainputstring", "X8768D7707B4CBBD4" ], [ "PermGroupToMagmaFormat", "10.3-1", [ 10, 3, 1 ], 68, 35, "permgrouptomagmaformat", "X8768D7707B4CBBD4" ], [ "PcGroupToMagmaFormat", "10.3-1", [ 10, 3, 1 ], 68, 35, "pcgrouptomagmaformat", "X8768D7707B4CBBD4" ], [ "MatrixGroupToMagmaFormat", "10.3-1", [ 10, 3, 1 ], 68, 35, "matrixgrouptomagmaformat", "X8768D7707B4CBBD4" ], [ "FindMatchingFiles", "11.1", [ 11, 1, 0 ], 4, 37, "findmatchingfiles", "X7A6BB3D084912F35" ], [ "CreateDirIfMissing", "11.1", [ 11, 1, 0 ], 4, 37, "createdirifmissing", "X7A6BB3D084912F35" ], [ "StringDotSuffix", "11.1", [ 11, 1, 0 ], 4, 37, "stringdotsuffix", "X7A6BB3D084912F35" ], [ "GetSuffix", "11.1", [ 11, 1, 0 ], 4, 37, "getsuffix", "X7A6BB3D084912F35" ], [ "SetIfMissing", "11.1", [ 11, 1, 0 ], 4, 37, "setifmissing", "X7A6BB3D084912F35" ], [ "PrintOneItemPerLine", "11.2", [ 11, 2, 0 ], 21, 37, "printoneitemperline", "X86F322FC7DECE36F" ], [ "PrintApplicableMethod", "11.3-1", [ 11, 3, 1 ], 52, 38, "printapplicablemethod", "X78B7D1A982BE9866" ], [ "ExponentOfPrime", "11.3-2", [ 11, 3, 2 ], 85, 38, "exponentofprime", "X7C1AF2467FB55D79" ], [ "OKtoReadFromUtils", "12.0", [ 12, 0, 0 ], 1, 39, "oktoreadfromutils", "X84AC9613842F014C" ] ] ); utils-0.86/doc/chapBib_mj.html000644 000765 000024 00000014121 14621610515 021364 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - References
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

References

[BCP97] Bosma, W., Cannon, J. and Playoust, C., The Magma algebra system. {I}. The user language, J. Symbolic Comput., 24 (3-4) (1997), 235--265 pages
( Computational algebra and number theory (London, 1993)} https://doi.org/10.1006/jsco.1996.0125 ).

[GH16] Gutsche, S. and Horn, M., AutoDoc - Generate documentation from GAP source code (Version 2016.12.04) (2016)
( GAP package, https://github.com/gap-packages/AutoDoc ).

[Hor17] Horn, M., GitHubPagesForGAP - Template for easily using GitHub Pages within GAP packages (Version 0.2) (2017)
( GAP package, https://gap-system.github.io/GitHubPagesForGAP/ ).

[Koh17a] Kohl, S., RCWA - Residue-Class-Wise Affine Groups (Version 4.5.1) (2017)
( GAP package, https://stefan-kohl.github.io/rcwa.html ).

[Koh17b] Kohl, S., ResClasses - Set-Theoretic Computations with Residue Classes (Version 4.6.0) (2017)
( GAP package, https://stefan-kohl.github.io/resclasses.html ).

[LN17] Lübeck, F. and Neunhöffer, M., GAPDoc (Version 1.6), RWTH Aachen (2017)
( GAP package, https://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/index.html ).

[WAOU17] Wensley, C. D., Alp, M., Odabas, A. and Uslu, E. O., XMod - Crossed Modules and Cat1-groups in GAP (Version 2.64) (2017)
( GAP package, https://github.com/gap-packages/xmod ).

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/record.xml000644 000765 000024 00000011615 14621444241 020466 0ustar00christopherwensleystaff000000 000000 Records
Functions for records This function has been transferred from package &RCWA;.

It assigns the record components of rec to global variables with the same names.

r := rec( a := 1, b := 2, c := 3 );; gap> AssignGlobals( r ); The following global variables have been assigned: [ "a", "b", "c" ] gap> [a,b,c]; [ 1, 2, 3 ] ]]>

Option records for functions This functions has been transferred by Chris Jefferson from other packages. It simplifies the handling of records which are intended to be used for expressing configuration options. defaults represents the "default record", and useroptions lets the user give new values for values in defaults.

The function returns a record with the same component names as defaults and which has the same values as defaults, except for those component names in useroptions, where the values in useroptions are used instead. An error is given if useroptions contains any component names not in defaults. If useroptions is an empty list it is treated as an empty record, and if useroptions is a list of length 1 containing a record, this record is used as useroptions.

defaults := rec( a := 1, b := 2, c := 3 );; gap> OptionRecordWithDefaults( defaults, rec( a := 6) ); rec( a := 6, b := 2, c := 3 ) gap> OptionRecordWithDefaults( defaults, rec( b := 7, c := 8 ) ); rec( a := 1, b := 7, c := 8 ) gap> OptionRecordWithDefaults( defaults, [ ] ); rec( a := 1, b := 2, c := 3 ) gap> OptionRecordWithDefaults( defaults, [ rec( c := 8 ) ] ); rec( a := 1, b := 2, c := 8 ) gap> OptionRecordWithDefaults( defaults, rec( d := 9 ) ); Error, Unknown option: d gap> OptionRecordWithDefaults( defaults, [ rec( b := 7 ), rec( c := 8 ) ] ); Error, Too many arguments for function gap> OptionRecordWithDefaults( defaults, [6,7,8] ); Error, Too many arguments for function ]]> This function is designed to support functions with optional arguments given as a variable record, of the form function(x,y,options...). In the following, very contrived, example function, PrintDimensions, the defaults are given by the variable order which takes values h, w and d having default values 1, 2 and 3. If there is a second argument, then OptionRecordWithDefaults( order, arg[2] ); is used to cvhange the values. These three values then determine the order in which the three dimensions are printed using a SortParallel command.

1 ) and IsRecord( arg[2] ) then order := OptionRecordWithDefaults( order, arg[2] ); fi; L := [ order!.h, order!.w, order!.d ]; len := Length( L ); K := [ 1..len ]; SortParallel( L, K ); Print( "dimensions: " ); Print( V[K[1]], " = ", dim[K[1]], ", " ); Print( V[K[2]], " = ", dim[K[2]], ", " ); Print( V[K[3]], " = ", dim[K[3]], "\n" ); end;; ]]> In the example below the first call to PrintDimensions has just one parameter, mydim, so the default order is used. In the second call, alternate values for h, w and d are given, causing the width to be printed first, and then the depth and height. mydim := rec( height := 45, width := 31, depth := 17 ); rec( depth := 17, height := 45, width := 31 ) gap> PrintDimensions( mydim ); dimensions: height = 45, width = 31, depth = 17 gap> PrintDimensions( mydim, rec( h:=3, w:=1, d:=2 ) ); dimensions: width = 31, depth = 17, height = 45 ]]>
utils-0.86/doc/_entities.xml000644 000765 000024 00000000530 14621610512 021161 0ustar00christopherwensleystaff000000 000000 AutoDoc'> {\sf MathJax}'> ResClasses'> RCWA'> XMod'> Home'> {\sf Magma}'> Utils'> utils-0.86/doc/chap11.html000644 000765 000024 00000017337 14621610515 020437 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 11: Obsolete functions
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

11 Obsolete functions

11.1 Operations from AutoDoc

The file functions FindMatchingFiles and CreateDirIfMissing were copied from package AutoDoc where they are named AutoDoc_FindMatchingFiles and AutoDoc_CreateDirIfMissing.

The string function StringDotSuffix was also copied from package AutoDoc, where it is named AUTODOC_GetSuffix.

The function SetIfMissing was also transferred from package AutoDoc, where it is called AUTODOC_SetIfMissing. It writes into a record provided the position is not yet bound.

As from version 0.61, all these functions became obsolete in Utils, but continue to be defined in AutoDoc.

11.2 Functions for printing

The function PrintOneItemPerLine was used to prints lists vertically, rather than horizontally. Since a very similar result may be achieved using the GAP library functions Perform and Display, this function became obsolete in version 0.61.


gap> s3 := SymmetricGroup( 3 );; 
gap> L := KnownPropertiesOfObject( GeneratorsOfGroup( s3 ) );;
gap> Perform( L, Display );
IsFinite
IsSmallList
IsGeneratorsOfMagmaWithInverses
IsGeneratorsOfSemigroup
IsSubsetLocallyFiniteGroup
gap> Perform( s3, Display ); 
()
(2,3)
(1,3)
(1,3,2)
(1,2,3)
(1,2)

11.3 Other obsolete functions

11.3-1 Applicable Methods

The function PrintApplicableMethod, which was included in versions from 0.41 to 0.58, has been removed since it was considered superfluous. The example shows how to print out a function.


gap> ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 1, 1 );
#I  Searching Method for IsCyclic with 1 arguments:
#I  Total: 7 entries
#I  Method 4: ``IsCyclic'' at /Applications/gap/gap4r9/lib/grp.gi:30 , value: 
36
function( G ) ... end
gap> Print( last );
function ( G )
    if Length( GeneratorsOfGroup( G ) ) = 1 then
        return true;
    else
        TryNextMethod();
    fi;
    return;
end
gap> ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 0, 3 );
function( <1 unnamed arguments> ) ... end
gap> Print( last );                                               
function ( <<arg-1>> )
    <<compiled GAP code from GAPROOT/lib/oper1.g:578>>
end

11.3-2 ExponentOfPrime

The function ExponentOfPrime was originally transferred from package RCWA. The command ExponentOfPrime(n,p) returned the exponent of the prime p in the prime factorization of n.

Since the GAP function PValuation produces the same results, and does so more quickly, this function has been made obsolete.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap8.txt000644 000765 000024 00000013625 14621610512 020231 0ustar00christopherwensleystaff000000 000000 8 Records 8.1 Functions for records 8.1-1 AssignGlobals AssignGlobals( rec )  function This function has been transferred from package RCWA. It assigns the record components of rec to global variables with the same names.  Example   gap> r := rec( a := 1, b := 2, c := 3 );;  gap> AssignGlobals( r ); The following global variables have been assigned: [ "a", "b", "c" ] gap> [a,b,c]; [ 1, 2, 3 ]   8.2 Option records for functions 8.2-1 OptionRecordWithDefaults OptionRecordWithDefaults( defaults, useroptions )  function This functions has been transferred by Chris Jefferson from other packages. It simplifies the handling of records which are intended to be used for expressing configuration options. defaults represents the "default record", and useroptions lets the user give new values for values in defaults. The function returns a record with the same component names as defaults and which has the same values as defaults, except for those component names in useroptions, where the values in useroptions are used instead. An error is given if useroptions contains any component names not in defaults. If useroptions is an empty list it is treated as an empty record, and if useroptions is a list of length 1 containing a record, this record is used as useroptions.  Example   gap> defaults := rec( a := 1, b := 2, c := 3 );; gap> OptionRecordWithDefaults( defaults, rec( a := 6) ); rec( a := 6, b := 2, c := 3 ) gap> OptionRecordWithDefaults( defaults, rec( b := 7, c := 8 ) ); rec( a := 1, b := 7, c := 8 ) gap> OptionRecordWithDefaults( defaults, [ ] ); rec( a := 1, b := 2, c := 3 ) gap> OptionRecordWithDefaults( defaults, [ rec( c := 8 ) ] ); rec( a := 1, b := 2, c := 8 ) gap> OptionRecordWithDefaults( defaults, rec( d := 9 ) ); Error, Unknown option: d gap> OptionRecordWithDefaults( defaults, [ rec( b := 7 ), rec( c := 8 ) ] ); Error, Too many arguments for function gap> OptionRecordWithDefaults( defaults, [6,7,8] ); Error, Too many arguments for function   This function is designed to support functions with optional arguments given as a variable record, of the form function(x,y,options...). In the following, very contrived, example function, PrintDimensions, the defaults are given by the variable order which takes values h, w and d having default values 1, 2 and 3. If there is a second argument, then OptionRecordWithDefaults( order, arg[2] ); is used to cvhange the values. These three values then determine the order in which the three dimensions are printed using a SortParallel command.   PrintDimensions := function( arg )   local nargs, dim, order, V, L, len, K, i;   nargs := Length( arg );   dim := [ arg[1]!.height, arg[1]!.width, arg[1]!.depth ];   order := rec( h := 1, w := 2, d := 3 );   V := [ "height", "width", "depth" ];   if ( nargs > 1 ) and IsRecord( arg[2] ) then   order := OptionRecordWithDefaults( order, arg[2] );   fi;   L := [ order!.h, order!.w, order!.d ];   len := Length( L );  K := [ 1..len ];   SortParallel( L, K );   Print( "dimensions: " );   Print( V[K[1]], " = ", dim[K[1]], ", " );  Print( V[K[2]], " = ", dim[K[2]], ", " );  Print( V[K[3]], " = ", dim[K[3]], "\n" ); end;;  In the example below the first call to PrintDimensions has just one parameter, mydim, so the default order is used. In the second call, alternate values for h, w and d are given, causing the width to be printed first, and then the depth and height.  Example   gap> mydim := rec( height := 45, width := 31, depth := 17 );  rec( depth := 17, height := 45, width := 31 ) gap> PrintDimensions( mydim ); dimensions: height = 45, width = 31, depth = 17 gap> PrintDimensions( mydim, rec( h:=3, w:=1, d:=2 ) ); dimensions: width = 31, depth = 17, height = 45   utils-0.86/doc/chap0_mj.html000644 000765 000024 00000046402 14621610515 021036 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Contents
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

utils

Utility functions in GAP

0.86

16 May 2024

Thomas Breuer
Email: sam@math.rwth-aachen.de
Homepage: https://www.math.rwth-aachen.de/~Thomas.Breuer

Sebastian Gutsche
Email: gutsche@mathematik.uni-siegen.de
Homepage: https://sebasguts.github.io/

Max Horn
Email: mhorn@rptu.de
Homepage: https://github.com/mhorn

Alexander Hulpke
Email: hulpke@math.colostate.edu
Homepage: https://www.math.colostate.edu/~hulpke

Pedro García-Sánchez
Email: pedro@ugr.es
Homepage: http://www.ugr.es/local/pedro

Christopher Jefferson
Email: caj21@st-andrews.ac.uk
Homepage: https://caj.host.cs.st-andrews.ac.uk/

Stefan Kohl
Email: stefan@mcs.st-and.ac.uk
Homepage: https://www.gap-system.org/DevelopersPages/StefanKohl/

Frank Lübeck
Email: Frank.Luebeck@Math.RWTH-Aachen.De
Homepage: https://www.math.rwth-aachen.de/~Frank.Luebeck

Chris Wensley
Email: cdwensley.maths@btinternet.com
Homepage: https://github.com/cdwensley

Abstract

The Utils package provides a space for utility functions in a variety of GAP packages to be collected together into a single package. In this way it is hoped that they will become more visible to package authors.

Any package author who transfers a function to Utils will become an author of Utils.

If deemed appropriate, functions may also be transferred from the main library.

Bug reports, suggestions and comments are, of course, welcome. Please contact the last author at cdwensley.maths@btinternet.com or submit an issue at the GitHub repository https://github.com/gap-packages/utils/issues/.

Copyright

© 2015-2024, The GAP Group.

The Utils package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Acknowledgements

This documentation was prepared using the GAPDoc [LN17] and AutoDoc [GH16] packages.

The procedure used to produce new releases uses the package GitHubPagesForGAP [Hor17] and the package ReleaseTools.

Contents


Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap9.txt000644 000765 000024 00000011710 14621610512 020223 0ustar00christopherwensleystaff000000 000000 9 Web Downloads The Download operation has been written by Thomas Breuer, incorporating a number of suggestions from Max Horn, for version 0.77 of Utils. It implements downloading a file from within GAP. It can use the IO or curlInterface packages, or wget or curl, if installed, and it can be extended with other download methods quite easily. It is envisaged that, once other packages have started to use it, and any problems have been addressed, that the functions will be transferred to the main GAP library. 9.1 Functions for downloading files from the web 9.1-1 Download Download( url[, opt] )  function This function downloads the file with the web address url, which must be a string. The result is a record which has at least the component success, with value true if the download was successful and false otherwise. In the former case, the component result is bound, whose value is a string that contains the contents of the downloaded file. In the latter case, the component error is bound, whose value is a string that describes the problem. The function calls the methods stored in the global list Download_Methods until one of them is successful. Currently there are methods based on the GAP functions DownloadURL (curl: DownloadURL) and SingleHTTPRequest (IO: SingleHTTPRequest), and methods based on the external programs wget and curl. An optional record opt can be given. The following components are supported. target If this component is bound then its value must be a string that is a local filename, and the function writes the downloaded contents to this file; the returned record does not have a result component in this case. verifyCert If this component is bound and has the value false then those download methods that are based on curl or wget will omit the check of the server's certificate. The same effect is achieved for all Download calls by setting the user preference DownloadVerifyCertificate (see 9.1-2) to false and omitting the verifyCert component from opt.  Example   gap> url:= "https://www.gap-system.org/Packages/utils.html";; gap> res1:= Download( url );; gap> res1.success; true gap> IsBound( res1.result ) and IsString( res1.result ); true gap> res2:= Download( Concatenation( url, "xxx" ) );; gap> res2.success; false gap> IsBound( res2.error ) and IsString( res2.error ); true   9.1-2 User preference DownloadVerifyCertificate The value true (the default) means that the server's certificate is checked in calls of Download (9.1-1), such that nothing gets downloaded if the certificate is invalid. If the value is false then download methods are supposed to omit the check of the server's certificate (this may not be supported by all download methods). One can set the value of the preference to be val via SetUserPreference (Reference: SetUserPreference), by calling SetUserPreference( "utils", "DownloadVerifyCertificate", val ), and access the current value via UserPreference (Reference: UserPreference), by calling UserPreference( "utils", "DownloadVerifyCertificate" ). We recommend leaving this preference at its default value true. Sometimes it can be necessary to change it, e.g. to work around issues with old operating systems which may not be able to correctly verify new certificates. In general it is better to update such a system, but if that is not an option, then disabling certificate checks may be a good last resort. utils-0.86/doc/chap2.html000644 000765 000024 00000013236 14621610515 020351 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 2: Printing Lists and Iterators
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

2 Printing Lists and Iterators

2.1 Printing selected items

The functions described here print lists or objects with an iterator with one item per line, either the whole list/iterator or certain subsets:

  • by giving a list of positions of items to be printed, or

  • by specifying a first item and then a regular step.

2.1-1 PrintSelection
‣ PrintSelection( obj, first, step[, last] )( function )
‣ PrintSelection( obj, list )( function )

This function, given three (or four) parameters, calls operations PrintSelectionFromList or PrintSelectionFromIterator which prints the first item specified, and then the item at every step. The fourth parameter is essential when the object being printed is infinite.

Alternatively, given two parameters, with the second parameter a list L of positive integers, only the items at positions in L are printed.


gap> L := List( [1..20], n -> n^5 );;
gap> PrintSelection( L, [18..20] );
18 : 1889568
19 : 2476099
20 : 3200000
gap> PrintSelection( L, 2, 9 );       
2 : 32
11 : 161051
20 : 3200000
gap> PrintSelection( L, 2, 3, 11 );
2 : 32
5 : 3125
8 : 32768
11 : 161051
gap> s5 := SymmetricGroup( 5 );;
gap> PrintSelection( s5, [30,31,100,101] );
30 : (1,5)(3,4)
31 : (1,5,2)
100 : (1,4,3)
101 : (1,4)(3,5)
gap> PrintSelection( s5, 1, 30 );
1 : ()
31 : (1,5,2)
61 : (1,2,3)
91 : (1,3,5,2,4)
gap> PrintSelection( s5, 9, 11, 43 );
9 : (2,5,3)
20 : (2,4)
31 : (1,5,2)
42 : (1,5,2,3,4)

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap3.html000644 000765 000024 00000040234 14621610515 020350 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 3: Lists, Sets and Strings
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

3 Lists, Sets and Strings

3.1 Functions for lists

3.1-1 DifferencesList
‣ DifferencesList( L )( function )

This function has been transferred from package ResClasses.

It takes a list L of length n and outputs the list of length n-1 containing all the differences L[i]-L[i-1].


gap> List( [1..12], n->n^3 );
[ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728 ]
gap> DifferencesList( last );
[ 7, 19, 37, 61, 91, 127, 169, 217, 271, 331, 397 ]
gap> DifferencesList( last );
[ 12, 18, 24, 30, 36, 42, 48, 54, 60, 66 ]
gap> DifferencesList( last );
[ 6, 6, 6, 6, 6, 6, 6, 6, 6 ]

3.1-2 QuotientsList
‣ QuotientsList( L )( function )
‣ FloatQuotientsList( L )( function )

These functions have been transferred from package ResClasses.

They take a list L of length n and output the quotients L[i]/L[i-1] of consecutive entries in L. An error is returned if an entry is zero.


gap> List( [0..10], n -> Factorial(n) );
[ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ]
gap> QuotientsList( last );
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
gap> L := [ 1, 3, 5, -1, -3, -5 ];;
gap> QuotientsList( L );
[ 3, 5/3, -1/5, 3, 5/3 ]
gap> FloatQuotientsList( L );
[ 3., 1.66667, -0.2, 3., 1.66667 ]
gap> QuotientsList( [ 2, 1, 0, -1, -2 ] );
[ 1/2, 0, fail, 2 ]
gap> FloatQuotientsList( [1..10] );
[ 2., 1.5, 1.33333, 1.25, 1.2, 1.16667, 1.14286, 1.125, 1.11111 ]
gap> Product( last );
10. 

3.1-3 SearchCycle
‣ SearchCycle( L )( operation )

This function has been transferred from package RCWA.

SearchCycle is a tool to find likely cycles in lists. What, precisely, a cycle is, is deliberately fuzzy here, and may possibly even change. The idea is that the beginning of the list may be anything, following that the same pattern needs to be repeated several times in order to be recognized as a cycle.


gap> L := [1..20];;  L[1]:=13;;                                              
gap> for i in [1..19] do                                                     
>        if IsOddInt(L[i]) then L[i+1]:=3*L[i]+1; else L[i+1]:=L[i]/2; fi;
>    od;                                                                  
gap> L;                                                                      
[ 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4 ]
gap> SearchCycle( L );                                                       
[ 1, 4, 2 ]
gap> n := 1;;  L := [n];;
gap> for i in [1..100] do  n:=(n^2+1) mod 1093;  Add(L,n);  od;
gap> L; 
[ 1, 2, 5, 26, 677, 363, 610, 481, 739, 715, 795, 272, 754, 157, 604, 848, 
  1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 
  211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 
  378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 
  754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 
  848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 
  271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004 ]
gap> C := SearchCycle( L );
[ 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754 ]
gap> P := Positions( L, 157 );
[ 14, 26, 38, 50, 62, 74, 86, 98 ]
gap> Length( C );  DifferencesList( P );
12
[ 12, 12, 12, 12, 12, 12, 12 ]

3.1-4 RandomCombination
‣ RandomCombination( S, k )( operation )

This function has been transferred from package ResClasses.

It returns a random unordered k-tuple of distinct elements of a set S.


gap> ## "6 aus 49" is a common lottery in Germany
gap> RandomCombination( [1..49], 6 ); 
[ 2, 16, 24, 26, 37, 47 ]

3.2 Distinct and Common Representatives

3.2-1 DistinctRepresentatives
‣ DistinctRepresentatives( list )( operation )
‣ CommonRepresentatives( list )( operation )
‣ CommonTransversal( grp, subgrp )( operation )
‣ IsCommonTransversal( grp, subgrp, list )( operation )

These operations have been transferred from package XMod.

They deal with lists of subsets of [1 ... n] and construct systems of distinct and common representatives using simple, non-recursive, combinatorial algorithms.

When L is a set of n subsets of [1 ... n] and the Hall condition is satisfied (the union of any k subsets has at least k elements), a set of DistinctRepresentatives exists.

When J,K are both lists of n sets, the operation CommonRepresentatives returns two lists: the set of representatives, and a permutation of the subsets of the second list.

The operation CommonTransversal may be used to provide a common transversal for the sets of left and right cosets of a subgroup H of a group G, although a greedy algorithm is usually quicker.


gap> J := [ [1,2,3], [3,4], [3,4], [1,2,4] ];;
gap> DistinctRepresentatives( J );
[ 1, 3, 4, 2 ]
gap> K := [ [3,4], [1,2], [2,3], [2,3,4] ];;
gap> CommonRepresentatives( J, K );
[ [ 3, 3, 3, 1 ], [ 1, 3, 4, 2 ] ]
gap> d16 := DihedralGroup( IsPermGroup, 16 ); 
Group([ (1,2,3,4,5,6,7,8), (2,8)(3,7)(4,6) ])
gap> SetName( d16, "d16" );
gap> c4 := Subgroup( d16, [ d16.1^2 ] ); 
Group([ (1,3,5,7)(2,4,6,8) ])
gap> SetName( c4, "c4" );
gap> RightCosets( d16, c4 );
[ RightCoset(c4,()), RightCoset(c4,(2,8)(3,7)(4,6)), RightCoset(c4,(1,8,7,6,5,
   4,3,2)), RightCoset(c4,(1,8)(2,7)(3,6)(4,5)) ]
gap> trans := CommonTransversal( d16, c4 );
[ (), (2,8)(3,7)(4,6), (1,2,3,4,5,6,7,8), (1,2)(3,8)(4,7)(5,6) ]
gap> IsCommonTransversal( d16, c4, trans );
true

3.3 Functions for strings

3.3-1 BlankFreeString
‣ BlankFreeString( obj )( function )

This function has been transferred from package ResClasses.

The result of BlankFreeString( obj ); is a composite of the functions String( obj ) and RemoveCharacters( obj, " " );.


gap> gens := GeneratorsOfGroup( DihedralGroup(12) );
[ f1, f2, f3 ]
gap> String( gens );                                
"[ f1, f2, f3 ]"
gap> BlankFreeString( gens );                       
"[f1,f2,f3]"

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap1_mj.html000644 000765 000024 00000021360 14621610515 021033 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 1: Introduction
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

1 Introduction

The Utils package provides a space for utility functions from a variety of GAP packages to be collected together into a single package. In this way it is hoped that they will become more visible to other package authors. This package was first distributed as part of the GAP 4.8.2 distribution.

The package is loaded with the command


gap> LoadPackage( "utils" ); 

Functions have been transferred from the following packages:

  • Conversion of a GAP group to a \({\sf Magma}\) output string, taken from various sources including other.gi in the main library.

Transfer is complete (for now) for functions from the following packages:

The package may be obtained either as a compressed .tar file or as a .zip file, utils-version_number.tar.gz, by ftp from one of the following sites:

The package also has a GitHub repository at: https://github.com/gap-packages/utils.

Once the package is loaded, the manual doc/manual.pdf can be found in the documentation folder. The html versions, with or without \({\sf MathJax}\), may be rebuilt as follows:


gap> ReadPackage( "utils", "makedoc.g" ); 

It is possible to check that the package has been installed correctly by running the test files (which terminates the GAP session):


gap> ReadPackage( "utils", "tst/testall.g" );
Architecture: . . . . . 
testing: . . . . . 
. . . 
#I  No errors detected while testing

Note that functions listed in this manual that are currently in the process of being transferred are only read from the source package Home (say), and so can only be used if Home has already been loaded. There are no such functions in transition at present.

1.1 Information for package authors

A function (or collection of functions) is suitable for transfer from a package Home to Utils if the following conditions are satisfied.

  • The function is sufficiently non-specialised so that it might be of use to other authors.

  • The function does not depend on the remaining functions in Home

  • The function does not do what can already be done with a GAP library function.

  • Documentation of the function and test examples are available.

  • When there is more than one active author of Home, they should all be aware (and content) that the transfer is taking place.

Authors of packages may be reluctant to let go of their utility functions. The following principles may help to reassure them. (Suggestions for more items here are welcome.)

  • A function that has been transferred to Utils will not be changed without the approval of the original author.

  • The current package maintainer has every intention of continuing to maintain Utils. In the event that this proves impossible, the GAP development team will surely find someone to take over.

  • Function names will not be changed unless specifically requested by Home's author(s) or unless they have the form HOME_FunctionName.

  • In order to speed up the transfer process, only functions from one package will be in transition at any given time. Hopefully a week or two will suffice for most packages.

  • Any package author who transfers a function to Utils will become an author of Utils. (In truth, Utils does not have authors, just a large number of contributors.)

The process for transferring utility functions from Home to Utils is described in Chapter 12.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/title.xml000644 000765 000024 00000006140 14621610512 020322 0ustar00christopherwensleystaff000000 000000 utils Utility functions in &GAP; 0.86 Thomas Breuer
sam@math.rwth-aachen.de https://www.math.rwth-aachen.de/~Thomas.Breuer
Sebastian Gutsche
gutsche@mathematik.uni-siegen.de https://sebasguts.github.io/
Max Horn
mhorn@rptu.de https://github.com/mhorn
Alexander Hulpke
hulpke@math.colostate.edu https://www.math.colostate.edu/~hulpke
Pedro García-Sánchez
pedro@ugr.es http://www.ugr.es/local/pedro
Christopher Jefferson
caj21@st-andrews.ac.uk https://caj.host.cs.st-andrews.ac.uk/
Stefan Kohl
stefan@mcs.st-and.ac.uk https://www.gap-system.org/DevelopersPages/StefanKohl/
Frank Lübeck
Frank.Luebeck@Math.RWTH-Aachen.De https://www.math.rwth-aachen.de/~Frank.Luebeck
Chris Wensley
cdwensley.maths@btinternet.com https://github.com/cdwensley
16 May 2024 The &Utils; package provides a space for utility functions in a variety of &GAP; packages to be collected together into a single package. In this way it is hoped that they will become more visible to package authors.

Any package author who transfers a function to &Utils; will become an author of &Utils;.

If deemed appropriate, functions may also be transferred from the main library.

Bug reports, suggestions and comments are, of course, welcome. Please contact the last author at cdwensley.maths@btinternet.com or submit an issue at the GitHub repository https://github.com/gap-packages/utils/issues/. ©right; 2015-2024, The GAP Group.

The &Utils; package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This documentation was prepared using the &GAPDoc; and &AutoDoc; packages.

The procedure used to produce new releases uses the package GitHubPagesForGAP and the package ReleaseTools.

utils-0.86/doc/download.xml000644 000765 000024 00000011330 14621444241 021011 0ustar00christopherwensleystaff000000 000000 Web Downloads The Download operation has been written by Thomas Breuer, incorporating a number of suggestions from Max Horn, for version 0.77 of Utils. It implements downloading a file from within &GAP;. It can use the IO or curlInterface packages, or wget or curl, if installed, and it can be extended with other download methods quite easily. It is envisaged that, once other packages have started to use it, and any problems have been addressed, that the functions will be transferred to the main &GAP; library.

Functions for downloading files from the web This function downloads the file with the web address url, which must be a string.

The result is a record which has at least the component success, with value true if the download was successful and false otherwise. In the former case, the component result is bound, whose value is a string that contains the contents of the downloaded file. In the latter case, the component error is bound, whose value is a string that describes the problem.

The function calls the methods stored in the global list Download_Methods until one of them is successful. Currently there are methods based on the &GAP; functions and , and methods based on the external programs wget and curl.

An optional record opt can be given. The following components are supported.

target If this component is bound then its value must be a string that is a local filename, and the function writes the downloaded contents to this file; the returned record does not have a result component in this case. verifyCert If this component is bound and has the value false then those download methods that are based on curl or wget will omit the check of the server's certificate. The same effect is achieved for all calls by setting the user preference DownloadVerifyCertificate (see ) to false and omitting the verifyCert component from opt.

url:= "https://www.gap-system.org/Packages/utils.html";; gap> res1:= Download( url );; gap> res1.success; true gap> IsBound( res1.result ) and IsString( res1.result ); true gap> res2:= Download( Concatenation( url, "xxx" ) );; gap> res2.success; false gap> IsBound( res2.error ) and IsString( res2.error ); true ]]> User preference DownloadVerifyCertificate DownloadVerifyCertificate The value true (the default) means that the server's certificate is checked in calls of , such that nothing gets downloaded if the certificate is invalid.

If the value is false then download methods are supposed to omit the check of the server's certificate (this may not be supported by all download methods).

One can set the value of the preference to be val via , by calling SetUserPreference( "utils", "DownloadVerifyCertificate", val ), and access the current value via , by calling UserPreference( "utils", "DownloadVerifyCertificate" ).

We recommend leaving this preference at its default value true. Sometimes it can be necessary to change it, e.g. to work around issues with old operating systems which may not be able to correctly verify new certificates. In general it is better to update such a system, but if that is not an option, then disabling certificate checks may be a good last resort.

utils-0.86/doc/manual.js000644 000765 000024 00000010113 14621610515 020270 0ustar00christopherwensleystaff000000 000000 /* manual.js Frank Lübeck */ /* This file contains a few javascript functions which allow to switch between display styles for GAPDoc HTML manuals. If javascript is switched off in a browser or this file in not available in a manual directory, this is no problem. Users just cannot switch between several styles and don't see the corresponding button. A style with name mystyle can be added by providing two files (or only one of them). mystyle.js: Additional javascript code for the style, it is read in the HTML pages after this current file. The additional code may adjust the preprocessing function jscontent() with is called onload of a file. This is done by appending functions to jscontentfuncs (jscontentfuncs.push(newfunc);). Make sure, that your style is still usable without javascript. mystyle.css: CSS configuration, read after manual.css (so it can just reconfigure a few details, or overwrite everything). Then adjust chooser.html such that users can switch on and off mystyle. A user can change the preferred style permanently by using the [Style] link and choosing one. Or one can append '?GAPDocStyle=mystyle' to the URL when loading any file of the manual (so the style can be configured in the GAP user preferences). */ /* generic helper function */ function deleteCookie(nam) { document.cookie = nam+"=;Path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT"; } /* read a value from a "nam1=val1;nam2=val2;..." string (e.g., the search part of an URL or a cookie */ function valueString(str,nam) { var cs = str.split(";"); for (var i=0; i < cs.length; i++) { var pos = cs[i].search(nam+"="); if (pos > -1) { pos = cs[i].indexOf("="); return cs[i].slice(pos+1); } } return 0; } /* when a non-default style is chosen via URL or a cookie, then the cookie is reset and the styles .js and .css files are read */ function overwriteStyle() { /* style in URL? */ var style = valueString(window.location.search, "GAPDocStyle"); /* otherwise check cookie */ if (style == 0) style = valueString(document.cookie, "GAPDocStyle"); if (style == 0) return; if (style == "default") deleteCookie("GAPDocStyle"); else { /* ok, we set the cookie for path "/" */ var path = "/"; /* or better like this ??? var here = window.location.pathname.split("/"); for (var i=0; i+3 < here.length; i++) path = path+"/"+here[i]; */ document.cookie = "GAPDocStyle="+style+";Path="+path; /* split into names of style files */ var stlist = style.split(","); /* read style's css and js files */ for (var i=0; i < stlist.length; i++) { document.writeln(''); document.writeln(''); } } } /* this adds a "[Style]" link next to the MathJax switcher */ function addStyleLink() { var line = document.getElementById("mathjaxlink"); var el = document.createElement("a"); var oncl = document.createAttribute("href"); var back = window.location.protocol+"//" if (window.location.protocol == "http:" || window.location.protocol == "https:") { back = back+window.location.host; if (window.location.port != "") { back = back+":"+window.location.port; } } back = back+window.location.pathname; oncl.nodeValue = "chooser.html?BACK="+back; el.setAttributeNode(oncl); var cont = document.createTextNode(" [Style]"); el.appendChild(cont); line.appendChild(el); } var jscontentfuncs = new Array(); jscontentfuncs.push(addStyleLink); /* the default jscontent() only adds the [Style] link to the page */ function jscontent () { for (var i=0; i < jscontentfuncs.length; i++) jscontentfuncs[i](); } utils-0.86/doc/number.xml000644 000765 000024 00000013234 14621444241 020477 0ustar00christopherwensleystaff000000 000000 Number-theoretic functions
Functions for integers This function has been transferred from package &RCWA;.

smooth integer The function AllSmoothIntegers(maxp,maxn) returns the list of all positive integers less than or equal to maxn whose prime factors are all in the list L = \{p ~|~ p \leqslant maxp, p~\mbox{prime} \}.

In the alternative form, when L is a list of primes, the function returns the list of all positive integers whose prime factors lie in L.

AllSmoothIntegers( 3, 1000 ); [ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96, 108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576, 648, 729, 768, 864, 972 ] gap> AllSmoothIntegers( [5,11,17], 1000 ); [ 1, 5, 11, 17, 25, 55, 85, 121, 125, 187, 275, 289, 425, 605, 625, 935 ] gap> Length( last ); 16 gap> List( [3..20], n -> Length( AllSmoothIntegers( [5,11,17], 10^n ) ) ); [ 16, 29, 50, 78, 114, 155, 212, 282, 359, 452, 565, 691, 831, 992, 1173, 1374, 1595, 1843 ] ]]> This function has been transferred from package &RCWA;.

The command AllProducts(L,k) returns the list of all products of k entries of the list L. Note that every ordering of the entries is used so that, in the commuting case, there are bound to be repetitions.

AllProducts([1..4],3); [ 1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16, 2, 4, 6, 8, 4, 8, 12, 16, 6, 12, 18, 24, 8, 16, 24, 32, 3, 6, 9, 12, 6, 12, 18, 24, 9, 18, 27, 36, 12, 24, 36, 48, 4, 8, 12, 16, 8, 16, 24, 32, 12, 24, 36, 48, 16, 32, 48, 64 ] gap> Set(last); [ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 64 ] gap> AllProducts( [(1,2,3),(2,3,4)], 2 ); [ (2,4,3), (1,2)(3,4), (1,3)(2,4), (1,3,2) ] ]]> This function has been transferred from package &RCWA;.

For a positive integer n and a set of positive integers S, this function returns the list of partitions of n into distinct elements of S. Unlike RestrictedPartitions, no repetitions are allowed.

RestrictedPartitions( 20, [4..10] ); [ [ 4, 4, 4, 4, 4 ], [ 5, 5, 5, 5 ], [ 6, 5, 5, 4 ], [ 6, 6, 4, 4 ], [ 7, 5, 4, 4 ], [ 7, 7, 6 ], [ 8, 4, 4, 4 ], [ 8, 6, 6 ], [ 8, 7, 5 ], [ 8, 8, 4 ], [ 9, 6, 5 ], [ 9, 7, 4 ], [ 10, 5, 5 ], [ 10, 6, 4 ], [ 10, 10 ] ] gap> RestrictedPartitionsWithoutRepetitions( 20, [4..10] ); [ [ 10, 6, 4 ], [ 9, 7, 4 ], [ 9, 6, 5 ], [ 8, 7, 5 ] ] gap> RestrictedPartitionsWithoutRepetitions( 10^2, List([1..10], n->n^2 ) ); [ [ 100 ], [ 64, 36 ], [ 49, 25, 16, 9, 1 ] ] ]]> This function has been transferred from package &RCWA;.

The function NextProbablyPrimeInt(n) does the same as NextPrimeInt(n) except that for reasons of performance it tests numbers only for IsProbablyPrimeInt(n) instead of IsPrimeInt(n). For large n, this function is much faster than NextPrimeInt(n)

n := 2^251; 3618502788666131106986593281521497120414687020801267626233049500247285301248 gap> NextProbablyPrimeInt( n ); 3618502788666131106986593281521497120414687020801267626233049500247285301313 gap> time; 1 gap> NextPrimeInt( n ); 3618502788666131106986593281521497120414687020801267626233049500247285301313 gap> time; 213 ]]> This function has been transferred from package &RCWA;.

This function returns an iterator which runs over the prime numbers n ascending order; it takes an optional argument chunksize which specifies the length of the interval which is sieved in one go (the default is 10^7), and which can be used to balance runtime vs. memory consumption. It is assumed that chunksize is larger than any gap between two consecutive primes within the range one intends to run the iterator over.

iter := PrimeNumbersIterator();; gap> for i in [1..100] do p := NextIterator(iter); od; gap> p; 541 gap> sum := 0;; gap> ## "prime number race" 1 vs. 3 mod 4 gap> for p in PrimeNumbersIterator() do > if p <> 2 then sum := sum + E(4)^(p-1); fi; > if sum > 0 then break; fi; > od; gap> p; 26861 ]]>

utils-0.86/doc/chap10.html000644 000765 000024 00000024624 14621610515 020433 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 10: Various other functions
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

10 Various other functions

10.1 File operations

10.1-1 Log2HTML
‣ Log2HTML( filename )( function )

This function has been transferred from package RCWA.

This function converts the GAP logfile filename to HTML. It appears that the logfile should be in your current directory. The extension of the input file must be *.log. The name of the output file is the same as the one of the input file except that the extension *.log is replaced by *.html. There is a sample CSS file in utils/doc/gaplog.css, which you can adjust to your taste.


gap> LogTo( "triv.log" );
gap> a := 33^5;
39135393
gap> LogTo(); 
gap> Log2HTML( "triv.log" );     

10.2 LaTeX strings

10.2-1 IntOrOnfinityToLaTeX
‣ IntOrOnfinityToLaTeX( n )( function )

This function has been transferred from package ResClasses.

IntOrInfinityToLaTeX(n) returns the LaTeX string for n.


gap> IntOrInfinityToLaTeX( 10^3 );
"1000"
gap> IntOrInfinityToLaTeX( infinity );
"\\infty"

10.2-2 LaTeXStringFactorsInt
‣ LaTeXStringFactorsInt( n )( function )

This function has been transferred from package RCWA.

It returns the prime factorization of the integer n as a string in LaTeX format.


gap> LaTeXStringFactorsInt( Factorial(12) );
"2^{10} \\cdot 3^5 \\cdot 5^2 \\cdot 7 \\cdot 11"

10.3 Conversion to Magma string

10.3-1 ConvertToMagmaInputString
‣ ConvertToMagmaInputString( arg )( function )

The function ConvertToMagmaInputString( obj [, str] ) attempts to output a string s which can be read into Magma [BCP97] so as to produce the same group in that computer algebra system. In the second form the user specifies the name of the resulting object, so that the output string has the form "str := ...". When obj is a permutation group, the operation PermGroupToMagmaFormat(obj) is called. This function has been taken from other.gi in the main library where it was called MagmaInputString. When obj is a pc-group, the operation PcGroupToMagmaFormat(obj) is called. This function was private code of Max Horn. When obj is a matrix group over a finite field, the operation MatrixGroupToMagmaFormat(obj) is called. This function is a modification of private code of Frank Lübeck.

Hopefully code for other types of group will be added in due course.

These functions should be considered experimental, and more testing is desirable.


gap> ConvertToMagmaInputString( Group( (1,2,3,4,5), (3,4,5) ) );
"PermutationGroup<5|(1,2,3,4,5),\n(3,4,5)>;\n"
gap> ConvertToMagmaInputString( Group( (1,2,3,4,5) ), "c5" );        
"c5:=PermutationGroup<5|(1,2,3,4,5)>;\n"
gap> ConvertToMagmaInputString( DihedralGroup( IsPcGroup, 10 ) );
"PolycyclicGroup< f1,f2 |\nf1^2,\nf2^5,\nf2^f1 = f2^4\n>;\n"
gap> M := GL(2,5);;  Size(M); 
480
gap> s1 := ConvertToMagmaInputString( M );
"F := GF(5);\nP := GL(2,F);\ngens := [\nP![2,0,0,1],\nP![4,1,4,0]\n];\nsub<P |\
 gens>;\n"
gap> Print( s1 );
F := GF(5);
P := GL(2,F);
gens := [
P![2,0,0,1],
P![4,1,4,0]
];
sub<P | gens>;
gap> n1 := [ [ Z(9)^0, Z(9)^0 ], [ Z(9)^0, Z(9) ] ];;
gap> n2 := [ [ Z(9)^0, Z(9)^3 ], [ Z(9)^4, Z(9)^2 ] ];;
gap> N := Group( n1, n2 );;  Size( N );
5760
gap> s2 := ConvertToMagmaInputString( N, "gpN" );;
gap> Print( s2 );
F := GF(3^2);
P := GL(2,F);
w := PrimitiveElement(F);
gens := [
P![ 1, 1, 1,w^1],
P![ 1,w^3, 2,w^2]
];
gpN := sub<P | gens>;

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap8_mj.html000644 000765 000024 00000023424 14621610515 021045 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 8: Records
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

8 Records

8.1 Functions for records

8.1-1 AssignGlobals
‣ AssignGlobals( rec )( function )

This function has been transferred from package RCWA.

It assigns the record components of rec to global variables with the same names.


gap> r := rec( a := 1, b := 2, c := 3 );;                                      
gap> AssignGlobals( r );
The following global variables have been assigned:
[ "a", "b", "c" ]
gap> [a,b,c];
[ 1, 2, 3 ]

8.2 Option records for functions

8.2-1 OptionRecordWithDefaults
‣ OptionRecordWithDefaults( defaults, useroptions )( function )

This functions has been transferred by Chris Jefferson from other packages. It simplifies the handling of records which are intended to be used for expressing configuration options. defaults represents the "default record", and useroptions lets the user give new values for values in defaults.

The function returns a record with the same component names as defaults and which has the same values as defaults, except for those component names in useroptions, where the values in useroptions are used instead. An error is given if useroptions contains any component names not in defaults. If useroptions is an empty list it is treated as an empty record, and if useroptions is a list of length \(1\) containing a record, this record is used as useroptions.


gap> defaults := rec( a := 1, b := 2, c := 3 );;
gap> OptionRecordWithDefaults( defaults, rec( a := 6) );
rec( a := 6, b := 2, c := 3 )
gap> OptionRecordWithDefaults( defaults, rec( b := 7, c := 8 ) );
rec( a := 1, b := 7, c := 8 )
gap> OptionRecordWithDefaults( defaults, [ ] );
rec( a := 1, b := 2, c := 3 )
gap> OptionRecordWithDefaults( defaults, [ rec( c := 8 ) ] );
rec( a := 1, b := 2, c := 8 )
gap> OptionRecordWithDefaults( defaults, rec( d := 9 ) );
Error, Unknown option: d
gap> OptionRecordWithDefaults( defaults, [ rec( b := 7 ), rec( c := 8 ) ] );
Error, Too many arguments for function
gap> OptionRecordWithDefaults( defaults, [6,7,8] );
Error, Too many arguments for function

This function is designed to support functions with optional arguments given as a variable record, of the form function(x,y,options...). In the following, very contrived, example function, PrintDimensions, the defaults are given by the variable order which takes values h, w and d having default values \(1\), \(2\) and \(3\). If there is a second argument, then OptionRecordWithDefaults( order, arg[2] ); is used to cvhange the values. These three values then determine the order in which the three dimensions are printed using a SortParallel command.


PrintDimensions := function( arg ) 
    local nargs, dim, order, V, L, len, K, i; 
    nargs := Length( arg ); 
    dim := [ arg[1]!.height, arg[1]!.width, arg[1]!.depth ]; 
    order := rec( h := 1, w := 2, d := 3 ); 
    V := [ "height", "width", "depth" ]; 
    if ( nargs > 1 ) and IsRecord( arg[2] ) then 
        order := OptionRecordWithDefaults( order, arg[2] ); 
    fi; 
    L := [ order!.h, order!.w, order!.d ]; 
    len := Length( L );
    K := [ 1..len ]; 
    SortParallel( L, K ); 
    Print( "dimensions: " ); 
    Print( V[K[1]], " = ", dim[K[1]], ", " );
    Print( V[K[2]], " = ", dim[K[2]], ", " );
    Print( V[K[3]], " = ", dim[K[3]], "\n" );
end;;

In the example below the first call to PrintDimensions has just one parameter, mydim, so the default order is used. In the second call, alternate values for h, w and d are given, causing the width to be printed first, and then the depth and height.


gap> mydim := rec( height := 45, width := 31, depth := 17 ); 
rec( depth := 17, height := 45, width := 31 )
gap> PrintDimensions( mydim );
dimensions: height = 45, width = 31, depth = 17
gap> PrintDimensions( mydim, rec( h:=3, w:=1, d:=2 ) );
dimensions: width = 31, depth = 17, height = 45

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/bib.xml.bib000644 000765 000024 00000011417 14621610512 020473 0ustar00christopherwensleystaff000000 000000 @manual{ AutoDoc, author = {Gutsche, S. and Horn, M.}, title = {{AutoDoc \texttt{\symbol{45}} Generate documentation from GAP source code (Version 2016.12.04)}}, year = {2016}, note = {GAP package, \href {https://github.com/gap-packages/AutoDoc} {\texttt{https://github.com/}\discretionary {}{}{}\texttt{gap\texttt{\symbol{45}}packages/}\discretionary {}{}{}\texttt{AutoDoc}}}, printedkey = {GH16} } @manual{ GAPDoc, author = {L{\"u}beck, F. and Neunh{\"o}ffer, M.}, title = {{GAPDoc (Version 1.6)}}, organization = {RWTH Aachen}, year = {2017}, note = {GAP package, \href {https://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/index.html} {\texttt{https://www.math.rwth\texttt{\symbol{45}}aachen.de/}\discretionary {}{}{}\texttt{\texttt{\symbol{126}}Frank.Luebeck/}\discretionary {}{}{}\texttt{GAPDoc/}\discretionary {}{}{}\texttt{index.html}}}, printedkey = {LN17} } @manual{ GitHubPagesForGAP, author = {Horn, M.}, title = {{GitHubPagesForGAP \texttt{\symbol{45}} Template for easily using GitHub Pages within GAP packages (Version 0.2)}}, year = {2017}, note = {GAP package, \href {https://gap-system.github.io/GitHubPagesForGAP/} {\texttt{https://gap\texttt{\symbol{45}}system.github.io/}\discretionary {}{}{}\texttt{GitHubPagesForGAP/}}}, printedkey = {Hor17} } @manual{ MAGMA, author = {Bosma, W. and Cannon, J. and Playoust, C.}, title = {{The Magma algebra system. \texttt{\symbol{123}}I\texttt{\symbol{125}}. The user language}}, journal = {J. Symbolic Comput.}, volume = {24}, number = {3\texttt{\symbol{45}}4}, year = {1997}, pages = {235\texttt{\symbol{45}}\texttt{\symbol{45}}265}, note = {Computational algebra and number theory (London, 1993)\texttt{\symbol{125}} \href {https://doi.org/10.1006/jsco.1996.0125} {\texttt{https://doi.org/}\discretionary {}{}{}\texttt{10.1006/}\discretionary {}{}{}\texttt{jsco.1996.0125}}}, mrclass = {68Q40}, mrnumber = {MR1484478}, ISSN = {0747\texttt{\symbol{45}}7171}, doi = {10.1006/jsco.1996.0125}, printedkey = {BCP97} } @manual{ RCWA, author = {Kohl, S.}, title = {{RCWA \texttt{\symbol{45}} Residue\texttt{\symbol{45}}Class\texttt{\symbol{45}}Wise Affine Groups (Version 4.5.1)}}, year = {2017}, note = {GAP package, \href {https://stefan-kohl.github.io/rcwa.html} {\texttt{https://stefan\texttt{\symbol{45}}kohl.github.io/}\discretionary {}{}{}\texttt{rcwa.html}}}, printedkey = {Koh17} } @manual{ ResClasses, author = {Kohl, S.}, title = {{ResClasses \texttt{\symbol{45}} Set\texttt{\symbol{45}}Theoretic Computations with Residue Classes (Version 4.6.0)}}, year = {2017}, note = {GAP package, \href {https://stefan-kohl.github.io/resclasses.html} {\texttt{https://stefan\texttt{\symbol{45}}kohl.github.io/}\discretionary {}{}{}\texttt{resclasses.html}}}, printedkey = {Koh17} } @manual{ XMod, author = {Wensley, C. D. and Alp, M. and Odabas, A. and Uslu, E. O.}, title = {{XMod \texttt{\symbol{45}} Crossed Modules and Cat1\texttt{\symbol{45}}groups in GAP (Version 2.64)}}, year = {2017}, note = {GAP package, \href {https://github.com/gap-packages/xmod} {\texttt{https://github.com/}\discretionary {}{}{}\texttt{gap\texttt{\symbol{45}}packages/}\discretionary {}{}{}\texttt{xmod}}}, printedkey = {WAOU17} } utils-0.86/doc/chapInd.html000644 000765 000024 00000021222 14621610515 020714 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Index
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

Index

AllIsomorphisms 7.1-1
AllIsomorphismsIterator 7.1-1
AllIsomorphismsNumber 7.1-1
AllProducts 4.1-2
AllSmoothIntegers 4.1-1 4.1-1
AllSubgroupsIterator 7.1-2
AssignGlobals 8.1-1
BlankFreeString 3.3-1
CartesianIterator 7.2-1
CentralProduct 5.3-3
CentralProductInfo 5.3-3
Comm 5.1-1
CommonRepresentatives 3.2-1
CommonTransversal 3.2-1
ConvertToMagmaInputString 10.3-1
CreateDirIfMissing 11.1
DifferencesList 3.1-1
DirectProductOfAutomorphismGroups 5.3-6
DirectProductOfFunctions 5.3-5
DirectSumDecompositionMatrices 6.1-1
distinct and common representatives 3.2
DistinctRepresentatives 3.2-1
Download 9.1-1
DownloadVerifyCertificate 9.1-2
EpimorphismByGenerators 5.3-1
ExponentOfPrime 11.3-2
FindMatchingFiles 11.1
Fitting series 5.1-5
FittingLength 5.1-5
FloatQuotientsList 3.1-2
GeneratorsAndInverses 5.1-4
GetSuffix 11.1
GitHub repository 1.
IdempotentEndomorphisms 5.3-4
IdempotentEndomorphismsData 5.3-4
IdempotentEndomorphismsWithImage 5.3-4
IntOrOnfinityToLaTeX 10.2-1
IsCommonTransversal 3.2-1
IsCommuting 5.1-2
Iterators 7.1
LaTeXStringFactorsInt 10.2-2
LeftCoset 5.2-1
ListOfPowers 5.1-3
Log2HTML 10.1-1
LowerFittingSeries 5.1-5
MatrixGroupToMagmaFormat 10.3-1
NextProbablyPrimeInt 4.1-4
OKtoReadFromUtils 12.
OptionRecordWithDefaults 8.2-1
PcGroupToMagmaFormat 10.3-1
PermGroupToMagmaFormat 10.3-1
PrimeNumbersIterator 4.1-5
PrintApplicableMethod 11.3-1
PrintOneItemPerLine 11.2
PrintSelection 2.1-1 2.1-1
Pullback 5.3-2
PullbackInfo 5.3-2
QuotientsList 3.1-2
RandomCombination 3.1-4
RestrictedPartitionsWithoutRepetitions 4.1-3
SearchCycle 3.1-3
SetIfMissing 11.1
smooth integer 4.1-1
StringDotSuffix 11.1
UnorderedPairsIterator 7.2-2
UpperFittingSeries 5.1-5

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap3_mj.html000644 000765 000024 00000041001 14621610515 021027 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 3: Lists, Sets and Strings
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

3 Lists, Sets and Strings

3.1 Functions for lists

3.1-1 DifferencesList
‣ DifferencesList( L )( function )

This function has been transferred from package ResClasses.

It takes a list \(L\) of length \(n\) and outputs the list of length \(n-1\) containing all the differences \(L[i]-L[i-1]\).


gap> List( [1..12], n->n^3 );
[ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728 ]
gap> DifferencesList( last );
[ 7, 19, 37, 61, 91, 127, 169, 217, 271, 331, 397 ]
gap> DifferencesList( last );
[ 12, 18, 24, 30, 36, 42, 48, 54, 60, 66 ]
gap> DifferencesList( last );
[ 6, 6, 6, 6, 6, 6, 6, 6, 6 ]

3.1-2 QuotientsList
‣ QuotientsList( L )( function )
‣ FloatQuotientsList( L )( function )

These functions have been transferred from package ResClasses.

They take a list \(L\) of length \(n\) and output the quotients \(L[i]/L[i-1]\) of consecutive entries in \(L\). An error is returned if an entry is zero.


gap> List( [0..10], n -> Factorial(n) );
[ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ]
gap> QuotientsList( last );
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
gap> L := [ 1, 3, 5, -1, -3, -5 ];;
gap> QuotientsList( L );
[ 3, 5/3, -1/5, 3, 5/3 ]
gap> FloatQuotientsList( L );
[ 3., 1.66667, -0.2, 3., 1.66667 ]
gap> QuotientsList( [ 2, 1, 0, -1, -2 ] );
[ 1/2, 0, fail, 2 ]
gap> FloatQuotientsList( [1..10] );
[ 2., 1.5, 1.33333, 1.25, 1.2, 1.16667, 1.14286, 1.125, 1.11111 ]
gap> Product( last );
10. 

3.1-3 SearchCycle
‣ SearchCycle( L )( operation )

This function has been transferred from package RCWA.

SearchCycle is a tool to find likely cycles in lists. What, precisely, a cycle is, is deliberately fuzzy here, and may possibly even change. The idea is that the beginning of the list may be anything, following that the same pattern needs to be repeated several times in order to be recognized as a cycle.


gap> L := [1..20];;  L[1]:=13;;                                              
gap> for i in [1..19] do                                                     
>        if IsOddInt(L[i]) then L[i+1]:=3*L[i]+1; else L[i+1]:=L[i]/2; fi;
>    od;                                                                  
gap> L;                                                                      
[ 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4 ]
gap> SearchCycle( L );                                                       
[ 1, 4, 2 ]
gap> n := 1;;  L := [n];;
gap> for i in [1..100] do  n:=(n^2+1) mod 1093;  Add(L,n);  od;
gap> L; 
[ 1, 2, 5, 26, 677, 363, 610, 481, 739, 715, 795, 272, 754, 157, 604, 848, 
  1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 
  211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 
  378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 
  754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 
  848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 
  271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004 ]
gap> C := SearchCycle( L );
[ 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754 ]
gap> P := Positions( L, 157 );
[ 14, 26, 38, 50, 62, 74, 86, 98 ]
gap> Length( C );  DifferencesList( P );
12
[ 12, 12, 12, 12, 12, 12, 12 ]

3.1-4 RandomCombination
‣ RandomCombination( S, k )( operation )

This function has been transferred from package ResClasses.

It returns a random unordered \(k\)-tuple of distinct elements of a set \(S\).


gap> ## "6 aus 49" is a common lottery in Germany
gap> RandomCombination( [1..49], 6 ); 
[ 2, 16, 24, 26, 37, 47 ]

3.2 Distinct and Common Representatives

3.2-1 DistinctRepresentatives
‣ DistinctRepresentatives( list )( operation )
‣ CommonRepresentatives( list )( operation )
‣ CommonTransversal( grp, subgrp )( operation )
‣ IsCommonTransversal( grp, subgrp, list )( operation )

These operations have been transferred from package XMod.

They deal with lists of subsets of \([1 \ldots n]\) and construct systems of distinct and common representatives using simple, non-recursive, combinatorial algorithms.

When \(L\) is a set of \(n\) subsets of \([1 \ldots n]\) and the Hall condition is satisfied (the union of any \(k\) subsets has at least \(k\) elements), a set of DistinctRepresentatives exists.

When \(J,K\) are both lists of \(n\) sets, the operation CommonRepresentatives returns two lists: the set of representatives, and a permutation of the subsets of the second list.

The operation CommonTransversal may be used to provide a common transversal for the sets of left and right cosets of a subgroup \(H\) of a group \(G\), although a greedy algorithm is usually quicker.


gap> J := [ [1,2,3], [3,4], [3,4], [1,2,4] ];;
gap> DistinctRepresentatives( J );
[ 1, 3, 4, 2 ]
gap> K := [ [3,4], [1,2], [2,3], [2,3,4] ];;
gap> CommonRepresentatives( J, K );
[ [ 3, 3, 3, 1 ], [ 1, 3, 4, 2 ] ]
gap> d16 := DihedralGroup( IsPermGroup, 16 ); 
Group([ (1,2,3,4,5,6,7,8), (2,8)(3,7)(4,6) ])
gap> SetName( d16, "d16" );
gap> c4 := Subgroup( d16, [ d16.1^2 ] ); 
Group([ (1,3,5,7)(2,4,6,8) ])
gap> SetName( c4, "c4" );
gap> RightCosets( d16, c4 );
[ RightCoset(c4,()), RightCoset(c4,(2,8)(3,7)(4,6)), RightCoset(c4,(1,8,7,6,5,
   4,3,2)), RightCoset(c4,(1,8)(2,7)(3,6)(4,5)) ]
gap> trans := CommonTransversal( d16, c4 );
[ (), (2,8)(3,7)(4,6), (1,2,3,4,5,6,7,8), (1,2)(3,8)(4,7)(5,6) ]
gap> IsCommonTransversal( d16, c4, trans );
true

3.3 Functions for strings

3.3-1 BlankFreeString
‣ BlankFreeString( obj )( function )

This function has been transferred from package ResClasses.

The result of BlankFreeString( obj ); is a composite of the functions String( obj ) and RemoveCharacters( obj, " " );.


gap> gens := GeneratorsOfGroup( DihedralGroup(12) );
[ f1, f2, f3 ]
gap> String( gens );                                
"[ f1, f2, f3 ]"
gap> BlankFreeString( gens );                       
"[f1,f2,f3]"

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/bib.xml000644 000765 000024 00000006312 14621444241 017742 0ustar00christopherwensleystaff000000 000000 SebastianGutsche MaxHorn <C>AutoDoc - Generate documentation from GAP source code (Version 2016.12.04)</C> 2016 GAP package, https://github.com/gap-packages/AutoDoc FrankLübeck MaxNeunhöffer <C>GAPDoc (Version 1.6)</C> RWTH Aachen 2017 GAP package, https://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/index.html MaxHorn <C>GitHubPagesForGAP - Template for easily using GitHub Pages within GAP packages (Version 0.2)</C> 2017 GAP package, https://gap-system.github.io/GitHubPagesForGAP/ http://magma.maths.usyd.edu.au/magma/ WiebBosma JohnCannon CatherinePlayoust <C>The Magma algebra system. {I}. The user language</C> Computational algebra and number theory (London, 1993)} https://doi.org/10.1006/jsco.1996.0125 J. Symbolic Comput. 24 1997 3-4 235--265 0747-7171 68Q40 MR1484478 10.1006/jsco.1996.0125 StefanKohl <C>RCWA - Residue-Class-Wise Affine Groups (Version 4.5.1)</C> 2017 GAP package, https://stefan-kohl.github.io/rcwa.html StefanKohl <C>ResClasses - Set-Theoretic Computations with Residue Classes (Version 4.6.0)</C> 2017 GAP package, https://stefan-kohl.github.io/resclasses.html Chris D.Wensley MuratAlp AlperOdabas Enver OnderUslu <C>XMod - Crossed Modules and Cat1-groups in GAP (Version 2.64)</C> 2017 GAP package, https://github.com/gap-packages/xmod utils-0.86/doc/chapInd.txt000644 000765 000024 00000004623 14621610512 020572 0ustar00christopherwensleystaff000000 000000 Index AllIsomorphisms 7.1-1 AllIsomorphismsIterator 7.1-1 AllIsomorphismsNumber 7.1-1 AllProducts 4.1-2 AllSmoothIntegers 4.1-1 4.1-1 AllSubgroupsIterator 7.1-2 AssignGlobals 8.1-1 BlankFreeString 3.3-1 CartesianIterator 7.2-1 CentralProduct 5.3-3 CentralProductInfo 5.3-3 Comm 5.1-1 CommonRepresentatives 3.2-1 CommonTransversal 3.2-1 ConvertToMagmaInputString 10.3-1 CreateDirIfMissing 11.1 DifferencesList 3.1-1 DirectProductOfAutomorphismGroups 5.3-6 DirectProductOfFunctions 5.3-5 DirectSumDecompositionMatrices 6.1-1 distinct and common representatives 3.2 DistinctRepresentatives 3.2-1 Download 9.1-1 DownloadVerifyCertificate 9.1-2 EpimorphismByGenerators 5.3-1 ExponentOfPrime 11.3-2 FindMatchingFiles 11.1 Fitting series 5.1-5 FittingLength 5.1-5 FloatQuotientsList 3.1-2 GeneratorsAndInverses 5.1-4 GetSuffix 11.1 GitHub repository 1.0 IdempotentEndomorphisms 5.3-4 IdempotentEndomorphismsData 5.3-4 IdempotentEndomorphismsWithImage 5.3-4 IntOrOnfinityToLaTeX 10.2-1 IsCommonTransversal 3.2-1 IsCommuting 5.1-2 Iterators 7.1 LaTeXStringFactorsInt 10.2-2 LeftCoset 5.2-1 ListOfPowers 5.1-3 Log2HTML 10.1-1 LowerFittingSeries 5.1-5 MatrixGroupToMagmaFormat 10.3-1 NextProbablyPrimeInt 4.1-4 OKtoReadFromUtils 12.0 OptionRecordWithDefaults 8.2-1 PcGroupToMagmaFormat 10.3-1 PermGroupToMagmaFormat 10.3-1 PrimeNumbersIterator 4.1-5 PrintApplicableMethod 11.3-1 PrintOneItemPerLine 11.2 PrintSelection 2.1-1 2.1-1 Pullback 5.3-2 PullbackInfo 5.3-2 QuotientsList 3.1-2 RandomCombination 3.1-4 RestrictedPartitionsWithoutRepetitions 4.1-3 SearchCycle 3.1-3 SetIfMissing 11.1 smooth integer 4.1-1 StringDotSuffix 11.1 UnorderedPairsIterator 7.2-2 UpperFittingSeries 5.1-5 ------------------------------------------------------- utils-0.86/doc/chap12.txt000644 000765 000024 00000013105 14621610512 020275 0ustar00christopherwensleystaff000000 000000 12 The transfer procedure We consider here the process for transferring utility functions from a package Home to Utils which has to avoid the potential problem of duplicate declarations of a function causing loading problems in GAP. If the functions in Home all have names of the form HOME_FunctionName then, in Utils, these functions are likely to be renamed as FunctionName or something similar. In this case the problem of duplicate declarations does not arise. This is what has happened with transfers from the AutoDoc package. The case where the function names are unchanged is more complicated. Initially we tried out a process which allowed repeated declarations and installations of the functions being transferred. This involved additions to the main library files global.g and oper.g. Since there were misgivings about interfering in this way with basic operations such as BIND_GLOBAL, a simpler (but slightly less convenient) process has been adopted. Using this alternative procedure, the following steps will be followed when making transfers from Home to Utils. 1 (Home:) Offer functions for inclusion. This may be simply done by emailing a list of functions. More usefully, email the declaration, implementation, test and documentation files, e.g.: home.gd, home.gi, home.tst and home.xml. (All active authors should be involved.) 2 (Home:) Declare that m.n is the last version of Home to contain these functions, so that m.n+1 (or similar) will be the first version of Home to have all these functions removed, and to specify Utils as a required package. 3 (Utils:) Add strings "home" and "m.n" to the list UtilsPackageVersions in the file utils/lib/start.gd.   Example   UtilsPackageVersions :=   [ "autodoc", "2016.01.31",   "resclasses", "4.2.5",   "home", "m.n",  ..., ...   ];   While the transfers are being made, it is essential that any new versions of Home should be tested with the latest version of Utils before they are released, so as to avoid loading failures. 4 (Utils:) Include the function declaration and implementation sections in suitable files, enclosed within a conditional clause of the form:   Example   if OKtoReadFromUtils( "Home" ) then . . . . . .    . . . . . .  fi;   The function OKtoReadFromUtils returns true only if there is an installed version of Home and if this version is greater than m.n. So, at this stage, the copied code will not be read, and the transferred functions can only be called if Home has been installed. 5 (Utils:) Add the test and documentation material to the appropriate files. The copied code can be tested by temporarily moving Home away from GAP's package directory. 6 (Utils:) Release a new version of Utils containing all the transferred material. 7 (Home:) Edit out the declarations and implementations of all the transferred functions, and remove references to them in the manual and tests. Possibly add a note to the manual that these functions have been transferred. Add Utils to the list of Home's required packages in PackageInfo.g. Release a new version of Home. 8 (Utils:) In due course, when the new version(s) of Home are well established, it may be safe to remove the conditional clauses mentioned in item 4 above. The entry for Home in UtilsPackageLists may then be removed. Finally, a note on the procedure for testing these functions. As long as a function being transferred still exists in the Home package, the code will not be read from Utils. So, when the tests are run, it is necessary to LoadPackage("home") before the function is called. The file utils/tst/testall.g makes sure that all the necessary packages are loaded before the individual tests are called. utils-0.86/doc/chap4.html000644 000765 000024 00000030177 14621610515 020356 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 4: Number-theoretic functions
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

4 Number-theoretic functions

4.1 Functions for integers

4.1-1 AllSmoothIntegers
‣ AllSmoothIntegers( maxp, maxn )( function )
‣ AllSmoothIntegers( L, maxp )( function )

This function has been transferred from package RCWA.

The function AllSmoothIntegers(maxp,maxn) returns the list of all positive integers less than or equal to maxn whose prime factors are all in the list L = {p ~|~ p leqslant maxp, p~mboxprime }.

In the alternative form, when L is a list of primes, the function returns the list of all positive integers whose prime factors lie in L.


gap> AllSmoothIntegers( 3, 1000 );
[ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96, 
  108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576, 
  648, 729, 768, 864, 972 ]
gap> AllSmoothIntegers( [5,11,17], 1000 );
[ 1, 5, 11, 17, 25, 55, 85, 121, 125, 187, 275, 289, 425, 605, 625, 935 ]
gap> Length( last );
16
gap> List( [3..20], n -> Length( AllSmoothIntegers( [5,11,17], 10^n ) ) );
[ 16, 29, 50, 78, 114, 155, 212, 282, 359, 452, 565, 691, 831, 992, 1173, 
  1374, 1595, 1843 ]

4.1-2 AllProducts
‣ AllProducts( L, k )( function )

This function has been transferred from package RCWA.

The command AllProducts(L,k) returns the list of all products of k entries of the list L. Note that every ordering of the entries is used so that, in the commuting case, there are bound to be repetitions.


gap> AllProducts([1..4],3); 
[ 1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16, 2, 4, 6, 8, 4, 8, 12, 
  16, 6, 12, 18, 24, 8, 16, 24, 32, 3, 6, 9, 12, 6, 12, 18, 24, 9, 18, 27, 
  36, 12, 24, 36, 48, 4, 8, 12, 16, 8, 16, 24, 32, 12, 24, 36, 48, 16, 32, 
  48, 64 ]
gap> Set(last);            
[ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 64 ]
gap> AllProducts( [(1,2,3),(2,3,4)], 2 );
[ (2,4,3), (1,2)(3,4), (1,3)(2,4), (1,3,2) ]

4.1-3 RestrictedPartitionsWithoutRepetitions
‣ RestrictedPartitionsWithoutRepetitions( n, S )( function )

This function has been transferred from package RCWA.

For a positive integer n and a set of positive integers S, this function returns the list of partitions of n into distinct elements of S. Unlike RestrictedPartitions, no repetitions are allowed.


gap> RestrictedPartitions( 20, [4..10] );
[ [ 4, 4, 4, 4, 4 ], [ 5, 5, 5, 5 ], [ 6, 5, 5, 4 ], [ 6, 6, 4, 4 ], 
  [ 7, 5, 4, 4 ], [ 7, 7, 6 ], [ 8, 4, 4, 4 ], [ 8, 6, 6 ], [ 8, 7, 5 ], 
  [ 8, 8, 4 ], [ 9, 6, 5 ], [ 9, 7, 4 ], [ 10, 5, 5 ], [ 10, 6, 4 ], 
  [ 10, 10 ] ]
gap> RestrictedPartitionsWithoutRepetitions( 20, [4..10] );
[ [ 10, 6, 4 ], [ 9, 7, 4 ], [ 9, 6, 5 ], [ 8, 7, 5 ] ]
gap> RestrictedPartitionsWithoutRepetitions( 10^2, List([1..10], n->n^2 ) );
[ [ 100 ], [ 64, 36 ], [ 49, 25, 16, 9, 1 ] ]

4.1-4 NextProbablyPrimeInt
‣ NextProbablyPrimeInt( n )( function )

This function has been transferred from package RCWA.

The function NextProbablyPrimeInt(n) does the same as NextPrimeInt(n) except that for reasons of performance it tests numbers only for IsProbablyPrimeInt(n) instead of IsPrimeInt(n). For large n, this function is much faster than NextPrimeInt(n)


gap> n := 2^251;
3618502788666131106986593281521497120414687020801267626233049500247285301248
gap> NextProbablyPrimeInt( n );
3618502788666131106986593281521497120414687020801267626233049500247285301313
gap> time;                     
1
gap> NextPrimeInt( n );        
3618502788666131106986593281521497120414687020801267626233049500247285301313
gap> time;             
213

4.1-5 PrimeNumbersIterator
‣ PrimeNumbersIterator( [chunksize] )( function )

This function has been transferred from package RCWA.

This function returns an iterator which runs over the prime numbers n ascending order; it takes an optional argument chunksize which specifies the length of the interval which is sieved in one go (the default is 10^7), and which can be used to balance runtime vs. memory consumption. It is assumed that chunksize is larger than any gap between two consecutive primes within the range one intends to run the iterator over.


gap> iter := PrimeNumbersIterator();;
gap> for i in [1..100] do  p := NextIterator(iter);  od;
gap> p;
541
gap> sum := 0;;
gap> ## "prime number race" 1 vs. 3 mod 4
gap> for p in PrimeNumbersIterator() do 
>       if p <> 2 then sum := sum + E(4)^(p-1); fi;
>       if sum > 0 then break; fi;
>    od;
gap> p;
26861

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/others.xml000644 000765 000024 00000011413 14621444241 020510 0ustar00christopherwensleystaff000000 000000 Various other functions
File operations This function has been transferred from package &RCWA;.

This function converts the &GAP; logfile filename to HTML. It appears that the logfile should be in your current directory. The extension of the input file must be *.log. The name of the output file is the same as the one of the input file except that the extension *.log is replaced by *.html. There is a sample CSS file in utils/doc/gaplog.css, which you can adjust to your taste.

LogTo( "triv.log" ); gap> a := 33^5; 39135393 gap> LogTo(); gap> Log2HTML( "triv.log" ); ]]>

&LaTeX; strings This function has been transferred from package &ResClasses;.

IntOrInfinityToLaTeX(n) returns the &LaTeX; string for n.

IntOrInfinityToLaTeX( 10^3 ); "1000" gap> IntOrInfinityToLaTeX( infinity ); "\\infty" ]]> This function has been transferred from package &RCWA;.

It returns the prime factorization of the integer n as a string in &LaTeX; format.

LaTeXStringFactorsInt( Factorial(12) ); "2^{10} \\cdot 3^5 \\cdot 5^2 \\cdot 7 \\cdot 11" ]]>

Conversion to &Magma; string The function ConvertToMagmaInputString( obj [, str] ) attempts to output a string s which can be read into &Magma; so as to produce the same group in that computer algebra system. In the second form the user specifies the name of the resulting object, so that the output string has the form "str := ...". When obj is a permutation group, the operation PermGroupToMagmaFormat(obj) is called. PermGroupToMagmaFormat This function has been taken from other.gi in the main library where it was called MagmaInputString. When obj is a pc-group, the operation PcGroupToMagmaFormat(obj) is called. PcGroupToMagmaFormat This function was private code of Max Horn. When obj is a matrix group over a finite field, the operation MatrixGroupToMagmaFormat(obj) is called. MatrixGroupToMagmaFormat This function is a modification of private code of Frank Lübeck.

Hopefully code for other types of group will be added in due course.

These functions should be considered experimental, and more testing is desirable.

ConvertToMagmaInputString( Group( (1,2,3,4,5), (3,4,5) ) ); "PermutationGroup<5|(1,2,3,4,5),\n(3,4,5)>;\n" gap> ConvertToMagmaInputString( Group( (1,2,3,4,5) ), "c5" ); "c5:=PermutationGroup<5|(1,2,3,4,5)>;\n" gap> ConvertToMagmaInputString( DihedralGroup( IsPcGroup, 10 ) ); "PolycyclicGroup< f1,f2 |\nf1^2,\nf2^5,\nf2^f1 = f2^4\n>;\n" gap> M := GL(2,5);; Size(M); 480 gap> s1 := ConvertToMagmaInputString( M ); "F := GF(5);\nP := GL(2,F);\ngens := [\nP![2,0,0,1],\nP![4,1,4,0]\n];\nsub

;\n" gap> Print( s1 ); F := GF(5); P := GL(2,F); gens := [ P![2,0,0,1], P![4,1,4,0] ]; sub

; gap> n1 := [ [ Z(9)^0, Z(9)^0 ], [ Z(9)^0, Z(9) ] ];; gap> n2 := [ [ Z(9)^0, Z(9)^3 ], [ Z(9)^4, Z(9)^2 ] ];; gap> N := Group( n1, n2 );; Size( N ); 5760 gap> s2 := ConvertToMagmaInputString( N, "gpN" );; gap> Print( s2 ); F := GF(3^2); P := GL(2,F); w := PrimitiveElement(F); gens := [ P![ 1, 1, 1,w^1], P![ 1,w^3, 2,w^2] ]; gpN := sub

; ]]>

utils-0.86/doc/chap10.txt000644 000765 000024 00000013466 14621610512 020305 0ustar00christopherwensleystaff000000 000000 10 Various other functions 10.1 File operations 10.1-1 Log2HTML Log2HTML( filename )  function This function has been transferred from package RCWA. This function converts the GAP logfile filename to HTML. It appears that the logfile should be in your current directory. The extension of the input file must be *.log. The name of the output file is the same as the one of the input file except that the extension *.log is replaced by *.html. There is a sample CSS file in utils/doc/gaplog.css, which you can adjust to your taste.  Example   gap> LogTo( "triv.log" ); gap> a := 33^5; 39135393 gap> LogTo();  gap> Log2HTML( "triv.log" );    10.2 LaTeX strings 10.2-1 IntOrOnfinityToLaTeX IntOrOnfinityToLaTeX( n )  function This function has been transferred from package ResClasses. IntOrInfinityToLaTeX(n) returns the LaTeX string for n.  Example   gap> IntOrInfinityToLaTeX( 10^3 ); "1000" gap> IntOrInfinityToLaTeX( infinity ); "\\infty"   10.2-2 LaTeXStringFactorsInt LaTeXStringFactorsInt( n )  function This function has been transferred from package RCWA. It returns the prime factorization of the integer n as a string in LaTeX format.  Example   gap> LaTeXStringFactorsInt( Factorial(12) ); "2^{10} \\cdot 3^5 \\cdot 5^2 \\cdot 7 \\cdot 11"   10.3 Conversion to Magma string 10.3-1 ConvertToMagmaInputString ConvertToMagmaInputString( arg )  function The function ConvertToMagmaInputString( obj [, str] ) attempts to output a string s which can be read into Magma [BCP97] so as to produce the same group in that computer algebra system. In the second form the user specifies the name of the resulting object, so that the output string has the form "str := ...". When obj is a permutation group, the operation PermGroupToMagmaFormat(obj) is called. This function has been taken from other.gi in the main library where it was called MagmaInputString. When obj is a pc-group, the operation PcGroupToMagmaFormat(obj) is called. This function was private code of Max Horn. When obj is a matrix group over a finite field, the operation MatrixGroupToMagmaFormat(obj) is called. This function is a modification of private code of Frank Lübeck. Hopefully code for other types of group will be added in due course. These functions should be considered experimental, and more testing is desirable.  Example   gap> ConvertToMagmaInputString( Group( (1,2,3,4,5), (3,4,5) ) ); "PermutationGroup<5|(1,2,3,4,5),\n(3,4,5)>;\n" gap> ConvertToMagmaInputString( Group( (1,2,3,4,5) ), "c5" );  "c5:=PermutationGroup<5|(1,2,3,4,5)>;\n" gap> ConvertToMagmaInputString( DihedralGroup( IsPcGroup, 10 ) ); "PolycyclicGroup< f1,f2 |\nf1^2,\nf2^5,\nf2^f1 = f2^4\n>;\n" gap> M := GL(2,5);; Size(M);  480 gap> s1 := ConvertToMagmaInputString( M ); "F := GF(5);\nP := GL(2,F);\ngens := [\nP![2,0,0,1],\nP![4,1,4,0]\n];\nsub

;\n" gap> Print( s1 ); F := GF(5); P := GL(2,F); gens := [ P![2,0,0,1], P![4,1,4,0] ]; sub

; gap> n1 := [ [ Z(9)^0, Z(9)^0 ], [ Z(9)^0, Z(9) ] ];; gap> n2 := [ [ Z(9)^0, Z(9)^3 ], [ Z(9)^4, Z(9)^2 ] ];; gap> N := Group( n1, n2 );; Size( N ); 5760 gap> s2 := ConvertToMagmaInputString( N, "gpN" );; gap> Print( s2 ); F := GF(3^2); P := GL(2,F); w := PrimitiveElement(F); gens := [ P![ 1, 1, 1,w^1], P![ 1,w^3, 2,w^2] ]; gpN := sub

;   utils-0.86/doc/chap11.txt000644 000765 000024 00000010414 14621610512 020274 0ustar00christopherwensleystaff000000 000000 11 Obsolete functions 11.1 Operations from AutoDoc The file functions FindMatchingFiles and CreateDirIfMissing were copied from package AutoDoc where they are named AutoDoc_FindMatchingFiles and AutoDoc_CreateDirIfMissing. The string function StringDotSuffix was also copied from package AutoDoc, where it is named AUTODOC_GetSuffix. The function SetIfMissing was also transferred from package AutoDoc, where it is called AUTODOC_SetIfMissing. It writes into a record provided the position is not yet bound. As from version 0.61, all these functions became obsolete in Utils, but continue to be defined in AutoDoc. 11.2 Functions for printing The function PrintOneItemPerLine was used to prints lists vertically, rather than horizontally. Since a very similar result may be achieved using the GAP library functions Perform and Display, this function became obsolete in version 0.61.  Example   gap> s3 := SymmetricGroup( 3 );;  gap> L := KnownPropertiesOfObject( GeneratorsOfGroup( s3 ) );; gap> Perform( L, Display ); IsFinite IsSmallList IsGeneratorsOfMagmaWithInverses IsGeneratorsOfSemigroup IsSubsetLocallyFiniteGroup gap> Perform( s3, Display );  () (2,3) (1,3) (1,3,2) (1,2,3) (1,2)   11.3 Other obsolete functions 11.3-1 Applicable Methods The function PrintApplicableMethod, which was included in versions from 0.41 to 0.58, has been removed since it was considered superfluous. The example shows how to print out a function.  Example   gap> ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 1, 1 ); #I Searching Method for IsCyclic with 1 arguments: #I Total: 7 entries #I Method 4: ``IsCyclic'' at /Applications/gap/gap4r9/lib/grp.gi:30 , value:  36 function( G ) ... end gap> Print( last ); function ( G )  if Length( GeneratorsOfGroup( G ) ) = 1 then  return true;  else  TryNextMethod();  fi;  return; end gap> ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 0, 3 ); function( <1 unnamed arguments> ) ... end gap> Print( last );  function ( <> )  <> end   11.3-2 ExponentOfPrime The function ExponentOfPrime was originally transferred from package RCWA. The command ExponentOfPrime(n,p) returned the exponent of the prime p in the prime factorization of n. Since the GAP function PValuation produces the same results, and does so more quickly, this function has been made obsolete. utils-0.86/doc/chap8.html000644 000765 000024 00000023004 14621610515 020351 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 8: Records

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

8 Records

8.1 Functions for records

8.1-1 AssignGlobals
‣ AssignGlobals( rec )( function )

This function has been transferred from package RCWA.

It assigns the record components of rec to global variables with the same names.


gap> r := rec( a := 1, b := 2, c := 3 );;                                      
gap> AssignGlobals( r );
The following global variables have been assigned:
[ "a", "b", "c" ]
gap> [a,b,c];
[ 1, 2, 3 ]

8.2 Option records for functions

8.2-1 OptionRecordWithDefaults
‣ OptionRecordWithDefaults( defaults, useroptions )( function )

This functions has been transferred by Chris Jefferson from other packages. It simplifies the handling of records which are intended to be used for expressing configuration options. defaults represents the "default record", and useroptions lets the user give new values for values in defaults.

The function returns a record with the same component names as defaults and which has the same values as defaults, except for those component names in useroptions, where the values in useroptions are used instead. An error is given if useroptions contains any component names not in defaults. If useroptions is an empty list it is treated as an empty record, and if useroptions is a list of length 1 containing a record, this record is used as useroptions.


gap> defaults := rec( a := 1, b := 2, c := 3 );;
gap> OptionRecordWithDefaults( defaults, rec( a := 6) );
rec( a := 6, b := 2, c := 3 )
gap> OptionRecordWithDefaults( defaults, rec( b := 7, c := 8 ) );
rec( a := 1, b := 7, c := 8 )
gap> OptionRecordWithDefaults( defaults, [ ] );
rec( a := 1, b := 2, c := 3 )
gap> OptionRecordWithDefaults( defaults, [ rec( c := 8 ) ] );
rec( a := 1, b := 2, c := 8 )
gap> OptionRecordWithDefaults( defaults, rec( d := 9 ) );
Error, Unknown option: d
gap> OptionRecordWithDefaults( defaults, [ rec( b := 7 ), rec( c := 8 ) ] );
Error, Too many arguments for function
gap> OptionRecordWithDefaults( defaults, [6,7,8] );
Error, Too many arguments for function

This function is designed to support functions with optional arguments given as a variable record, of the form function(x,y,options...). In the following, very contrived, example function, PrintDimensions, the defaults are given by the variable order which takes values h, w and d having default values 1, 2 and 3. If there is a second argument, then OptionRecordWithDefaults( order, arg[2] ); is used to cvhange the values. These three values then determine the order in which the three dimensions are printed using a SortParallel command.


PrintDimensions := function( arg ) 
    local nargs, dim, order, V, L, len, K, i; 
    nargs := Length( arg ); 
    dim := [ arg[1]!.height, arg[1]!.width, arg[1]!.depth ]; 
    order := rec( h := 1, w := 2, d := 3 ); 
    V := [ "height", "width", "depth" ]; 
    if ( nargs > 1 ) and IsRecord( arg[2] ) then 
        order := OptionRecordWithDefaults( order, arg[2] ); 
    fi; 
    L := [ order!.h, order!.w, order!.d ]; 
    len := Length( L );
    K := [ 1..len ]; 
    SortParallel( L, K ); 
    Print( "dimensions: " ); 
    Print( V[K[1]], " = ", dim[K[1]], ", " );
    Print( V[K[2]], " = ", dim[K[2]], ", " );
    Print( V[K[3]], " = ", dim[K[3]], "\n" );
end;;

In the example below the first call to PrintDimensions has just one parameter, mydim, so the default order is used. In the second call, alternate values for h, w and d are given, causing the width to be printed first, and then the depth and height.


gap> mydim := rec( height := 45, width := 31, depth := 17 ); 
rec( depth := 17, height := 45, width := 31 )
gap> PrintDimensions( mydim );
dimensions: height = 45, width = 31, depth = 17
gap> PrintDimensions( mydim, rec( h:=3, w:=1, d:=2 ) );
dimensions: width = 31, depth = 17, height = 45

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/nocolorprompt.css000644 000765 000024 00000000313 14621610515 022105 0ustar00christopherwensleystaff000000 000000 /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000000; font-weight: normal; } span.GAPbrkprompt { color: #000000; font-weight: normal; } span.GAPinput { color: #000000; } utils-0.86/doc/lefttoc.css000644 000765 000024 00000000474 14621610515 020640 0ustar00christopherwensleystaff000000 000000 /* leftmenu.css Frank Lübeck */ /* Change default CSS to show section menu on left side */ body { padding-left: 28%; } body.chap0 { padding-left: 2%; } div.ChapSects div.ContSect:hover div.ContSSBlock { left: 15%; } div.ChapSects { left: 1%; width: 25%; } utils-0.86/doc/chap9.html000644 000765 000024 00000022165 14621610515 020361 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 9: Web Downloads
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

9 Web Downloads

The Download operation has been written by Thomas Breuer, incorporating a number of suggestions from Max Horn, for version 0.77 of Utils. It implements downloading a file from within GAP. It can use the IO or curlInterface packages, or wget or curl, if installed, and it can be extended with other download methods quite easily. It is envisaged that, once other packages have started to use it, and any problems have been addressed, that the functions will be transferred to the main GAP library.

9.1 Functions for downloading files from the web

9.1-1 Download
‣ Download( url[, opt] )( function )

This function downloads the file with the web address url, which must be a string.

The result is a record which has at least the component success, with value true if the download was successful and false otherwise. In the former case, the component result is bound, whose value is a string that contains the contents of the downloaded file. In the latter case, the component error is bound, whose value is a string that describes the problem.

The function calls the methods stored in the global list Download_Methods until one of them is successful. Currently there are methods based on the GAP functions DownloadURL (curl: DownloadURL) and SingleHTTPRequest (IO: SingleHTTPRequest), and methods based on the external programs wget and curl.

An optional record opt can be given. The following components are supported.

target

If this component is bound then its value must be a string that is a local filename, and the function writes the downloaded contents to this file; the returned record does not have a result component in this case.

verifyCert

If this component is bound and has the value false then those download methods that are based on curl or wget will omit the check of the server's certificate. The same effect is achieved for all Download calls by setting the user preference DownloadVerifyCertificate (see 9.1-2) to false and omitting the verifyCert component from opt.


gap> url:= "https://www.gap-system.org/Packages/utils.html";;
gap> res1:= Download( url );;
gap> res1.success;
true
gap> IsBound( res1.result ) and IsString( res1.result );
true
gap> res2:= Download( Concatenation( url, "xxx" ) );;
gap> res2.success;
false
gap> IsBound( res2.error ) and IsString( res2.error );
true

9.1-2 User preference DownloadVerifyCertificate

The value true (the default) means that the server's certificate is checked in calls of Download (9.1-1), such that nothing gets downloaded if the certificate is invalid.

If the value is false then download methods are supposed to omit the check of the server's certificate (this may not be supported by all download methods).

One can set the value of the preference to be val via SetUserPreference (Reference: SetUserPreference), by calling SetUserPreference( "utils", "DownloadVerifyCertificate", val ), and access the current value via UserPreference (Reference: UserPreference), by calling UserPreference( "utils", "DownloadVerifyCertificate" ).

We recommend leaving this preference at its default value true. Sometimes it can be necessary to change it, e.g. to work around issues with old operating systems which may not be able to correctly verify new certificates. In general it is better to update such a system, but if that is not an option, then disabling certificate checks may be a good last resort.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/intro.xml000644 000765 000024 00000011663 14621444241 020346 0ustar00christopherwensleystaff000000 000000 Introduction The &Utils; package provides a space for utility functions from a variety of &GAP; packages to be collected together into a single package. In this way it is hoped that they will become more visible to other package authors. This package was first distributed as part of the &GAP; 4.8.2 distribution.

The package is loaded with the command LoadPackage( "utils" ); ]]>

Functions have been transferred from the following packages: Conversion of a &GAP; group to a &Magma; output string, taken from various sources including other.gi in the main library.

Transfer is complete (for now) for functions from the following packages: &AutoDoc; (with function names changed); &ResClasses; ; &RCWA; ; &XMod; .

The package may be obtained either as a compressed .tar file or as a .zip file, utils-version_number.tar.gz, by ftp from one of the following sites: the &Utils; GitHub release site: https://gap-packages.github.io/utils/. any &GAP; archive, e.g. https://www.gap-system.org/Packages/packages.html; GitHub repository The package also has a GitHub repository at: https://github.com/gap-packages/utils.

Once the package is loaded, the manual doc/manual.pdf can be found in the documentation folder. The html versions, with or without &MathJax;, may be rebuilt as follows:

ReadPackage( "utils", "makedoc.g" ); ]]>

It is possible to check that the package has been installed correctly by running the test files (which terminates the &GAP; session):

ReadPackage( "utils", "tst/testall.g" ); Architecture: . . . . . testing: . . . . . . . . #I No errors detected while testing ]]>

Note that functions listed in this manual that are currently in the process of being transferred are only read from the source package &Home; (say), and so can only be used if &Home; has already been loaded. There are no such functions in transition at present.

Information for package authors A function (or collection of functions) is suitable for transfer from a package &Home; to &Utils; if the following conditions are satisfied. The function is sufficiently non-specialised so that it might be of use to other authors. The function does not depend on the remaining functions in &Home; The function does not do what can already be done with a &GAP; library function. Documentation of the function and test examples are available. When there is more than one active author of &Home;, they should all be aware (and content) that the transfer is taking place.

Authors of packages may be reluctant to let go of their utility functions. The following principles may help to reassure them. (Suggestions for more items here are welcome.) A function that has been transferred to &Utils; will not be changed without the approval of the original author. The current package maintainer has every intention of continuing to maintain &Utils;. In the event that this proves impossible, the &GAP; development team will surely find someone to take over. Function names will not be changed unless specifically requested by &Home;'s author(s) or unless they have the form HOME_FunctionName. In order to speed up the transfer process, only functions from one package will be in transition at any given time. Hopefully a week or two will suffice for most packages. Any package author who transfers a function to &Utils; will become an author of &Utils;. (In truth, &Utils; does not have authors, just a large number of contributors.)

The process for transferring utility functions from &Home; to &Utils; is described in Chapter .

utils-0.86/doc/matrix.xml000644 000765 000024 00000007731 14621444241 020520 0ustar00christopherwensleystaff000000 000000 Matrices
Some operations for matrices In June 2023 Hongyi Zhao asked in the Forum for a function to implement matrix decomposition into blocks. Such a function was then provided by Pedro García-Sánchez. Hongyi Zhao then requested that the function be added to Utils. What is provided here is a revised version of the original solution, returning a list of decompositions.

This function is a partial inverse to the undocumented library operation DirectSumMat. So if L is the list of diagonal decompositions of a matrix M then each entry in L is a list of matrices, and the direct sum of each of these lists is equal to the original M.

In the following examples, M_6 is an obvious direct sum with 3 blocks. M_4 is an example with three decompositions, while M_8 = M_4 \oplus M_4 has 16 decompositions (not listed).

M6 := [ [1,2,0,0,0,0], [3,4,0,0,0,0], [5,6,0,0,0,0], > [0,0,9,0,0,0], [0,0,0,1,2,3], [0,0,0,4,5,6] ];; gap> Display( M6 ); [ [ 1, 2, 0, 0, 0, 0 ], [ 3, 4, 0, 0, 0, 0 ], [ 5, 6, 0, 0, 0, 0 ], [ 0, 0, 9, 0, 0, 0 ], [ 0, 0, 0, 1, 2, 3 ], [ 0, 0, 0, 4, 5, 6 ] ] gap> L6 := DirectSumDecompositionMatrices( M6 ); [ [ [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ], [ [ 9 ] ], [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] ] ] gap> M4 := [ [0,3,0,0], [0,0,0,0], [0,0,0,0], [0,0,4,0] ];; gap> Display( M4 ); [ [ 0, 3, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 4, 0 ] ] gap> L4 := DirectSumDecompositionMatrices( M4 ); [ [ [ [ 0, 3 ] ], [ [ 0, 0 ], [ 0, 0 ], [ 4, 0 ] ] ], [ [ [ 0, 3 ], [ 0, 0 ] ], [ [ 0, 0 ], [ 4, 0 ] ] ], [ [ [ 0, 3 ], [ 0, 0 ], [ 0, 0 ] ], [ [ 4, 0 ] ] ] ] gap> for L in L4 do > A := DirectSumMat( L );; > if ( A = M4 ) then Print( "yes, A = M4\n" ); fi; > od; yes, A = M4 yes, A = M4 yes, A = M4 gap> M8 := DirectSumMat( M4, M4 );; gap> Display( M8 ); [ [ 0, 3, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 4, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 3, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 4, 0 ] ] gap> L8 := DirectSumDecompositionMatrices( M8 );; gap> Length( L8 ); 16 ]]>

The current method does not, however, catch all possible decompositions. In the following example the matrix M_5 has its third row and third column extirely zero, and the only decomposition found has a [0] factor. There are clearly two 2-factor decompositions with a 2-by-3 and a 3-by-2 factor, but these are not found at present.

M5 := [ [1,2,0,0,0], [3,4,0,0,0], [0,0,0,0,0], > [0,0,0,6,7], [0,0,0,8,9] ];; gap> Display(M5); [ [ 1, 2, 0, 0, 0 ], [ 3, 4, 0, 0, 0 ], [ 0, 0, 0, 0, 0 ], [ 0, 0, 0, 6, 7 ], [ 0, 0, 0, 8, 9 ] ] gap> L5 := DirectSumDecompositionMatrices( M5 ); [ [ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 0 ] ], [ [ 6, 7 ], [ 8, 9 ] ] ] ] ]]>

utils-0.86/doc/chap2_mj.html000644 000765 000024 00000013630 14621610515 021035 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 2: Printing Lists and Iterators
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

2 Printing Lists and Iterators

2.1 Printing selected items

The functions described here print lists or objects with an iterator with one item per line, either the whole list/iterator or certain subsets:

  • by giving a list of positions of items to be printed, or

  • by specifying a first item and then a regular step.

2.1-1 PrintSelection
‣ PrintSelection( obj, first, step[, last] )( function )
‣ PrintSelection( obj, list )( function )

This function, given three (or four) parameters, calls operations PrintSelectionFromList or PrintSelectionFromIterator which prints the first item specified, and then the item at every step. The fourth parameter is essential when the object being printed is infinite.

Alternatively, given two parameters, with the second parameter a list L of positive integers, only the items at positions in L are printed.


gap> L := List( [1..20], n -> n^5 );;
gap> PrintSelection( L, [18..20] );
18 : 1889568
19 : 2476099
20 : 3200000
gap> PrintSelection( L, 2, 9 );       
2 : 32
11 : 161051
20 : 3200000
gap> PrintSelection( L, 2, 3, 11 );
2 : 32
5 : 3125
8 : 32768
11 : 161051
gap> s5 := SymmetricGroup( 5 );;
gap> PrintSelection( s5, [30,31,100,101] );
30 : (1,5)(3,4)
31 : (1,5,2)
100 : (1,4,3)
101 : (1,4)(3,5)
gap> PrintSelection( s5, 1, 30 );
1 : ()
31 : (1,5,2)
61 : (1,2,3)
91 : (1,3,5,2,4)
gap> PrintSelection( s5, 9, 11, 43 );
9 : (2,5,3)
20 : (2,4)
31 : (1,5,2)
42 : (1,5,2,3,4)

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap5.html000644 000765 000024 00000103715 14621610515 020356 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 5: Groups and homomorphisms
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

5 Groups and homomorphisms

5.1 Functions for groups

5.1-1 Comm
‣ Comm( L )( operation )

This method has been transferred from package ResClasses.

It provides a method for Comm when the argument is a list (enclosed in square brackets), and calls the function LeftNormedComm.


gap> Comm( [ (1,2), (2,3) ] );
(1,2,3)
gap> Comm( [(1,2),(2,3),(3,4),(4,5),(5,6)] );
(1,5,6)
gap> Comm(Comm(Comm(Comm((1,2),(2,3)),(3,4)),(4,5)),(5,6));  ## the same
(1,5,6)

5.1-2 IsCommuting
‣ IsCommuting( a, b )( operation )

This function has been transferred from package ResClasses.

It tests whether two elements in a group commute.


gap> D12 := DihedralGroup( 12 );
<pc group of size 12 with 3 generators>
gap> SetName( D12, "D12" ); 
gap> a := D12.1;;  b := D12.2;;  
gap> IsCommuting( a, b );
false

5.1-3 ListOfPowers
‣ ListOfPowers( g, exp )( operation )

This function has been transferred from package RCWA.

The operation ListOfPowers(g,exp) returns the list [g,g^2,...,g^exp] of powers of the element g.


gap> ListOfPowers( 2, 20 );
[ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
 32768, 65536, 131072, 262144, 524288, 1048576 ]
gap> ListOfPowers( (1,2,3)(4,5), 12 );
[ (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), (),
 (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), () ]
gap> ListOfPowers( D12.2, 6 );
[ f2, f3, f2*f3, f3^2, f2*f3^2, <identity> of ... ]

5.1-4 GeneratorsAndInverses
‣ GeneratorsAndInverses( G )( operation )

This function has been transferred from package RCWA.

This operation returns a list containing the generators of G followed by the inverses of these generators.


gap> GeneratorsAndInverses( D12 );
[ f1, f2, f3, f1, f2*f3^2, f3^2 ]
gap> GeneratorsAndInverses( SymmetricGroup(5) );     
[ (1,2,3,4,5), (1,2), (1,5,4,3,2), (1,2) ]

5.1-5 UpperFittingSeries
‣ UpperFittingSeries( G )( attribute )
‣ LowerFittingSeries( G )( attribute )
‣ FittingLength( G )( attribute )

These three functions have been transferred from package ResClasses.

The upper and lower Fitting series and the Fitting length of a solvable group are described here: https://en.wikipedia.org/wiki/Fitting_length.


gap> UpperFittingSeries( D12 );  LowerFittingSeries( D12 );
[ Group([  ]), Group([ f3, f2*f3 ]), Group([ f1, f3, f2*f3 ]) ]
[ D12, Group([ f3 ]), Group([  ]) ]
gap> FittingLength( D12 );
2
gap> S4 := SymmetricGroup( 4 );;
gap> UpperFittingSeries( S4 );
[ Group(()), Group([ (1,2)(3,4), (1,4)(2,3) ]), Group([ (1,2)(3,4), (1,4)
  (2,3), (2,4,3) ]), Group([ (3,4), (2,3,4), (1,2)(3,4) ]) ]
gap> List( last, StructureDescription );
[ "1", "C2 x C2", "A4", "S4" ]
gap> LowerFittingSeries( S4 );
[ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,3)
 (2,4) ]), Group(()) ]
gap> List( last, StructureDescription );
[ "S4", "A4", "C2 x C2", "1" ]
gap> FittingLength( S4);
3

5.2 Left Cosets for Groups

5.2-1 LeftCoset
‣ LeftCoset( g, U )( operation )

Since GAP uses right actions by default, the library contains the operation RightCoset(U,g) for constructing the right coset Ug of a subgroup U ≤ G and an element g ∈ G. It has been noted in the reference manual that, by inverting all the elements in Ug, the left coset g^-1U is obtained.

Just for the sake of completeness, from August 2022 this package provides the operation LeftCoset(g,U) for constructing the left coset gU. Users are strongly recommended to continue to use RightCoset for all serious calculations, since left cosets have a much simpler implementation and do not behave exactly like right cosets.

The methods for left cosets which are provided generally work by converting gU to Ug^-1; applying the equivalent method for right cosets; and, if necessary, converting back again to left cosets.

G acts on gU by OnLeftInverse: (gU)^g_0 = g_0^-1*(gU) = (g_0^-1g)U.


gap> lc1 := LeftCoset( (1,2,3), Group( [ (1,2), (3,4) ] ) ); 
LeftCoset((1,2,3),Group([ (1,2), (3,4) ]))
gap> Representative( lc1 );
(1,2,3)
gap> ActingDomain( lc1 );
Group([ (1,2), (3,4) ])
gap> AsSet( lc1 );
[ (2,3), (2,4,3), (1,2,3), (1,2,4,3) ]
gap> (1,2,3) in lc1;
true
gap> lc2 := (2,4,3) * lc1;   
LeftCoset((1,2,4),Group([ (1,2), (3,4) ]))
gap> lc3 := lc1^(2,3,4);;
gap> lc2 = lc3;            
true

5.2-2 Inverse

The inverse of the left coset gU is the right coset Ug^-1, and conversely. This is an abuse of the attribute Inverse, since the standard requirement, that x*x^-1 is an identity, does not hold.


gap> rc1 := Inverse( lc1 ); 
RightCoset(Group([ (1,2), (3,4) ]),(1,3,2))
gap> rc4 := RightCoset( Group( (1,2), (2,3) ), (3,4) ); 
RightCoset(Group([ (1,2), (2,3) ]),(3,4))
gap> lc4 := Inverse( rc4 );
LeftCoset((3,4),Group([ (1,2), (2,3) ]))
gap> Intersection( lc2, lc4 );
[ (2,3,4), (1,2,3,4) ]

5.3 Functions for group homomorphisms

5.3-1 EpimorphismByGenerators
‣ EpimorphismByGenerators( G, H )( operation )

This function has been transferred from package RCWA.

It constructs a group homomorphism which maps the generators of G to those of H. Its intended use is when G is a free group, and a warning is printed when this is not the case. Note that anything may happen if the resulting map is not a homomorphism!


gap> G := Group( (1,2,3), (3,4,5), (5,6,7), (7,8,9) );;
gap> phi := EpimorphismByGenerators( FreeGroup("a","b","c","d"), G );
[ a, b, c, d ] -> [ (1,2,3), (3,4,5), (5,6,7), (7,8,9) ]
gap> PreImagesRepresentativeNC( phi, (1,2,3,4,5,6,7,8,9) );
d*c*b*a
gap> a := G.1;; b := G.2;; c := G.3;; d := G.4;;
gap> d*c*b*a;
(1,2,3,4,5,6,7,8,9)
gap> ## note that it is easy to produce nonsense: 
gap> epi := EpimorphismByGenerators( Group((1,2,3)), Group((8,9)) );
Warning: calling GroupHomomorphismByImagesNC without checks
[ (1,2,3) ] -> [ (8,9) ]
gap> IsGroupHomomorphism( epi );
true
gap> Image( epi, (1,2,3) );                                            
()
gap> Image( epi, (1,3,2) );
(8,9)

5.3-2 Pullback
‣ Pullback( hom1, hom2 )( operation )
‣ PullbackInfo( G )( attribute )

If ϕ_1 : G_1 -> H and ϕ_2 : G_2 -> H are two group homomorphisms with the same range, then their pullback is the subgroup of G_1 × G_2 consisting of those elements (g_1,g_2) such that ϕ_1 g_1 = ϕ_2 g_2.

The attribute PullbackInfo of a pullback group P is similar to DirectProductInfo for a direct product of groups. Its value is a record with the following components:

directProduct

the direct product G_1 × G_2, and

projections

a list with the two projections onto G_1 and G_2.

There are no embeddings in this record, but it is possible to use the embeddings into the direct product, see Embedding (Reference: Embedding).


gap> s4 := Group( (1,2),(2,3),(3,4) );;
gap> s3 := Group( (5,6),(6,7) );;
gap> c3 := Subgroup( s3, [ (5,6,7) ] );;
gap> f := GroupHomomorphismByImages( s4, s3, 
>             [(1,2),(2,3),(3,4)], [(5,6),(6,7),(5,6)] );; 
gap> i := GroupHomomorphismByImages( c3, s3, [(5,6,7)], [(5,6,7)] );; 
gap> Pfi := Pullback( f, i );
Group([ (2,3,4)(5,7,6), (1,2)(3,4) ])
gap> StructureDescription( Pfi );
"A4"
gap> info := PullbackInfo( Pfi );
rec( directProduct := Group([ (1,2), (2,3), (3,4), (5,6,7) ]), 
  projections := [ [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (2,3,4), (1,2)(3,4) ], 
      [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (5,7,6), () ] ] )
gap> g := (1,2,3)(5,6,7);; 
gap> ImageElm( info!.projections[1], g );
(1,2,3)
gap> ImageElm( info!.projections[2], g );
(5,6,7) 
gap> dp := info!.directProduct;; 
gap> a := ImageElm( Embedding( dp, 1 ), (1,4,3) );; 
gap> b := ImageElm( Embedding( dp, 2 ), (5,7,6) );; 
gap> a*b in Pfi;
true

5.3-3 CentralProduct
‣ CentralProduct( G1, G2, Z1, Phi )( operation )
‣ CentralProductInfo( G )( attribute )

This function was added by Thomas Breuer, following discussions with Hongyi Zhao (see https://github.com/gap-packages/hap/issues/73).

Let G1 and G2 be two groups, Z1 be a central subgroup of G1, and Phi be an isomorphism from Z1 to a central subgroup of G2. The central product defined by these arguments is the factor group of the direct product of G1 and G2 by the central subgroup { (z, (Phi(z))^-1) : z ∈ Z1 }.

The attribute CentralProductInfo of a group G that has been created by CentralProduct is similar to PullbackInfo (5.3-2) for pullback groups. Its value is a record with the following components.

projection

the epimorphism from the direct product of G1 and G2 to G, and

phi

the map Phi.

Note that one can access the direct product as the Source (Reference: Source) value of the projection map, and one can access G1 and G2 as the two embeddings of this direct product, see Embedding (Reference: Embedding).

gap> g1 := DihedralGroup( 8 );
<pc group of size 8 with 3 generators>
gap> c1 := Centre( g1 );
Group([ f3 ])
gap> cp1 := CentralProduct( g1, g1, c1, IdentityMapping( c1 ) );
Group([ f1, f2, f5, f3, f4, f5 ])
gap> IdGroup( cp1 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) );
true
gap> g2 := QuaternionGroup( 8 );
<pc group of size 8 with 3 generators>
gap> c2 := Centre( g2 );
Group([ y2 ])
gap> cp2 := CentralProduct( g2, g2, c2, IdentityMapping( c2 ) );
Group([ f1, f2, f5, f3, f4, f5 ])
gap> IdGroup( cp2 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) );
true
gap> info2 := CentralProductInfo( cp2 );
rec( phi := IdentityMapping( Group([ y2 ]) ), 
  projection := [ f1, f2, f3, f4, f5, f6 ] -> [ f1, f2, f5, f3, f4, f5 ] )
gap> Source( Embedding( Source( info2.projection ), 1 ) ) = g2;
true

5.3-4 IdempotentEndomorphisms
‣ IdempotentEndomorphisms( G )( operation )
‣ IdempotentEndomorphismsData( G )( attribute )
‣ IdempotentEndomorphismsWithImage( genG, R )( operation )

An endomorphism f : G -> G is idempotent if f^2=f. It has an image R leqslant G; is the identity map when restricted to R; and has a kernel N which has trivial intersection with R and has size |G|/|R|.

The operation IdempotentEndomorphismsWithImage(genG,R) returns a list of the images of the generating set genG of a group G under the idempotent endomorphisms with image R.

The attribute IdempotentEndomorphismsData(G) returns a record data with fields data.gens, a fixed generating set for G, and data.images a list of the non-empty outputs of IdempotentEndomorphismsWithImage(genG,R) obtained by iterating over all subgroups of G.

The operation IdempotentEndomorphisms(G) returns the list of these mappings obtained using IdempotentEndomorphismsData(G). The first of these is the zero map, the second is the identity.


gap> gens := [ (1,2,3,4), (1,2)(3,4) ];; 
gap> d8 := Group( gens );;
gap> SetName( d8, "d8" );
gap> c2 := Subgroup( d8, [ (2,4) ] );;
gap> IdempotentEndomorphismsWithImage( gens, c2 );
[ [ (), (2,4) ], [ (2,4), () ] ]
gap> IdempotentEndomorphismsData( d8 );
rec( gens := [ (1,2,3,4), (1,2)(3,4) ], 
  images := [ [ [ (), () ] ], [ [ (), (2,4) ], [ (2,4), () ] ], 
      [ [ (), (1,3) ], [ (1,3), () ] ], 
      [ [ (), (1,2)(3,4) ], [ (1,2)(3,4), (1,2)(3,4) ] ], 
      [ [ (), (1,4)(2,3) ], [ (1,4)(2,3), (1,4)(2,3) ] ], 
      [ [ (1,2,3,4), (1,2)(3,4) ] ] ] )
gap> List( last.images, L -> Length(L) );
[ 1, 2, 2, 2, 2, 1 ]
gap> IdempotentEndomorphisms( d8 );               
[ [ (1,2,3,4), (1,2)(3,4) ] -> [ (), () ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (2,4) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (2,4), () ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,3) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,3), () ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,2)(3,4) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2)(3,4), (1,2)(3,4) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,4)(2,3) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,4)(2,3), (1,4)(2,3) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2,3,4), (1,2)(3,4) ] ]

The quaternion group q8 is an example of a group with a tail: there is only one subgroup in the lattice which covers the identity subgroup. The only idempotent isomorphisms of such groups are the identity mapping and the zero mapping because the only pairs N,R are the whole group and the identity subgroup.


gap> q8 := QuaternionGroup( 8 );;
gap> IdempotentEndomorphisms( q8 );
[ [ x, y ] -> [ <identity> of ..., <identity> of ... ], [ x, y ] -> [ x, y ] ]

5.3-5 DirectProductOfFunctions
‣ DirectProductOfFunctions( G, H, f1, f2 )( operation )

Given group homomorphisms f_1 : G_1 -> G_2 and f_2 : H_1 -> H_2, this operation return the product homomorphism f_1 × f_2 : G_1 × G_2 -> H_1 × H_2.


gap> c4 := Group( (1,2,3,4) );; 
gap> c2 := Group( (5,6) );; 
gap> f1 := GroupHomomorphismByImages( c4, c2, [(1,2,3,4)], [(5,6)] );;
gap> c3 := Group( (1,2,3) );; 
gap> c6 := Group( (1,2,3,4,5,6) );; 
gap> f2 := GroupHomomorphismByImages( c3, c6, [(1,2,3)], [(1,3,5)(2,4,6)] );; 
gap> c4c3 := DirectProduct( c4, c3 ); 
Group([ (1,2,3,4), (5,6,7) ])
gap> c2c6 := DirectProduct( c2, c6 ); 
Group([ (1,2), (3,4,5,6,7,8) ])
gap> f := DirectProductOfFunctions( c4c3, c2c6, f1, f2 ); 
[ (1,2,3,4), (5,6,7) ] -> [ (1,2), (3,5,7)(4,6,8) ]
gap> ImageElm( f, (1,4,3,2)(5,7,6) ); 
(1,2)(3,7,5)(4,8,6)

5.3-6 DirectProductOfAutomorphismGroups
‣ DirectProductOfAutomorphismGroups( A1, A2 )( operation )

Let A_1,A_2 be groups of automorphism of groups G_1,G_2 respectively. The output of this function is a group A_1 × A_2 of automorphisms of G_1 × G_2.


gap> c9 := Group( (1,2,3,4,5,6,7,8,9) );; 
gap> ac9 := AutomorphismGroup( c9 );; 
gap> q8 := QuaternionGroup( IsPermGroup, 8 );;
gap> aq8 := AutomorphismGroup( q8 );;
gap> A := DirectProductOfAutomorphismGroups( ac9, aq8 );
<group with 5 generators>
gap> genA := GeneratorsOfGroup( A );;
gap> G := Source( genA[1] );
Group([ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)
(14,15,16,17) ])
gap> a := genA[1]*genA[5];  
[ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)(14,15,16,17) 
 ] -> [ (1,3,5,7,9,2,4,6,8), (10,16,12,14)(11,15,13,17), 
  (10,11,12,13)(14,15,16,17) ]
gap> ImageElm( a, (1,9,8,7,6,5,4,3,2)(10,14,12,16)(11,17,13,15) );
(1,8,6,4,2,9,7,5,3)(10,16,12,14)(11,15,13,17)

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/transfer.xml000644 000765 000024 00000011463 14621444241 021035 0ustar00christopherwensleystaff000000 000000 The transfer procedure We consider here the process for transferring utility functions from a package &Home; to &Utils; which has to avoid the potential problem of duplicate declarations of a function causing loading problems in &GAP;.

If the functions in &Home; all have names of the form HOME_FunctionName then, in &Utils;, these functions are likely to be renamed as FunctionName or something similar. In this case the problem of duplicate declarations does not arise. This is what has happened with transfers from the &AutoDoc; package.

The case where the function names are unchanged is more complicated. Initially we tried out a process which allowed repeated declarations and installations of the functions being transferred. This involved additions to the main library files global.g and oper.g. Since there were misgivings about interfering in this way with basic operations such as BIND_GLOBAL, a simpler (but slightly less convenient) process has been adopted.

Using this alternative procedure, the following steps will be followed when making transfers from &Home; to &Utils;. (&Home;:) Offer functions for inclusion. This may be simply done by emailing a list of functions. More usefully, email the declaration, implementation, test and documentation files, e.g.: home.gd, home.gi, home.tst and home.xml. (All active authors should be involved.) (&Home;:) Declare that m.n is the last version of &Home; to contain these functions, so that m.n+1 (or similar) will be the first version of &Home; to have all these functions removed, and to specify &Utils; as a required package. (&Utils;:) Add strings "home" and "m.n" to the list UtilsPackageVersions in the file utils/lib/start.gd. While the transfers are being made, it is essential that any new versions of &Home; should be tested with the latest version of &Utils; before they are released, so as to avoid loading failures. (&Utils;:) Include the function declaration and implementation sections in suitable files, enclosed within a conditional clause of the form: . . . . . . fi; ]]> OKtoReadFromUtils The function OKtoReadFromUtils returns true only if there is an installed version of &Home; and if this version is greater than m.n. So, at this stage, the copied code will not be read, and the transferred functions can only be called if &Home; has been installed. (&Utils;:) Add the test and documentation material to the appropriate files. The copied code can be tested by temporarily moving &Home; away from &GAP;'s package directory. (&Utils;:) Release a new version of &Utils; containing all the transferred material. (&Home;:) Edit out the declarations and implementations of all the transferred functions, and remove references to them in the manual and tests. Possibly add a note to the manual that these functions have been transferred. Add &Utils; to the list of &Home;'s required packages in PackageInfo.g. Release a new version of &Home;. (&Utils;:) In due course, when the new version(s) of &Home; are well established, it may be safe to remove the conditional clauses mentioned in item 4 above. The entry for &Home; in UtilsPackageLists may then be removed.

Finally, a note on the procedure for testing these functions. As long as a function being transferred still exists in the &Home; package, the code will not be read from &Utils;. So, when the tests are run, it is necessary to LoadPackage("home") before the function is called. The file utils/tst/testall.g makes sure that all the necessary packages are loaded before the individual tests are called. utils-0.86/doc/manual.lab000644 000765 000024 00000015745 14621610515 020432 0ustar00christopherwensleystaff000000 000000 \GAPDocLabFile{utils} \makelabel{utils:Title page}{}{X7D2C85EC87DD46E5} \makelabel{utils:Abstract}{}{X7AA6C5737B711C89} \makelabel{utils:Copyright}{}{X81488B807F2A1CF1} \makelabel{utils:Acknowledgements}{}{X82A988D47DFAFCFA} \makelabel{utils:Table of Contents}{}{X8537FEB07AF2BEC8} \makelabel{utils:Introduction}{1}{X7DFB63A97E67C0A1} \makelabel{utils:Information for package authors}{1.1}{X8508AD637B79CEE8} \makelabel{utils:Printing Lists and Iterators}{2}{X83686EE47E4D4F66} \makelabel{utils:Printing selected items}{2.1}{X7F6817927F86240F} \makelabel{utils:Lists, Sets and Strings}{3}{X7AE6EFC086C0EB3C} \makelabel{utils:Functions for lists}{3.1}{X7C3F1E7D878AAA65} \makelabel{utils:Distinct and Common Representatives}{3.2}{X82F443FF84B8FCE3} \makelabel{utils:Functions for strings}{3.3}{X8033A2FE80FC2F2A} \makelabel{utils:Number-theoretic functions}{4}{X86E71C1687F2D0AD} \makelabel{utils:Functions for integers}{4.1}{X7D33B5B17BF785CA} \makelabel{utils:Groups and homomorphisms}{5}{X8171DAF2833FF728} \makelabel{utils:Functions for groups}{5.1}{X7E21E6D285E6B12C} \makelabel{utils:Left Cosets for Groups}{5.2}{X7FE4848B7DE6B3FD} \makelabel{utils:Inverse}{5.2.2}{X793E48267EF5FD77} \makelabel{utils:Functions for group homomorphisms}{5.3}{X80A512877F515DE7} \makelabel{utils:Matrices}{6}{X812CCAB278643A59} \makelabel{utils:Some operations for matrices}{6.1}{X802118FB7C94D6BA} \makelabel{utils:Iterators}{7}{X85A3F00985453F95} \makelabel{utils:Some iterators for groups and their isomorphisms}{7.1}{X7BB5350081B27D17} \makelabel{utils:Operations on iterators}{7.2}{X85413EED812C6497} \makelabel{utils:Records}{8}{X7AA1073C7E943DD7} \makelabel{utils:Functions for records}{8.1}{X82B3D1D583CDF0E5} \makelabel{utils:Option records for functions}{8.2}{X7E6207B47B9AA30C} \makelabel{utils:Web Downloads}{9}{X815B0C4B7EBE6E1E} \makelabel{utils:Functions for downloading files from the web}{9.1}{X8758CB7F79EFB6ED} \makelabel{utils:User preference DownloadVerifyCertificate}{9.1.2}{X85182BA486E3C2AA} \makelabel{utils:Various other functions}{10}{X83EFC3178180D918} \makelabel{utils:File operations}{10.1}{X81A0A4FF842B039B} \makelabel{utils:LaTeX strings}{10.2}{X84D2922D87EDE9E9} \makelabel{utils:Conversion to Magma string}{10.3}{X7BDFFBC379DE83E6} \makelabel{utils:Obsolete functions}{11}{X7F561B1D803182FF} \makelabel{utils:Operations from AutoDoc}{11.1}{X7A6BB3D084912F35} \makelabel{utils:Functions for printing}{11.2}{X86F322FC7DECE36F} \makelabel{utils:Other obsolete functions}{11.3}{X84A4F0B281FA0F94} \makelabel{utils:Applicable Methods}{11.3.1}{X78B7D1A982BE9866} \makelabel{utils:ExponentOfPrime}{11.3.2}{X7C1AF2467FB55D79} \makelabel{utils:The transfer procedure}{12}{X84AC9613842F014C} \makelabel{utils:Bibliography}{Bib}{X7A6F98FD85F02BFE} \makelabel{utils:References}{Bib}{X7A6F98FD85F02BFE} \makelabel{utils:Index}{Ind}{X83A0356F839C696F} \makelabel{utils:GitHub repository}{1}{X7DFB63A97E67C0A1} \makelabel{utils:PrintSelection}{2.1.1}{X7997C991826D0191} \makelabel{utils:PrintSelection}{2.1.1}{X7997C991826D0191} \makelabel{utils:DifferencesList}{3.1.1}{X78B7C92681D2F13C} \makelabel{utils:QuotientsList}{3.1.2}{X7975371E865B89BC} \makelabel{utils:FloatQuotientsList}{3.1.2}{X7975371E865B89BC} \makelabel{utils:SearchCycle}{3.1.3}{X86096E73858CFABD} \makelabel{utils:RandomCombination}{3.1.4}{X7EF06CAD7F35245D} \makelabel{utils:distinct and common representatives}{3.2}{X82F443FF84B8FCE3} \makelabel{utils:DistinctRepresentatives}{3.2.1}{X78105CAA847A888C} \makelabel{utils:CommonRepresentatives}{3.2.1}{X78105CAA847A888C} \makelabel{utils:CommonTransversal}{3.2.1}{X78105CAA847A888C} \makelabel{utils:IsCommonTransversal}{3.2.1}{X78105CAA847A888C} \makelabel{utils:BlankFreeString}{3.3.1}{X870C964E7804B266} \makelabel{utils:AllSmoothIntegers}{4.1.1}{X802064F37D50F46A} \makelabel{utils:AllSmoothIntegers}{4.1.1}{X802064F37D50F46A} \makelabel{utils:smooth integer}{4.1.1}{X802064F37D50F46A} \makelabel{utils:AllProducts}{4.1.2}{X78BE6B8B878D250D} \makelabel{utils:RestrictedPartitionsWithoutRepetitions}{4.1.3}{X845F46E579CEA43F} \makelabel{utils:NextProbablyPrimeInt}{4.1.4}{X81708BF4858505E8} \makelabel{utils:PrimeNumbersIterator}{4.1.5}{X8021EEE5787FCA37} \makelabel{utils:Comm}{5.1.1}{X80761843831B468E} \makelabel{utils:IsCommuting}{5.1.2}{X803A050C7A183CCC} \makelabel{utils:ListOfPowers}{5.1.3}{X87A8F01286548037} \makelabel{utils:GeneratorsAndInverses}{5.1.4}{X820B71307E41BEE5} \makelabel{utils:UpperFittingSeries}{5.1.5}{X84CF95227F9D562F} \makelabel{utils:LowerFittingSeries}{5.1.5}{X84CF95227F9D562F} \makelabel{utils:FittingLength}{5.1.5}{X84CF95227F9D562F} \makelabel{utils:Fitting series}{5.1.5}{X84CF95227F9D562F} \makelabel{utils:LeftCoset}{5.2.1}{X8340B4537F17DCD3} \makelabel{utils:EpimorphismByGenerators}{5.3.1}{X80C9A0B583FEA7B9} \makelabel{utils:Pullback}{5.3.2}{X7C705F2A79F8E43C} \makelabel{utils:PullbackInfo}{5.3.2}{X7C705F2A79F8E43C} \makelabel{utils:CentralProduct}{5.3.3}{X78DD2C617B992BE2} \makelabel{utils:CentralProductInfo}{5.3.3}{X78DD2C617B992BE2} \makelabel{utils:IdempotentEndomorphisms}{5.3.4}{X801038CB808FC956} \makelabel{utils:IdempotentEndomorphismsData}{5.3.4}{X801038CB808FC956} \makelabel{utils:IdempotentEndomorphismsWithImage}{5.3.4}{X801038CB808FC956} \makelabel{utils:DirectProductOfFunctions}{5.3.5}{X81FA9E6C7F3B9238} \makelabel{utils:DirectProductOfAutomorphismGroups}{5.3.6}{X7CB2D5F27F4182AF} \makelabel{utils:DirectSumDecompositionMatrices}{6.1.1}{X787B89237E1398B6} \makelabel{utils:Iterators}{7.1}{X7BB5350081B27D17} \makelabel{utils:AllIsomorphismsIterator}{7.1.1}{X7F8B54D1806C762D} \makelabel{utils:AllIsomorphismsNumber}{7.1.1}{X7F8B54D1806C762D} \makelabel{utils:AllIsomorphisms}{7.1.1}{X7F8B54D1806C762D} \makelabel{utils:AllSubgroupsIterator}{7.1.2}{X831DA5AE8437578F} \makelabel{utils:CartesianIterator}{7.2.1}{X87395A9181A35301} \makelabel{utils:UnorderedPairsIterator}{7.2.2}{X7C95E27987A812EA} \makelabel{utils:AssignGlobals}{8.1.1}{X84D82EB579B2ACCD} \makelabel{utils:OptionRecordWithDefaults}{8.2.1}{X8322B9377CC590D2} \makelabel{utils:Download}{9.1.1}{X7A7438AE8448635E} \makelabel{utils:DownloadVerifyCertificate}{9.1.2}{X85182BA486E3C2AA} \makelabel{utils:Log2HTML}{10.1.1}{X7B7ECADF85F748BE} \makelabel{utils:IntOrOnfinityToLaTeX}{10.2.1}{X87DEB2B58266F858} \makelabel{utils:LaTeXStringFactorsInt}{10.2.2}{X7DC642B97CD02F4E} \makelabel{utils:ConvertToMagmaInputString}{10.3.1}{X8768D7707B4CBBD4} \makelabel{utils:PermGroupToMagmaFormat}{10.3.1}{X8768D7707B4CBBD4} \makelabel{utils:PcGroupToMagmaFormat}{10.3.1}{X8768D7707B4CBBD4} \makelabel{utils:MatrixGroupToMagmaFormat}{10.3.1}{X8768D7707B4CBBD4} \makelabel{utils:FindMatchingFiles}{11.1}{X7A6BB3D084912F35} \makelabel{utils:CreateDirIfMissing}{11.1}{X7A6BB3D084912F35} \makelabel{utils:StringDotSuffix}{11.1}{X7A6BB3D084912F35} \makelabel{utils:GetSuffix}{11.1}{X7A6BB3D084912F35} \makelabel{utils:SetIfMissing}{11.1}{X7A6BB3D084912F35} \makelabel{utils:PrintOneItemPerLine}{11.2}{X86F322FC7DECE36F} \makelabel{utils:PrintApplicableMethod}{11.3.1}{X78B7D1A982BE9866} \makelabel{utils:ExponentOfPrime}{11.3.2}{X7C1AF2467FB55D79} \makelabel{utils:OKtoReadFromUtils}{12}{X84AC9613842F014C} utils-0.86/doc/chap6.html000644 000765 000024 00000020137 14621610515 020353 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 6: Matrices

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

6 Matrices

6.1 Some operations for matrices

6.1-1 DirectSumDecompositionMatrices
‣ DirectSumDecompositionMatrices( M )( operation )

In June 2023 Hongyi Zhao asked in the Forum for a function to implement matrix decomposition into blocks. Such a function was then provided by Pedro García-Sánchez. Hongyi Zhao then requested that the function be added to Utils. What is provided here is a revised version of the original solution, returning a list of decompositions.

This function is a partial inverse to the undocumented library operation DirectSumMat. So if L is the list of diagonal decompositions of a matrix M then each entry in L is a list of matrices, and the direct sum of each of these lists is equal to the original M.

In the following examples, M_6 is an obvious direct sum with 3 blocks. M_4 is an example with three decompositions, while M_8 = M_4 ⊕ M_4 has 16 decompositions (not listed).


gap> M6 := [ [1,2,0,0,0,0], [3,4,0,0,0,0], [5,6,0,0,0,0],                       
>            [0,0,9,0,0,0], [0,0,0,1,2,3], [0,0,0,4,5,6] ];;
gap> Display( M6 );
[ [  1,  2,  0,  0,  0,  0 ],
  [  3,  4,  0,  0,  0,  0 ],
  [  5,  6,  0,  0,  0,  0 ],
  [  0,  0,  9,  0,  0,  0 ],
  [  0,  0,  0,  1,  2,  3 ],
  [  0,  0,  0,  4,  5,  6 ] ]
gap> L6 := DirectSumDecompositionMatrices( M6 );
[ [ [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ], [ [ 9 ] ], [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] 
     ] ]

gap> M4 := [ [0,3,0,0], [0,0,0,0], [0,0,0,0], [0,0,4,0] ];;
gap> Display( M4 );
[ [  0,  3,  0,  0 ],
  [  0,  0,  0,  0 ],
  [  0,  0,  0,  0 ],
  [  0,  0,  4,  0 ] ]
gap> L4 := DirectSumDecompositionMatrices( M4 );
[ [ [ [ 0, 3 ] ], [ [ 0, 0 ], [ 0, 0 ], [ 4, 0 ] ] ], 
  [ [ [ 0, 3 ], [ 0, 0 ] ], [ [ 0, 0 ], [ 4, 0 ] ] ], 
  [ [ [ 0, 3 ], [ 0, 0 ], [ 0, 0 ] ], [ [ 4, 0 ] ] ] ]
gap> for L in L4 do 
>        A := DirectSumMat( L );; 
>        if ( A = M4 ) then Print( "yes, A = M4\n" ); fi; 
>    od;
yes, A = M4
yes, A = M4
yes, A = M4

gap> M8 := DirectSumMat( M4, M4 );; 
gap> Display( M8 );
[ [  0,  3,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  4,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  3,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  4,  0 ] ]
gap> L8 := DirectSumDecompositionMatrices( M8 );;
gap> Length( L8 ); 
16

The current method does not, however, catch all possible decompositions. In the following example the matrix M_5 has its third row and third column extirely zero, and the only decomposition found has a [0] factor. There are clearly two 2-factor decompositions with a 2-by-3 and a 3-by-2 factor, but these are not found at present.


gap> M5 := [ [1,2,0,0,0], [3,4,0,0,0], [0,0,0,0,0],
>            [0,0,0,6,7], [0,0,0,8,9] ];;
gap> Display(M5);
[ [  1,  2,  0,  0,  0 ],
  [  3,  4,  0,  0,  0 ],
  [  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  6,  7 ],
  [  0,  0,  0,  8,  9 ] ]
gap> L5 := DirectSumDecompositionMatrices( M5 ); 
[ [ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 0 ] ], [ [ 6, 7 ], [ 8, 9 ] ] ] ]

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/print.xml000644 000765 000024 00000004427 14621444241 020347 0ustar00christopherwensleystaff000000 000000 Printing Lists and Iterators
Printing selected items The functions described here print lists or objects with an iterator with one item per line, either the whole list/iterator or certain subsets: by giving a list of positions of items to be printed, or by specifying a first item and then a regular step. This function, given three (or four) parameters, calls operations PrintSelectionFromList or PrintSelectionFromIterator which prints the first item specified, and then the item at every step. The fourth parameter is essential when the object being printed is infinite.

Alternatively, given two parameters, with the second parameter a list L of positive integers, only the items at positions in L are printed.

L := List( [1..20], n -> n^5 );; gap> PrintSelection( L, [18..20] ); 18 : 1889568 19 : 2476099 20 : 3200000 gap> PrintSelection( L, 2, 9 ); 2 : 32 11 : 161051 20 : 3200000 gap> PrintSelection( L, 2, 3, 11 ); 2 : 32 5 : 3125 8 : 32768 11 : 161051 gap> s5 := SymmetricGroup( 5 );; gap> PrintSelection( s5, [30,31,100,101] ); 30 : (1,5)(3,4) 31 : (1,5,2) 100 : (1,4,3) 101 : (1,4)(3,5) gap> PrintSelection( s5, 1, 30 ); 1 : () 31 : (1,5,2) 61 : (1,2,3) 91 : (1,3,5,2,4) gap> PrintSelection( s5, 9, 11, 43 ); 9 : (2,5,3) 20 : (2,4) 31 : (1,5,2) 42 : (1,5,2,3,4) ]]>

utils-0.86/doc/chapBib.txt000644 000765 000024 00000003411 14621610512 020546 0ustar00christopherwensleystaff000000 000000 References [BCP97] Bosma, W., Cannon, J. and Playoust, C., The Magma algebra system. {I}. The user language, J. Symbolic Comput., 24, 3-4 (1997), 235--265 pages, ( Computational algebra and number theory (London, 1993)} https://doi.org/10.1006/jsco.1996.0125 ). [GH16] Gutsche, S. and Horn, M., AutoDoc - Generate documentation from GAP source code (Version 2016.12.04) (2016), ( GAP package, https://github.com/gap-packages/AutoDoc ). [Hor17] Horn, M., GitHubPagesForGAP - Template for easily using GitHub Pages within GAP packages (Version 0.2) (2017), ( GAP package, https://gap-system.github.io/GitHubPagesForGAP/ ). [Koh17a] Kohl, S., RCWA - Residue-Class-Wise Affine Groups (Version 4.5.1) (2017), ( GAP package, https://stefan-kohl.github.io/rcwa.html ). [Koh17b] Kohl, S., ResClasses - Set-Theoretic Computations with Residue Classes (Version 4.6.0) (2017), ( GAP package, https://stefan-kohl.github.io/resclasses.html ). [LN17] Lübeck, F. and Neunhöffer, M., GAPDoc (Version 1.6), RWTH Aachen (2017), ( GAP package, https://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/index.html ). [WAOU17] Wensley, C. D., Alp, M., Odabas, A. and Uslu, E. O., XMod - Crossed Modules and Cat1-groups in GAP (Version 2.64) (2017), ( GAP package, https://github.com/gap-packages/xmod ).  utils-0.86/doc/chap7_mj.html000644 000765 000024 00000027310 14621610515 021042 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 7: Iterators
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

7 Iterators

7.1 Some iterators for groups and their isomorphisms

The motivation for adding these operations is partly to give a simple example of an iterator for a list that does not yet exist, and need not be created.

7.1-1 AllIsomorphismsIterator
‣ AllIsomorphismsIterator( G, H )( operation )
‣ AllIsomorphismsNumber( G, H )( operation )
‣ AllIsomorphisms( G, H )( operation )

The main GAP library contains functions producing complete lists of group homomorphisms such as AllHomomorphisms; AllEndomorphisms and AllAutomorphisms. Here we add the missing AllIsomorphisms(G,H) for a list of isomorphisms from \(G\) to \(H\). The method is simple -- find one isomorphism \(G \to H\) and compose this with all the automorphisms of \(G\). In all these cases it may not be desirable to construct a list of homomorphisms, but just implement an iterator, and that is what is done here. The operation AllIsomorphismsNumber returns the number of isomorphisms iterated over (this is, of course, just the order of the automorphisms group). The operation AllIsomorphisms produces the list or isomorphisms.


gap> G := SmallGroup( 6,1);; 
gap> iter := AllIsomorphismsIterator( G, s3 );;
gap> NextIterator( iter );
[ f1, f2 ] -> [ (6,7), (5,6,7) ]
gap> n := AllIsomorphismsNumber( G, s3 );
6
gap> AllIsomorphisms( G, s3 );
[ [ f1, f2 ] -> [ (6,7), (5,6,7) ], [ f1, f2 ] -> [ (5,7), (5,6,7) ], 
  [ f1, f2 ] -> [ (5,6), (5,7,6) ], [ f1, f2 ] -> [ (6,7), (5,7,6) ], 
  [ f1, f2 ] -> [ (5,7), (5,7,6) ], [ f1, f2 ] -> [ (5,6), (5,6,7) ] ]
gap> iter := AllIsomorphismsIterator( G, s3 );;
gap> for h in iter do Print( ImageElm( h, G.1 ) = (6,7), ", " ); od;
true, false, false, true, false, false,

7.1-2 AllSubgroupsIterator
‣ AllSubgroupsIterator( G )( operation )

The manual entry for the operation AllSubgroups states that it is only intended to be used on small examples in a classroom situation. Access to all subgroups was required by the XMod package, so this iterator was introduced here. It used the operations LatticeSubgroups(G) and ConjugacyClassesSubgroups(lat), and then iterates over the entries in these classes.


gap> c3c3 := Group( (1,2,3), (4,5,6) );; 
gap> iter := AllSubgroupsIterator( c3c3 );
<iterator>
gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od;
Group( () )
Group( [ (4,5,6) ] )
Group( [ (1,2,3) ] )
Group( [ (1,2,3)(4,5,6) ] )
Group( [ (1,3,2)(4,5,6) ] )
Group( [ (4,5,6), (1,2,3) ] )

7.2 Operations on iterators

This section considers ways of producing an iterator from one or more iterators. It may be that operations equivalent to these are available elsewhere in the library -- if so, the ones here can be removed in due course.

7.2-1 CartesianIterator
‣ CartesianIterator( iter1, iter2 )( operation )

This iterator returns all pairs \([x,y]\) where \(x\) is the output of a first iterator and \(y\) is the output of a second iterator.


gap> it1 := Iterator( [ 1, 2, 3 ] );;
gap> it2 := Iterator( [ 4, 5, 6 ] );;
gap> iter := CartesianIterator( it1, it2 );;
gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od;
[ 1, 4 ]
[ 1, 5 ]
[ 1, 6 ]
[ 2, 4 ]
[ 2, 5 ]
[ 2, 6 ]
[ 3, 4 ]
[ 3, 5 ]
[ 3, 6 ]

7.2-2 UnorderedPairsIterator
‣ UnorderedPairsIterator( iter )( operation )

This operation returns pairs \([x,y]\) where \(x,y\) are output from a given iterator iter. Unlike the output from CartesianIterator(iter,iter), unordered pairs are returned. In the case \(L = [1,2,3,\ldots]\) the pairs are ordered as \([1,1],[1,2],[2,2],[1,3],[2,3],[3,3],\ldots\).


gap> L := [6,7,8,9];;
gap> iterL := IteratorList( L );; 
gap> pairsL := UnorderedPairsIterator( iterL );;                              
gap> while not IsDoneIterator(pairsL) do Print(NextIterator(pairsL),"\n"); od;
[ 6, 6 ]
[ 6, 7 ]
[ 7, 7 ]
[ 6, 8 ]
[ 7, 8 ]
[ 8, 8 ]
[ 6, 9 ]
[ 7, 9 ]
[ 8, 9 ]
[ 9, 9 ]
gap> iter4 := IteratorList( [ 4 ] );
<iterator>
gap> pairs4 := UnorderedPairsIterator(iter4);
<iterator>
gap> NextIterator( pairs4 );
[ 4, 4 ]
gap> IsDoneIterator( pairs4 );
true

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/lists.xml000644 000765 000024 00000016465 14621444241 020356 0ustar00christopherwensleystaff000000 000000 Lists, Sets and Strings
Functions for lists This function has been transferred from package &ResClasses;.

It takes a list L of length n and outputs the list of length n-1 containing all the differences L[i]-L[i-1].

List( [1..12], n->n^3 ); [ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728 ] gap> DifferencesList( last ); [ 7, 19, 37, 61, 91, 127, 169, 217, 271, 331, 397 ] gap> DifferencesList( last ); [ 12, 18, 24, 30, 36, 42, 48, 54, 60, 66 ] gap> DifferencesList( last ); [ 6, 6, 6, 6, 6, 6, 6, 6, 6 ] ]]> These functions have been transferred from package &ResClasses;.

They take a list L of length n and output the quotients L[i]/L[i-1] of consecutive entries in L. An error is returned if an entry is zero.

List( [0..10], n -> Factorial(n) ); [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ] gap> QuotientsList( last ); [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] gap> L := [ 1, 3, 5, -1, -3, -5 ];; gap> QuotientsList( L ); [ 3, 5/3, -1/5, 3, 5/3 ] gap> FloatQuotientsList( L ); [ 3., 1.66667, -0.2, 3., 1.66667 ] gap> QuotientsList( [ 2, 1, 0, -1, -2 ] ); [ 1/2, 0, fail, 2 ] gap> FloatQuotientsList( [1..10] ); [ 2., 1.5, 1.33333, 1.25, 1.2, 1.16667, 1.14286, 1.125, 1.11111 ] gap> Product( last ); 10. ]]> This function has been transferred from package &RCWA;.

SearchCycle is a tool to find likely cycles in lists. What, precisely, a cycle is, is deliberately fuzzy here, and may possibly even change. The idea is that the beginning of the list may be anything, following that the same pattern needs to be repeated several times in order to be recognized as a cycle.

L := [1..20];; L[1]:=13;; gap> for i in [1..19] do > if IsOddInt(L[i]) then L[i+1]:=3*L[i]+1; else L[i+1]:=L[i]/2; fi; > od; gap> L; [ 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4 ] gap> SearchCycle( L ); [ 1, 4, 2 ] gap> n := 1;; L := [n];; gap> for i in [1..100] do n:=(n^2+1) mod 1093; Add(L,n); od; gap> L; [ 1, 2, 5, 26, 677, 363, 610, 481, 739, 715, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004 ] gap> C := SearchCycle( L ); [ 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754 ] gap> P := Positions( L, 157 ); [ 14, 26, 38, 50, 62, 74, 86, 98 ] gap> Length( C ); DifferencesList( P ); 12 [ 12, 12, 12, 12, 12, 12, 12 ] ]]> This function has been transferred from package &ResClasses;.

It returns a random unordered k-tuple of distinct elements of a set S.

## "6 aus 49" is a common lottery in Germany gap> RandomCombination( [1..49], 6 ); [ 2, 16, 24, 26, 37, 47 ] ]]>

Distinct and Common Representatives distinct and common representatives These operations have been transferred from package &XMod;.

They deal with lists of subsets of [1 \ldots n] and construct systems of distinct and common representatives using simple, non-recursive, combinatorial algorithms.

When L is a set of n subsets of [1 \ldots n] and the Hall condition is satisfied (the union of any k subsets has at least k elements), a set of DistinctRepresentatives exists.

When J,K are both lists of n sets, the operation CommonRepresentatives returns two lists: the set of representatives, and a permutation of the subsets of the second list.

The operation CommonTransversal may be used to provide a common transversal for the sets of left and right cosets of a subgroup H of a group G, although a greedy algorithm is usually quicker.

J := [ [1,2,3], [3,4], [3,4], [1,2,4] ];; gap> DistinctRepresentatives( J ); [ 1, 3, 4, 2 ] gap> K := [ [3,4], [1,2], [2,3], [2,3,4] ];; gap> CommonRepresentatives( J, K ); [ [ 3, 3, 3, 1 ], [ 1, 3, 4, 2 ] ] gap> d16 := DihedralGroup( IsPermGroup, 16 ); Group([ (1,2,3,4,5,6,7,8), (2,8)(3,7)(4,6) ]) gap> SetName( d16, "d16" ); gap> c4 := Subgroup( d16, [ d16.1^2 ] ); Group([ (1,3,5,7)(2,4,6,8) ]) gap> SetName( c4, "c4" ); gap> RightCosets( d16, c4 ); [ RightCoset(c4,()), RightCoset(c4,(2,8)(3,7)(4,6)), RightCoset(c4,(1,8,7,6,5, 4,3,2)), RightCoset(c4,(1,8)(2,7)(3,6)(4,5)) ] gap> trans := CommonTransversal( d16, c4 ); [ (), (2,8)(3,7)(4,6), (1,2,3,4,5,6,7,8), (1,2)(3,8)(4,7)(5,6) ] gap> IsCommonTransversal( d16, c4, trans ); true ]]>

Functions for strings This function has been transferred from package &ResClasses;.

The result of BlankFreeString( obj ); is a composite of the functions String( obj ) and RemoveCharacters( obj, " " );.

gens := GeneratorsOfGroup( DihedralGroup(12) ); [ f1, f2, f3 ] gap> String( gens ); "[ f1, f2, f3 ]" gap> BlankFreeString( gens ); "[f1,f2,f3]" ]]>

utils-0.86/doc/rainbow.js000644 000765 000024 00000005336 14621610515 020467 0ustar00christopherwensleystaff000000 000000 function randchar(str) { var i = Math.floor(Math.random() * str.length); while (i == str.length) i = Math.floor(Math.random() * str.length); return str[i]; } hexdigits = "0123456789abcdef"; function randlight() { return randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits) } function randdark() { return randchar("012345789")+randchar(hexdigits)+ randchar("012345789")+randchar(hexdigits)+ randchar("102345789")+randchar(hexdigits) } document.write('\n'); utils-0.86/doc/chap12_mj.html000644 000765 000024 00000020274 14621610515 021120 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 12: The transfer procedure
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

12 The transfer procedure

We consider here the process for transferring utility functions from a package Home to Utils which has to avoid the potential problem of duplicate declarations of a function causing loading problems in GAP.

If the functions in Home all have names of the form HOME_FunctionName then, in Utils, these functions are likely to be renamed as FunctionName or something similar. In this case the problem of duplicate declarations does not arise. This is what has happened with transfers from the AutoDoc package.

The case where the function names are unchanged is more complicated. Initially we tried out a process which allowed repeated declarations and installations of the functions being transferred. This involved additions to the main library files global.g and oper.g. Since there were misgivings about interfering in this way with basic operations such as BIND_GLOBAL, a simpler (but slightly less convenient) process has been adopted.

Using this alternative procedure, the following steps will be followed when making transfers from Home to Utils.

  1. (Home:) Offer functions for inclusion. This may be simply done by emailing a list of functions. More usefully, email the declaration, implementation, test and documentation files, e.g.: home.gd, home.gi, home.tst and home.xml. (All active authors should be involved.)

  2. (Home:) Declare that m.n is the last version of Home to contain these functions, so that m.n+1 (or similar) will be the first version of Home to have all these functions removed, and to specify Utils as a required package.

  3. (Utils:) Add strings "home" and "m.n" to the list UtilsPackageVersions in the file utils/lib/start.gd.

    
    UtilsPackageVersions := 
      [ "autodoc",     "2016.01.31", 
        "resclasses",  "4.2.5", 
        "home",        "m.n",
        ...,           ... 
      ];
    
    

    While the transfers are being made, it is essential that any new versions of Home should be tested with the latest version of Utils before they are released, so as to avoid loading failures.

  4. (Utils:) Include the function declaration and implementation sections in suitable files, enclosed within a conditional clause of the form:

    
    if OKtoReadFromUtils( "Home" ) then
    . . . . . . 
     <the code> 
    . . . . . . 
    fi;
    
    

    The function OKtoReadFromUtils returns true only if there is an installed version of Home and if this version is greater than m.n. So, at this stage, the copied code will not be read, and the transferred functions can only be called if Home has been installed.

  5. (Utils:) Add the test and documentation material to the appropriate files. The copied code can be tested by temporarily moving Home away from GAP's package directory.

  6. (Utils:) Release a new version of Utils containing all the transferred material.

  7. (Home:) Edit out the declarations and implementations of all the transferred functions, and remove references to them in the manual and tests. Possibly add a note to the manual that these functions have been transferred. Add Utils to the list of Home's required packages in PackageInfo.g. Release a new version of Home.

  8. (Utils:) In due course, when the new version(s) of Home are well established, it may be safe to remove the conditional clauses mentioned in item 4 above. The entry for Home in UtilsPackageLists may then be removed.

Finally, a note on the procedure for testing these functions. As long as a function being transferred still exists in the Home package, the code will not be read from Utils. So, when the tests are run, it is necessary to LoadPackage("home") before the function is called. The file utils/tst/testall.g makes sure that all the necessary packages are loaded before the individual tests are called.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap6_mj.html000644 000765 000024 00000020634 14621610515 021043 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 6: Matrices
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

6 Matrices

6.1 Some operations for matrices

6.1-1 DirectSumDecompositionMatrices
‣ DirectSumDecompositionMatrices( M )( operation )

In June 2023 Hongyi Zhao asked in the Forum for a function to implement matrix decomposition into blocks. Such a function was then provided by Pedro García-Sánchez. Hongyi Zhao then requested that the function be added to Utils. What is provided here is a revised version of the original solution, returning a list of decompositions.

This function is a partial inverse to the undocumented library operation DirectSumMat. So if \(L\) is the list of diagonal decompositions of a matrix \(M\) then each entry in \(L\) is a list of matrices, and the direct sum of each of these lists is equal to the original \(M\).

In the following examples, \(M_6\) is an obvious direct sum with \(3\) blocks. \(M_4\) is an example with three decompositions, while \(M_8 = M_4 \oplus M_4\) has \(16\) decompositions (not listed).


gap> M6 := [ [1,2,0,0,0,0], [3,4,0,0,0,0], [5,6,0,0,0,0],                       
>            [0,0,9,0,0,0], [0,0,0,1,2,3], [0,0,0,4,5,6] ];;
gap> Display( M6 );
[ [  1,  2,  0,  0,  0,  0 ],
  [  3,  4,  0,  0,  0,  0 ],
  [  5,  6,  0,  0,  0,  0 ],
  [  0,  0,  9,  0,  0,  0 ],
  [  0,  0,  0,  1,  2,  3 ],
  [  0,  0,  0,  4,  5,  6 ] ]
gap> L6 := DirectSumDecompositionMatrices( M6 );
[ [ [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ], [ [ 9 ] ], [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] 
     ] ]

gap> M4 := [ [0,3,0,0], [0,0,0,0], [0,0,0,0], [0,0,4,0] ];;
gap> Display( M4 );
[ [  0,  3,  0,  0 ],
  [  0,  0,  0,  0 ],
  [  0,  0,  0,  0 ],
  [  0,  0,  4,  0 ] ]
gap> L4 := DirectSumDecompositionMatrices( M4 );
[ [ [ [ 0, 3 ] ], [ [ 0, 0 ], [ 0, 0 ], [ 4, 0 ] ] ], 
  [ [ [ 0, 3 ], [ 0, 0 ] ], [ [ 0, 0 ], [ 4, 0 ] ] ], 
  [ [ [ 0, 3 ], [ 0, 0 ], [ 0, 0 ] ], [ [ 4, 0 ] ] ] ]
gap> for L in L4 do 
>        A := DirectSumMat( L );; 
>        if ( A = M4 ) then Print( "yes, A = M4\n" ); fi; 
>    od;
yes, A = M4
yes, A = M4
yes, A = M4

gap> M8 := DirectSumMat( M4, M4 );; 
gap> Display( M8 );
[ [  0,  3,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  4,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  3,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  0,  0,  0,  4,  0 ] ]
gap> L8 := DirectSumDecompositionMatrices( M8 );;
gap> Length( L8 ); 
16

The current method does not, however, catch all possible decompositions. In the following example the matrix \(M_5\) has its third row and third column extirely zero, and the only decomposition found has a \([0]\) factor. There are clearly two \(2\)-factor decompositions with a \(2\)-by-\(3\) and a \(3\)-by-\(2\) factor, but these are not found at present.


gap> M5 := [ [1,2,0,0,0], [3,4,0,0,0], [0,0,0,0,0],
>            [0,0,0,6,7], [0,0,0,8,9] ];;
gap> Display(M5);
[ [  1,  2,  0,  0,  0 ],
  [  3,  4,  0,  0,  0 ],
  [  0,  0,  0,  0,  0 ],
  [  0,  0,  0,  6,  7 ],
  [  0,  0,  0,  8,  9 ] ]
gap> L5 := DirectSumDecompositionMatrices( M5 ); 
[ [ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 0 ] ], [ [ 6, 7 ], [ 8, 9 ] ] ] ]

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap7.html000644 000765 000024 00000026622 14621610515 020361 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 7: Iterators
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

7 Iterators

7.1 Some iterators for groups and their isomorphisms

The motivation for adding these operations is partly to give a simple example of an iterator for a list that does not yet exist, and need not be created.

7.1-1 AllIsomorphismsIterator
‣ AllIsomorphismsIterator( G, H )( operation )
‣ AllIsomorphismsNumber( G, H )( operation )
‣ AllIsomorphisms( G, H )( operation )

The main GAP library contains functions producing complete lists of group homomorphisms such as AllHomomorphisms; AllEndomorphisms and AllAutomorphisms. Here we add the missing AllIsomorphisms(G,H) for a list of isomorphisms from G to H. The method is simple -- find one isomorphism G -> H and compose this with all the automorphisms of G. In all these cases it may not be desirable to construct a list of homomorphisms, but just implement an iterator, and that is what is done here. The operation AllIsomorphismsNumber returns the number of isomorphisms iterated over (this is, of course, just the order of the automorphisms group). The operation AllIsomorphisms produces the list or isomorphisms.


gap> G := SmallGroup( 6,1);; 
gap> iter := AllIsomorphismsIterator( G, s3 );;
gap> NextIterator( iter );
[ f1, f2 ] -> [ (6,7), (5,6,7) ]
gap> n := AllIsomorphismsNumber( G, s3 );
6
gap> AllIsomorphisms( G, s3 );
[ [ f1, f2 ] -> [ (6,7), (5,6,7) ], [ f1, f2 ] -> [ (5,7), (5,6,7) ], 
  [ f1, f2 ] -> [ (5,6), (5,7,6) ], [ f1, f2 ] -> [ (6,7), (5,7,6) ], 
  [ f1, f2 ] -> [ (5,7), (5,7,6) ], [ f1, f2 ] -> [ (5,6), (5,6,7) ] ]
gap> iter := AllIsomorphismsIterator( G, s3 );;
gap> for h in iter do Print( ImageElm( h, G.1 ) = (6,7), ", " ); od;
true, false, false, true, false, false,

7.1-2 AllSubgroupsIterator
‣ AllSubgroupsIterator( G )( operation )

The manual entry for the operation AllSubgroups states that it is only intended to be used on small examples in a classroom situation. Access to all subgroups was required by the XMod package, so this iterator was introduced here. It used the operations LatticeSubgroups(G) and ConjugacyClassesSubgroups(lat), and then iterates over the entries in these classes.


gap> c3c3 := Group( (1,2,3), (4,5,6) );; 
gap> iter := AllSubgroupsIterator( c3c3 );
<iterator>
gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od;
Group( () )
Group( [ (4,5,6) ] )
Group( [ (1,2,3) ] )
Group( [ (1,2,3)(4,5,6) ] )
Group( [ (1,3,2)(4,5,6) ] )
Group( [ (4,5,6), (1,2,3) ] )

7.2 Operations on iterators

This section considers ways of producing an iterator from one or more iterators. It may be that operations equivalent to these are available elsewhere in the library -- if so, the ones here can be removed in due course.

7.2-1 CartesianIterator
‣ CartesianIterator( iter1, iter2 )( operation )

This iterator returns all pairs [x,y] where x is the output of a first iterator and y is the output of a second iterator.


gap> it1 := Iterator( [ 1, 2, 3 ] );;
gap> it2 := Iterator( [ 4, 5, 6 ] );;
gap> iter := CartesianIterator( it1, it2 );;
gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od;
[ 1, 4 ]
[ 1, 5 ]
[ 1, 6 ]
[ 2, 4 ]
[ 2, 5 ]
[ 2, 6 ]
[ 3, 4 ]
[ 3, 5 ]
[ 3, 6 ]

7.2-2 UnorderedPairsIterator
‣ UnorderedPairsIterator( iter )( operation )

This operation returns pairs [x,y] where x,y are output from a given iterator iter. Unlike the output from CartesianIterator(iter,iter), unordered pairs are returned. In the case L = [1,2,3,...] the pairs are ordered as [1,1],[1,2],[2,2],[1,3],[2,3],[3,3],....


gap> L := [6,7,8,9];;
gap> iterL := IteratorList( L );; 
gap> pairsL := UnorderedPairsIterator( iterL );;                              
gap> while not IsDoneIterator(pairsL) do Print(NextIterator(pairsL),"\n"); od;
[ 6, 6 ]
[ 6, 7 ]
[ 7, 7 ]
[ 6, 8 ]
[ 7, 8 ]
[ 8, 8 ]
[ 6, 9 ]
[ 7, 9 ]
[ 8, 9 ]
[ 9, 9 ]
gap> iter4 := IteratorList( [ 4 ] );
<iterator>
gap> pairs4 := UnorderedPairsIterator(iter4);
<iterator>
gap> NextIterator( pairs4 );
[ 4, 4 ]
gap> IsDoneIterator( pairs4 );
true

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/manual.pdf000644 000765 000024 00001433475 14621610514 020451 0ustar00christopherwensleystaff000000 000000 %PDF-1.5 % 163 0 obj << /Length 425 /Filter /FlateDecode >> stream xuKo@+:=9dD9d}C@K!eX8i4UwU!-netI *y) dVXM?9_43LR NHz|22*v?];k.S)$54h](څR:X>gX/4Jdhֲ18̢ .nI/PҖ*Vk- ϫOct|s`d*Rڝ(.ڠN㰯s*MzOla0hSxwL1F * VįnS̷NS{]C)?J^O)3qS[wBs=Vgק,}?t!1FU<-&uU7E^E{ J,AzPƖCOʗ|y endstream endobj 173 0 obj << /Length 737 /Filter /FlateDecode >> stream xՖMs0:dMN$c&x&@ ANzo Adi\`{̈g]䢳|RMq8u=4_!2bןi|>[r92pN}<nhV b^3rఘ Z۟xJ=dN+TLmB]{37~uSj^;)XtEC~pۂx[H̒QTJm┏=Km 2 u. ^!b zTJ8f=uy6᣺}Ml@wÙpLFFI]e=՟W qSfx5~`VJ$B6 gh}.`ԩUR"uՕjf2S״;#+0F&`\kf\HU/=6 g?X1gBX/~P:(޴Gۙ(&Eջ`K[P~Q25Ihp\@c;-`֙TJ=sVċa|#1uf[p 6nwrL%|.%QbtYl-*a-Zuo< $ހӚkd/xe:qt v;s[*܏Ri]PF ]aV*^\]b_=~;Xh endstream endobj 184 0 obj << /Length 1290 /Filter /FlateDecode >> stream xڝWn8+&fҙI::Bh, $?/j"}yxy1.QhwhU"UQYT,uxҼWݿۻ,F58j07+0HҬ96i"wgnJ˦ճ-m(E(rwb_HhULQ̠i4GlhQ#27nCcB-/^: bcB󸑜98a=240}X#*;b5Z8{O}Zͺ}dĤ ~F}`u9|=skJ6)?Wn\<'Vy}V{֊,_=rL?Cz'!ivo'r!u`R-|b=YIĚ*5W̺-!"\0IR"B> I?wY9DF^-]toz%1Kgʠ 9q^6爗^OdSe,(V@XMG(O,*p_p3tKfOƗVҊI*`치5y痼B8dQl`i֭ Mx4u2 ˈuWV]I#|cMVŌlN#Rk-+cj`p]/5Bœ݀$,y=4qZxYAczk?d oN9> stream xZr}Ẉ~I$[%kKR~(XDD,AP"$UA===rˆ&C8.%pHFXя;b @%B=xˉd9 .H-hZՒ9PpQZ`rB;ZfD0f-^ 0 ZibAq=01h>Bt2sBUXȳʭEt:"fNɋ(INKσ5cae8ᐅu8aY;M 7ϛf[|وOig=w7Qew&,۞_QۚYj ESךjJSt2vX&S9Krt4.}oA&ɴ,7UAt<&E!Nw򉅭55)N2"^kXM :KKoW*-e̵0 fU[)6/|6vyI3Y\ >")'0pzF{Iuj,߅d: SY Ek֭Mhy݊u[ӵ<]ӵ<]ӵM_irs(r 1,y wNn\EKor4iOja;j߁(˧7mPsb -(bBl 8㞆-X4 ;p.Cz4n(21CYoG @--џ S/}¦2guor4*No)gxyB"@A$ J^ih(_<+h< RO FPD1GO@#!@= XavLI`T*I%}`g:Y~&ߒq6K"TwEtQk6[PRBӍep'WCHH_dQe`SatSIƨtuPˈ GkeXD;dZLQӤ ]S e`k6o0߃LVlZtZ"WR0̚KNsdu1^Ǹz\ +1PD9C-C jk}jD]j^9U鸈ҢnTѳ=;7,D%E-i6?z endstream endobj 224 0 obj << /Length 1107 /Filter /FlateDecode >> stream x]o6+x)-m6$: ۅj30 $y;r,@MJz0IC}x4A Di?MhOH+,DJ(̅A9zue1k5R /Pil$(Vsb^3@1%De>&Yf#A\a-)\ԏG w##bʱ] PdS:A\6'/dᚋdS>gyc FxKxkw¡5"FTJy [thK RystyRƔ6*ҁXvUP62/&nfkJK p{"UTAjz %c#;]^lu/kB=Vy_K{,9ؼVn\w/+oX9a2gBeZ6T6#;mM[~c~٬w76-%[g7UOXq(]V{qW-0ƇPQl}PDbQ2…:ͅ#O@1n^ s܅)sZ[&lՈ^HB"J_8j+ϝ{*;Sl-V@ԗ*h_(~,a ?#IګS c qY&M rNyl. f/*VaY|#qت}CATAL }3ŐO9@@E4| Zy恝dx{7`GM fIt.{J)([f}%,A+,X4yd4rϪet?N)وKv2Ϫ݀&埄jk;V2? ?2%IU}'EIf΍{4!TE\+w$PV˷s.m.o񛹒vdKynkHդilE+2FSjٯզU5(7BC.#uĜ0S3&t'S,&`Cu vIv_:/}6ˑ1XsYOb+l5刾e_}5.{i|^ 7a^6 endstream endobj 237 0 obj << /Length 397 /Filter /FlateDecode >> stream x=k0 `--mBСuĐП_9MhiFܽwtGx6_@ ;D5R`C8hUz,×ySَ763h{4^؜^EIAXKU 7 ŠBH2?ʆ,<+ʧ܉1 DL>"1EaMW[}uūOR~wWWCL|N7pcrtL"ɍEgvM; 9iV~:,No _f[u-fA?}I9B( >5+wybygٴek$ӄ[O37mQ26FyB=e[}:ԮR endstream endobj 248 0 obj << /Length 1921 /Filter /FlateDecode >> stream xڽY[o6~ϯ$1͋X`vnwv)Z`:X6m #D%Mɚ\bYyx߹7W=~{zрbǔ g<9Af6Afd+p}Í#$M!e0Kn$ նBՖ `̟ Em.{>C2~EmcR2m,r$Z[ٚ(C ۤ]٩ƮupAjWBۮQՈ݂P4nN`DݼqVHL&8HUr [C+X2- CdEp_~Ø6/ۢM^P 74zSi $fNaSRDgCְ4c(&VNRJlΏ\?@{+t8 ,F)ܦ [G,K~gA seؐ CYLcb,Ա:fF 8v#}>EeԔ')\B3Di \\\@óg+Hўt#7 nflMnMlb΍ |\rܙ@|r׿2~e_`|=R_bg }fN m| ('1(tOP"(a#] bޑs\3iZ!\#v'ƃM#AT&mCahfT8%=F)o8|uNjZS,}0O1.R6"e P/6,>?I)(IžsM"mӇN[&kxl2tBY_Q]뎩HR@כE[&ۗ$MP89~#:QE=1m%RY<,b,Ӿt9tx'GM%D<çT"_@c`Y< >dc"H@Ըm endstream endobj 257 0 obj << /Length 2488 /Filter /FlateDecode >> stream xڭYYܸ~_!84Iٝ "݊uTEԭ9CCIU̓]rs]ăe 6ixI,X&f|Z }Qv׿]gnT)вbsʼnxER VKm_VEpuh-&6{M{u3n};7{kLMZz]fC5y_{m;uQNgeig}Z,S <7mUԺDܒzfzCPjOʍX'~Sg@MM 2Voo~b8KTWW~~ 8LY"KXwe? "XM2T `g;oCi9+)a=?GL1<,K3 H [Hx!RXA!"Lf$8il.OÂ3IRxZC.w%8u$Fo~6H 6^_a`AP ğS2Q\}vI7m/z=Ck^;]0wz6y6Pz- 8Ww ֶmνn :)K|:%ζyȱ/ذ -~ /RJWSUG Un^g!C J%/p.#vE^ˢ>TJ׃.OI薨ځp:EMHƽ7[8 {[]w[t6G­dBQڶM_ꚡ͍q(qo*˔D&,wBNt5{k7q:CDC`ϑH]M]V+ "UQ4Ill )W7{c- BAݸg756"^4` DwCk: FK8Sa,Q~n; 'GsPo!K5m\iX3{yNT HDlk~`׻*.[~91̦itWWqvQ_n碟W*~"C=Ɍ޵eiofh0ג~@EDZZ"E$(_MyK@A/n͘0mS?EwwWU)TV% ^H8hn7#u<Ϫrt$8oybkދkܬ>%8ɡH ubWԶuc̘L%Cu&.̎x Ԯ~6`ѡgX0ǼR6^]E=8$ָuOzIh @^/̙5eA)?bj,.'{ǾfWRB%,Ld-Cb |i-K Pt#TG0U`CH Ȟk$W`H⤅Oo1͘Je[71vc=X'*Ápp,7==Oq/k؃r;B\SA{vFkPG1Ev !zl|p[Ҝ]2g#E OHo8>ºo'7h@Z\Rr<6 9,ĴvsSq:VL4G,jlr}<5&i@6'SNHAܔbRfS@ ;x!,5PHW¦[uZ2X"Gb9n[{&RAՃ84aaǞ$FL6B =kmrx)edW||HO:@4^trPw{C8. O wA y'9|y endstream endobj 264 0 obj << /Length 1615 /Filter /FlateDecode >> stream xڽYnF}WQ/ -o f!Q*IgF".ݝ33gfeg8;8r9yӌb$%]$LdRĨ.olNpWx(GJ+ٜ QeSn00 ͺ?pĸX@H<"eWs1SKhl_4v-2&Yi$_>ٜ5{,M.xkEUܸc[u'!YD"X^SV{ƅ(#7m2)TtW\9r_̨:&*e߅q:?maxYkCG ߧgy_/* l@l bz#uc7INGCi i#tcܷҙ`9;knS˞ݧ9aR%\jk;|L jX: 2 U *889XH,n^,.rF 0$TrDw!OsfbFB|(AH#3fZ~t<$iJv.-w RYprn /WXg"_.mqda5bơ >VE `@v)چK } s".]wuXN*tfYOXX=1Wi!Ҍ8rd#kqno MA1E ֻDc$hOA' t7|!v,E)T"+`B/SM:$TDZu{ZQ:J!G$2Luy J[\3).OjĴyrns2~) .Iyp%n*|1 -ϖnZoUF%ut'<(Rb[wjx VfQb߰6xM>\NX3a1p5nL@u:{+WE.LݾeyglI[Rj c2:~/_m/Q#{j3pF?A "?rDRz|LP aGR;߽t>j'BpR/V}l<7v/B& .f~x)N"Q|}0ߧG2K+5/*{'[Gcׇ_5{%F;݊ 흰Ip Rg<1zEdoDǘ ՚2Z)L!ILXoBؘ֣o ; 9W(cSSF7J7)%iͩSy4L}1A  H4{1s \Fk3hy=@R.IWoR$pzMqJ9 ,TB88Y2ǫ`DP+66k7!FuAo$f_|d: WoQp8;I>[Gѷ $|%BQ%ZtogW+TZ?nt[ u=QpXJ:_[ endstream endobj 274 0 obj << /Length 662 /Filter /FlateDecode >> stream xڽMo0 :6 a:m-ah @mmѶ\lCڃ!Q!W lNwe@Ay:"ZowX!qm66H~^4\6[P(񴷬1QWj Z;Wm O?-fV;u|i@Fk TQGg\'+J u@qж  Vofws_%0,nVZ-ȅw]s'4>#[y¥Z DSKؔȀ-wݭ}0 W,sQBFMbq 5@iUd` "j:@+ʡib9 {We]jr lS MɁd ND) qV4E\EW2,pdxAÊqEsg,K:K>"Wi&$fzH',r19UX 003tUP> stream xZ[o6~У ,"غXїy2@sĨ#;Iٴb7CQѹ96_/G//K%J1\2Qg&IwC]&iחF$n׏oRAt*Dwϫz}*ʍOիyy[9;F#…b^Ԩkp+4x,|Yzó1҇b $ g3%diQN"2w(@!J 5!z&X]//H QqX PI݇&PFDq$P8!!M H_Kљ_f 7ptb4^n+row(T ^^ލp,CnCXTyUUf2Yd%2•H&  (c)Wnv᱀W{[CKyEy[Ѫ,TqK4Ӫ\>+6Oyflx>'⦦-EqsiLztqB >(yM0[ f B9"|>_$k\|iv–&Z`'5Mnw\rF>xEi=^* bUF76?,e܍y}ݸ/ OM15H@ *s~w;t t*QblQݥX-B| EwsµqգR  7QN^r7-.wCfxp~:)AUL˔PKP5O2'`ҏ(?{y ifXasY&3$lx݄iMy&Lٓ1>Uxx fWI,灣2dǀ>05c@ A.@GF;}`7G s!/UL7bK!l1BePaeVAXEopHݬ0C9 S? g\&dgC9!Ф<.yQ'6m9=ΈatF ɔ<DX./sD.˼nasaW"bə`Šf͙UsU`ƌAřh:N^O2Dh0W/oruvr'Wg$g{hQuT`c{: LTU:u~/aRs*wa`[IOgHY.Ə>v6`1SL&`Snw.(.jnc+5/W{S{'m \o@qU};?縧ukb0c灲 ;{Ρ"pʡ )p {pykKg||%_[>=&"<_O\lgg M\7e^2z@DZ[}ehR&l}^U#Cf U 2T5~w㐎yf*!)8d OKEPI0I_a!uDgm?] endstream endobj 290 0 obj << /Length 2271 /Filter /FlateDecode >> stream xZ[o6~ϯУ0_f0 tg;vC[N:Rv;P$eo2E|Pc\BFaN39bdJdn']fןF72$jl\`/ۋ_؛8b"S".i6~aČhG>h!YOAw/Yg'AFRie@gR07nq_yAJ+pfwWf6?ږw't-UqF$µ>gRf+xh$89`=ՙ @8†k^eUM.aG릁2 ɨDJDmvÆ)"nneteU s&Ihfr)HKoIthbtGB$4T +׍HvZ1&3Ί `*4p`_b>":?}::w*뵚gW~uo u}{eI$ q&l+d[~uȔK9/US)WL~i>U8c+z*|CY弨r>/'~ƼyvW/tKs_ϟ~Y0ۊJL6V(ɕî\/:/le\DzqozΪG쫻7x!U]I_%*h2/Ζ"}'H%!]@<+T /34)gՃ%}$LBQpӦ߾}S9//ȋz Y,U ac Z3JH&e] z(Ǫu5Ӎ1Ӎ=[Ea/[Eqf6kp hE\b,Qd6n7/_J@w~-03?zܤ*/OLeb9n[Zk:m nrۈQ#*U4 d/ީ &(q6 a ~ p̰w;b{ |aXӁ%qτ-1ӣXܡ[9pJI3ɰb>ӻ! EL^Mt?,9P8͠ڛ <7w;b%Tkr7޾\ɨFapz;f<0a +cЦLLC#wÀq -qg@apx$ o#Hr񫷉QT:@1se \/Hvou1a )< uBlP'R*L@p4U~IV H}է ٝ2g:fA$xK: u;ʊI}7)uP<V/j~8xq\Nk9S VHS -Uxdu W$Q&x*j%B&"H8iX%# 9-lWY ҽ}AA>.n꒯w} FaT 9IVV]؂EMxN;db$%: !=w. @n&T|/vB#K1 ^i؃w C$ A2ށӚoܹ{P;߳w㗪| 刈HRpǹoE?| ;`nL4%)-M ?ˣTtbxLAG̀>&%%GD׷aZ&+FF tbCVGK_EeXr&h:N12Ƈ(QE7(% Y'cW`-]S碛M~\>mN)wj:-e=.{b@藌[ a'$ž}!L#Us4s')atG!o~+U >8EF \8cDN_'y endstream endobj 296 0 obj << /Length 2505 /Filter /FlateDecode >> stream xZ[o~ / M> nIڢM DKBtT=sE,SVC!=O{Rјadԍ=ndo,{5WA6Ue4 _ ^I xM;X]xf e dVbTn3ڻEߧTd&H,7ڭd:EFGD4J<4(:0R$ƄY>,-vgVInlYjXv jGEq\*S1aZe4Lq:[uw*]"oi'ƍJCBp@۫߮3FH̉FG3G\G$VHX]E_І%cĘĈ: "2>ʲW͟#P[WL04ų\;+h6 fh{<|ӡ(G8Uϓ?mkD~4W>Hv{kXL뵉Efj[im&i/u+ņa d[I|!]@HXZ A-ٿNB<;.&= ԽqjA-b a 1d]IJDQPLWz׎yA̶ՐkhlpȄ SKh1voyMPɗ|$3~kBeǚp5tQ QnN;!S:Y*BY-Y|7ȶ&%3reX^PۏVME-z3o~ zW$՘;qPRs_S[ggYRV]`,yl%`*p5u<ܕD{m .ߖ3%q* WO9칖6 t=*FTɦa?ΖErbT<;:XD6FSe=)s>R"z*Zn;$MgO{.Zdm~y6XȦ3gV0}[#Ք gB% Kf ͑2b'g݄ǟ0tf#:baF6|Tؖ'_UЉ :=6|g`3L#5oz ěg\mhZ|!ւMpFd3\,Yݘ:2ߡ1=~{OO1Il>{,"c[ߌ1K1#5~6P,H%I;wVXû-N @X"%y%~I%47ἆ72mlb..6\3M/[+'DCs6R |_'R#szpcZ]7mqC8OHjr6W,|=gwvfDԟf;7C7> stream xڽZo7pF7AW Hr8Bb4KF[sQdku@ R\r8ff'UhE\mqNΤե4u5+Zsՙ4|3{gC0mR4' X2D(1 bUg1dp zKT+{0D1Pi1'9j(i)%WV-*fz3,ae,~\"B7E! i\ !bl.sX0Xq]JƯ +`.UH-'PD*i.G\VX%"˙{7uP03[ZPqy#. E*Ȯ`8K2W2M+sĄ`0AiP{j%q5F3rQar?0ÿ%dp|I؂q}ju$ϮV?ݾ}~~|yvk{u?O`77{&`=dyps)Dp&zۛ5}/wW?.pi-<1\M|mPLzxo%gH 6 m2uh[2f[8:6ihЖC;'|2'|2'|2'|2'|2y(uIbw AQ91j~ڔOEp[vߖb^N|e\4٨6ڈq]WI%j#BUoop$2 \~qJv˨65jf_Hj*uӣ2IbKn{a|i_\ּæFımh6dTv_!̓8zTir](H߀ (=&٨. x'$2Q&2&*AAQ>'AM@7 !: Є#.:6T6X@zP᫞*Ba,7] j[gBa" X&׆l :>u0q~ ITA I0:m! P'Q 'D@u'#y>A?d7΅84s+²Ji] )g9th5FfQ -[ M4Xk]Bu(,PXP;Ah7=R,"S(%0Hbq@9fFg֕s@:hO0]j `}LOs3"ta'Db.زl @?539]}di-#.S)s;1d *o~F:{q۬n6G6b 1͆fCL!P,t\l۬KBF#@: )pA=C?1(ª*\)p_v [83HR{Ù#bN1v+_y+o4A lCWEd!2cYOdj^睰}jڼ\|Z6c clʰD~uL78CCyڦ^4/,{ Z)働1t0(8E鰱4LpϺHXTG!!o$||x.pWؔm√|l_9ht{~ C;dϗmtcQt:R;Im؝>v,8P,ERY-acICiwhp1Xmx /i:lZfmcsc8k棼e"oّ[!'H|k,Rd)6VAW`/x endstream endobj 306 0 obj << /Length 1126 /Filter /FlateDecode >> stream xڽWMsF+|*1d+9TlnZ0Y@D7!K@!f^?~3"h|n' &M3b9H+ h:GOj*GϷ!%g3%(72;g@߁}HÚKB14[ óψ`nb!hy"b50?D0Ƈ~%ÿ$E#:䑮D҈E<TSX |+cEN X z ]%! ðؠb'ܰHDu5l zrJQu )E LH6V|!| zozo:+P:% S[?jx4;+`@6l ! A)!fDu3 >vBk0֐>M]A !fV-ss&0ߔU,ց8}`*f 8=\%bDa>xpQn'*FX6pGg}[se]/>ӡ#X{U/̿s]a;(paNUcBM[n > stream xYKoFW(f I @ 6h$R&}iي_zZ~pg goG8<=={iF1|)1jbjoLc><7gWϳOoRV*ٔ >W<{ChKj0 NLWEEQEvuʭ4թ!1.U3%#K i{/MOQ90E`V\1 <ί&,Ӧ`"qx: ){; /qS\7I"OuA-3$!Ձ1V!~rpɝLL[ԥ$G<68\!a[nZ< IxF̻ķ/fUtL \B0pT&DmuF۲hm6ٸO_ :^`N`;}JxղH5Ȱ@I]8z}>:3kSE"$^..qv&`7'ΈQHMu} ]d$P 2L!N|Y SwW| *EFA 2"dk}\/To:pyM:Uv4f +H=7/BmuvDN6-;O[ݢ'W{U܎K<A̡aiPĬ;HaTDI&$EtD]?җ'QS+&c,>TC)eӰk}QΛE-r[3?*OOG)axJD8}ξ>SA>Z b!Dq_L_Lhc! 88{= rϳpd(ӏ>BNL5 O}< E~:V#LT(R"cN&TRj$B;RʜDK{8ȣ2 D" @;+ꯌ$|Ct$3$T=[*ykBr|}tay۠zj.SxețC D^vS:!ZfPb}ٓ=6;/8/1 X?ȗ8m@ې:6i pZ5 ӁuQ6vl'Z i 7Pwq:P5w?;w]"w b[kܕ4 :;Rc5l(7dZjVaikpʊ+w1 }Uʠ ʯL]lfmjsݵNHC0SK?v`%(] endstream endobj 326 0 obj << /Length 2256 /Filter /FlateDecode >> stream x[o8Bm a9|sak\ GNVn"iYXj>fPJnjf\{I3MN%HƵ8O QƐyr- O!dD bN'j=BrOR:{#Fs!XQ#ݺp|Jspowp|{Ö"O|fP4_cb[io={3%I DJ>(B#aC$B(^ Y: sIc{CY#hbؤ,e>̊rQ.6)ɢ|ڼ<6J{X4b3J| nkX׼M`r]Ǘ3T4/)xkg'g ;r( ;[E^cQp-G-+¹$nt Ya,fC^jGY_ϳ?fX6[vؿ↟ U2+ήWUs '7h8v٢6x~r.s]0w Hƙ[g}p"..S۝@'Wiy(X)vWVhltgkxb@fqb2GNȰ˗*_Ahs*>dzB}\n8^\ RvnNr{WV50+c834څ U([ף41PN"Rk>$ b̀Јl`5'xMF,ͿΌ ۭ IpRsQ`V4f&h?CuQLdxMՁjuuR,g>pi uA }zL eK*(z*bzsئV{Btn[Ekm6 $G-S=l7^ JB860QjN,>~ӟT* 5<Eq#֧pLbN1?z4bøDcÀwt_yu_p/W?IA@c uN9v~wY置_;7ՐЄ1%^NT#3µkԟlν%M0U7Ch`Ud@7D8LNnf_u.7_f_߮*u]Ѷ'-=Ũ8Ԡ7i 敾$Ӓ*K %k;Uݡ(*SVrr4og2v ̶]I@Nk81kUկsE^K2" 9VL|tŵE9/pjtO;)16cPk7+nܹѯ۠oU5S\ ͘-|'{+WR8WɚbDa(ѭnGO]Ϊ6:waXsOwȁ+'^| +Y ܧ68t֘8ddvN ((d 0aP5Fd͂3171kWlb?) 0g%&5I6F)*(ii@ba50*@()S)2q!VRʄfFrp_e˜=o6"h5mpR|9m5 v.fƁ12004̌-{hVOoS0b;11> stream xYo6_!/263XCufbӶ[d9i(RldC"R=@YzTͫQ* nGL:L7᭷ޤ(q‡wEzk9F05XȀ3Jpl!pNm'`u^C b"GHqZ6ǿ6{[ߕHʼ`așl^3ޒ:c>k0YOX`?Xi/0M&{X_ݾ$EII hK O7ٸLбGF 2LK7t=QIx}omxUIڢ0ȗJz(Y?0}H醂!,F*8\^aMUC$"~tl+֣_GlfTLlq PÐ؆Ve؎]ْ,@ŐxYڬ1 W]GM75ze'8L+Xm8,l6+T>L3 qNl vjuƲY\,;x 4l:K_*U >b8iӉ&~8hYWQyII6d ~-/BU\[G~\vg '䜔3͎ }?PSZzv` fd}@]6 ʰc&2M+݅S J*Dc";_ $A^N. <"rPLBqDjh}"^`.ZU뇟ܓ-~\t,~~C P̵A4_\ M /!sW %+)zEqW yE)cݲ:i-8WW.Eu(}uhWoRl:S4I)K#ӈKe2@}?/_z_@MyǕ/+]$c7T2?z }s 8?0Ym&9ݽ t߃k&;mq-_'C.y/ZH8+IEizSFOLCtp u}a3ݛ 8B[UL&],S[7˙H 'n-[%MJ$Y~a #*CAC./\p@S`4j횝 ːCvi~Yb endstream endobj 340 0 obj << /Length 1429 /Filter /FlateDecode >> stream xڽYnF}W ؛_6ub#A\?JBuѯ,wId&+Vٳgfgd"]pvӈb$%4R &")bD]|9O6TXo0Q?E_o(GJ+@qt ҄ylLt>mr`AF>2SeZ5_` 6pn"9Wa?Gد4zw%ՈhU@+E\D 5LR%YӍGu.b9Ӡ`c aĸ%sYbVRI䃵k?*dOmٰf+?$?Q cY/Iۼ.ϒrpVj /MZߎ~H8HG+=+W1 [FGLI"d]ĀwMʽ'Ҷ-3 &yʹa{ G> $J@TNA_F=0*70G۴*`w<&nD' I|l>lk$ \/u-ݹ^F9!7CX-ˉz\/ǶPe؆k;s֢U2oEQ;BO#f0ᐆjvRLcq&xh5u'}p1A7:o@HD$ TT uwꈼ%/ҳe/\{"sD0 iƺIE^r eUC 9l0j  ɣ/bvX'uS@Ҳypku0tQC;@E:@pE3H~WٵPbֵga"'~H6~8)m(|4HoH+ЫL%p1'}􀨜g~Fp@e:MQA qZT|"?O}̒x V~v'3TZ!~"ϛl_7L|m2(~[Hrgo3U!RJȷ*-AXI; Դ%'bW+Hd/ \UyD/a3Em2T f V&AC37mzD I$Y4Ylsʡn>P%v/W6= BuH\uƨfl ;h) _Y8/K endstream endobj 351 0 obj << /Length 2056 /Filter /FlateDecode >> stream xZ[o6~У< v(еM6lpc1؞w(dNd$uxx yOs#$ETs($]N>[,˷g\D# r2,{@L#lxAhRI<Σr qn~:8^ $鶲q6g6Zz9qۦиfئ`%InYFg)0k>QquӴcHӂXh*Q&I'b SWj̴AZ(دBDy\.18ݯn,#׻I⇲tΒ4M~Fsd8EUEGD W a&mb)]hS~ ,A 5U&H7a*ԏ-|Qra~dʣM65a׏vI7w{)tϛpDcRఖ;ڸG\3Бs@ ٳ!_D!f}Q^?u8V:4!G(RxR;3!Np1;d%q/MhʢͲ\sđ6In*\]h w1чo*$2H*sQ1&FoN6ˤ0وHsU.Dcb*!-7=SՇP{v}J͌*nQ'n,/䭛*,VmKjg…P@fjNqdM K_>~EPdjVm!0Ya'ZǶBUXfDG+NXv r ~-؁ip*'A.<i1QowC琨=KjwK:NپZN>=jDo|7<뚓5BF w~֏].,09%+8oel m4Rplom&) :\՞1L=ffi'$흝focCf~&VEOOԖNX恉%;=Qw` i퉺 <5$ScRWMM9p=9{ 0#p'.jH[,DץT]ҏѓD>ne1gCFK M?GX1F6H@La%߄9wְԑe/ %; u% 1h endstream endobj 361 0 obj << /Length 2652 /Filter /FlateDecode >> stream x[[o8~ϯ,bwRSδ6Sm$;m^DKDk`Rux;8&8pN&mB5GDI2“Irn>r{.Q3כ2$݈6}ΰg!N#Os҈R/Tͼ^{0/fToE=պ\.CG[R$:kR"X5"<Q;zcUZ`qL@BIpl2G!. Ʊʻ&:IΗ-6aog`y#eeUǗg`XC֨)9 kQ#u;>O'`N0`<靡i>6qRܞ曙 ){4+Vyu^EӇaQ$C?U4"Ŵo]!yX Z$#djM׃Vz4 qJFg$ o>e,t" qus7T:5ypl #jV Qe .D-īpzb^,HH`THjjUӘɓ*U@6LwyZ ״Xk,|` WmQƚM>sndrޟ4㑫kS~Aţf-*2Z[/% I 083ȖS$60 o%]GD`|PZ~5 bSQ]zm\rf-R4ioC_rbQԵZrL@)m$L*˧^Z/'gv~һL֙H'M(hdܙi i7ci·/d.-^EU;yU `b Ҫ JoQ :w1]P&6EF~.2D g${U)̣\njcƛ]ښPACSR]~Ne|3cb iuǰ(wxŽ` :/ :rEĦabjm44hۜC@%}3z]G ˯;+{6$/6dF v]M'Ͱ;;C ,>LQJ$Н)AJg/֎ X'ZxMc3tK#\''D7 m+H}O֤H]50\2 l{(CHrH!I|XQ^ i43-Ƥ{.[Cj| Z'.z z㔠_7^Uh؞ClP Oj;҇C• TKŪ*j<]a6>C<фF s[Opcp ? 7[[Cm9K2c(*}\Fzv OkM' 2EޟEe:3>|9y̱RA:w4-4:GsA20>9"}ܖb"l8}D5CX`DK$k]mL>h_oe> إg䴛Gf`xb4gGa9'͜͜OWh}".߀U 1ʄMV[qQ (jlЋ8> stream xڽZ]۶}_/re[ 'Eݢv?ލn[1?d4ߤ36-O4xlgy"ZuWp7 0`68PD"X74q>=\"Lt00H0 !r1Pc*qC#94 li"xH#4 $s_Kۍzy/|sL]n)cHȍC9Pb% .+e@6lW7m+`qI>qk[dV7wlI _ ȶÙ%ހ57s4ߺ ҈rr MgCVXz v/c:4)XBީe/wOs<6(6l^'B\i^br@ K/ɺ/0+ky;AWP_G0Fl4Ax|5 V0Dp+Rl r+^nN 2VB_oݹ^?,͓b7=mVh5Αu)7H\, oad7QCQZJ U.ȁjtӝQxN@+Nu4 Bʡb5&Uz '1M}S'fyꅋiZu23yQD4;(|{կ~:P%+颌 8%pI0VP4)*'y;B'kIi>~rdqNYMc5=$P蕮#{PpW)V~*RQBJUxpeP  &vN 1  +Whi(`8qvyg*aWbvgltk۵[F .2N6)ñ?4|1J`)9@R&N9l:tOvQ8#0Yz q"ѳHzSnV`$_N߬N(6(˸FpCN3 &?7s5J+>zP b(joSzɽC܎׈]KbU 8;qSvZR|'Eb7yQeQw\ۡa~TƠ)>,J={$TBG|8ףA|n*1kEBz\k~XB2Kl~N?) locX8izasgۑ ~T%f :OLZ,P7/%{Ww=p!znlBd;3P :1 ;7(@}m);iHǁQ뺼:ݕj$kZDQy6msՙm=dl mǮd;N .MRuưAWRʩAjpfuL. H3 !/\݁nNJcd/;1xHWZIR j;"g||Fj)9qrt^CH4dZ?> stream x[KH 6\3;;vki{@Jb'KU*Ll8*Y_>$hǻ72 qQ$R Cx8"Y|""l5eH`UQlig4"FjǜDL -$CC8g]4&v|LDј/SMhܰRQݤ)&+tEFñ i)ZMƷi R *nlR$麚r.c%RGc671C(լ H2}41E )nj;8PPBX8wT6֬-htH(2"BF #@aQKBF0=*8ki*y IzI#Cu?Ma7)cjȠ:$x,n6IݭI' a3<cӐHG i <ɋd5$^ƫx]JHM!DX4:-jZTqpٻC)q&!4@O;g7]~t&Kedצ8œwkʸagnmGqIcb:-TKIVڤy,"um^(mYz /kq0q~_ !)uފ>HיSy;JE@̈6˸+QTѭr#6C9Ҕq2EZ,v'ky6P.b@y3 w%|X^d|pox m;"#j]wdt1wɻw{_@kFkiȍ V^Ŝavb$kH}{#k^PX^??!ឳ׏@֢:1&g{"6|%tQuOi=ǿ8F_e c{(O.H7aw(u1yxSy[6UD43}s~'G}?j$3c<0Ҷ멳 j#w.sխBq uA& qn.`'gOpuT{ D@dD>8dμF~taqoTAXTm tK@]j"Tny\U9EH:Oeq.֚(~E@D9^v8K* Vb_#{: n.B!UEDw/4ڍ[zW.ѺYA u٦4:iq.ޙW;I{;ƣV3}aX&M[y<lӼ\b4M5^4q:-n4!Q7o*E1'7{mrH1A\)lFv =ѿG , ~ oX8)X!tb&(؆>\a=>\G.|~vS: ͑OY_ݴO}A)x_߶t187'?qQ'?H>9_S endstream endobj 389 0 obj << /Length 3022 /Filter /FlateDecode >> stream x[[o~P$܇hڍA$lZ$&T_3^FZ9|21'xrsWO jB%% ҄On:fn HcFSQv%f'sN@Г9(l=]v:/v*~s"f M]뼞tsCb{N}%]gյ}:bCRrЙ ɜ2ӡjn:K! q4BnHlm1QA nӂٜJ=zb]}*6T(a?ϐ"ez OÝ=*VQFDP$`WF:rqk·laʫv;Y]0:VN Եn/j'G8)ONhOj5 z>dLC/2HQ#E0[d͠ߚ<6#3%ǃ;CA!Q):}1dFܡŲKŰj3Ҳqv0;ݪO"B_I")8:fY:5Xz$DlQbs$Σ Tc4IqHPh"̜%u]w3A'LPvyHTݪz^&n:sӞIy31qMZ;S wYse&۟btGƾP:g!S`o{.b% RAىٱ=a n[^ͽ\_{@2R OՕ)&C~Ҙ\sWVpfWa Z B-/v&堣/DCf|U QFrQ{EWEaRUX]9M"tEqjuئL!ȉ1LJ>& ax7;qĜ"tȪ60-ȈCfš\d1\ +.V-ײ"{ ~ L`n'% ҮսՃ&͙(G[9 6Zbsf?f!n-0*ļ%/MOTN9@vffۻlPW6ѹӰ,H ($>m3Oid"9}3փ۫_wJ18AO۫?} يJ| Oν#-tAC#_Ztφ3 3+kɖP\ݘ²>N0fD&K݀|>DC 8g0HP_8c>ٜ`Щ߲WD3Ad$2vŐ-gk?@&—bOf:~54gPϹ $FټSuFC@Xix꧓fc.>{^'[o?cEq7\{:^؊zV9a oNl݇ۊ@KaˡēYnJѶņ (a(S"$]f->g[z\XÎ2l%6㞭uyٳgPORR<%Ͷ  wl~Z|8'1|$A $~b"kd-Z^`g3W~IRt>T;[I\/R/CO̞>Rk ْxLL`'Kr٪6/Q|:?ic=\.RR]D!"cʴ' _eX ̲|*X á o 2d94HTܳS8F@<7187hR„m4!j2FыGAl{J$={68C|@t*G'z6إ LpȮekO"!|U"!B(8>&?iDopA,"w6#Aw=SECQQ O(C4D`M4loŢ Z6hs3pEX;Ǟ6&;EL_W)2Gk},qЄ_чhTOr>+Sm{"slyx5QL0Ht=>>.ͻm̃Q V:ݘK}lrDINE]8 {ՠ6IJSHtQ 9z5 ᮗmC5#khC뢌Bۭ 6=Sr,Z-GOiTO7Q[O n^_8Uwȶ: oLYx JEF5ߓO7ɮ4vمm^?a Ί#Wv* i{m L}d砓W*6{݌SY&پhq/6G3Q׼i"wuVVMnʱ;vDͅT~S8}Da[~M=~RuA˛Uy?|-q!g!0!5Mش юiQI('.[kEh[Eˬ>)}^^Õ;֍6DѴ F~q|0Viq*4WW /< {6E[fQnq󪞣c(u:Ą]  endstream endobj 395 0 obj << /Length 2319 /Filter /FlateDecode >> stream xڽ[Ks8W$UI&N*5jhU%K2IM @HYhldkA5q_7W?8R(Lj%£yt;e6G."ISUV {єP&L4ei)S2RGq1Š?q5k )EK͓:OVxJF:<-8_?f'QqnJUioUp4y ͡V8Һ2"r:Ę&y֦s5dՊH1QN` JGSCMH1d.$ўQ:u=&^ I*۬RH+3jjūVt?&*|,w-z֣q]$j?||ͳg0GPKAlX€\OtѕR([beǒ <ᎋR{W1詻/mvyɇ!0?KdrP4B\|1 --Hu68 $ m>wv`O¢wnex3w6f6 P1'Q Bj堄 aq,tȪKw] `[;\ăn>\\Yqd$`:0=SţpS3:VH>G($}n}-7DIetecI͔syLžaaB)]7Wa-j@ 4SD j CduZq e%{.K/-cm@#d )IP?ƛ.i(+ @at;TEhO{[wjLM I㪽b{;kΔ)MF/PE)@iNnmxo|,!aX(Abi;I{rܳ &VH/D^6'wFS+k mC7|hHwŅ-@LzL$9p#LJ#~Ba{(T1H6_}:]']'M ޅUKOBT()=ǍEo8)ęClÕ,wPlkrs}] `v%#tiDUQ?ͰUM|%q!^hS  #%$蒰;v#vpNX l%`C8M[uѫq|z@ȍFRD/L-M!/2-݃C?PÑ BnW.:\bw΄x(%\iĸ85/*l,=aޟ&>y7 .25 kбL#y5og*S 1Mpę>~?@!Ɛi3 8E`ٍnzne`J+ȯ Ӄ$ǜS@m3{ct^>0Ae4&k4omKَD!RHj So! GRH[{R RO5 R"/H-W7b  qKa[rzn:f%=aoC@D:2rܤv#1`'=鸄~ChR${Bf 1[x2nG~ 1>h 3T"`w7"f]SFa?%\L6Γtek\K*&E9 q"v{Չ^? [Tu5{yX1^AzQ,+)qemxkbfp5=^|kE5mTTY-O%]Weyے{هRWi@Ygq\> stream xڽ[mo6_&d.-v[ ^C%SvLY+,V3pFcFo}4j "cF ~y3'!3Rg3N$R4ݜ+Ϧp1i)(g%ogSP~^& S 4#" }VF[Edb@HE\^ī np&CҠzqZRq-{8JzZ{htbTQ,C WߦlQIdb' C3$j~(pZ0,Yh xeR?>AvJϡEթ6[µP]A?)} p&O7-`#]%B{e~bET{*(oxŐ$B CPJYU.kjyN}F( 8Ndb˨emQ{% [g'7 x˂u,*ń\H‰:2m3r(?=h=4md4//!7~ni!Oq5uhi6eF'Ӛz L!yՂZesr2i-g(U< :f]9'--n,ZjO:OHHhBmL{fh"ݓ]Ti\gGNwq񖸳ڕw>2C}3z˅50 {#dY3XIȬ2ѷk$Ɣ[ߺfnm=.%>8ndT24 r*:,DKF:h*v@S` lS,\tjC>`< Ï}3.S+%KTJ^>dJ 0$=UmuBM,zaya*KH#. 'C qCWӁ,jXmW<q|}38ɸX4=!'hux;;ccќ1bwP>Y/K3BqfڅA6!x{Qᘝp>mx0xrp Ydx1=Ø5fbr@|=;#m01V#_"ꥃ}Fn00db5Aʴ8{OfZ(*@p+/@v̇r>?]M3JZ"$* Q\F%_K'6Ih"XL۸{)d8bDĥ! 9">)ōZ>$|9ln+.CL0M@"d+=l =T !)P,6Ű?lp,@10@nm3 2YJ(F @5Ig&EGH&nV<;x! qڤk"J 1ӈWMBGkqB%J]TdZ y}I%Bۭ Oqg̺ۚi endstream endobj 407 0 obj << /Length 1971 /Filter /FlateDecode >> stream xڽZn6}WQlKnEMMJ,me%i,Yr%nX]E8:=䫏F#).n#%`" FMt.}8O'(-S#Jq4iœ*yZ:MKpĸ~P`rF0yN>-*7Nse}AF Di!+&D:߮?|}E4h K0F`Yp EVWuGuA<dF!1޺vNe@XZ 2Z+0l2m&7R'Q.v[{luHG aivV S*$y۟\0f٭|%Ba/CZg̀V;^G&b.v%wuubp#'hgCH Q #4ƷfhMO"HV! \6zbg9]v\\ݎlO5tw -Ũ_5_#ēF7HPe g/2ߘ(xVܦwSž{׀75ag$ófMkPm)@lƥ|?4tj䙛tHʆ砋:N®>84S^WݨPo*m$% u(H0-oCU#vosc:mh@,؞BğL"*7gڝtautxq!P0าh>}5:"Ɗu7_'TRYyeP <}4vsWl݁jP#iQdip9 \ uUPp%FUSu+;逧 hօaI| hu+d3`~my|醗dJ96~ݴʖh=D'TQhl<0~}`PEp!YӺ9}Į(k&;Yn-"^~8kj;tgpv3>[a>vH &]]QN5 k$C{4>m-kC[rD<јFۂç˺ͬGC\#9JmxhƎCjY7g]X.'OܐHĥx ދptv%.eGH1Gߣ OPr'U^hNOsטi 铻?q0F[ #ےĻ.1{oGm[tR ,) &7 @x~jxC}!W/DRB)|5 砒B C>KF 5za)e^>zw<>Ce8 )hx}X@u$b1 F?1K4GEy?J endstream endobj 303 0 obj << /Type /ObjStm /N 100 /First 872 /Length 1551 /Filter /FlateDecode >> stream xYo7 ~_a:~ AE04-45xv6}d'"?Rҙ7ΰ##b`(z&Ñ {#.#@w&ńL#l<&c'),+DB7T/h("23"B(/bJ|1ANH0*}0Ā!( cI0!0 KC 9VpB#dC3R",' V,sTGz u b!CD.uLz 袳r ]3T>V/pO tJ,,5YO ]9.> OB^\zFZP"nXZ&~h8yIM:U*ϤEWal,E5'hEhP/i̋GCC֘gLҮDr&zVpBCCG"8!X@ĺFLPD b&CdD,c &(ɁGI.dԼ61gޚ_3)>94}rœXVl6]ӜX>fR:HW(=t_urԯ:Ϗqh= )/¢xa.L3Ӽ^}W7Q 95jގ糇*&W/gͅ*%X$m.vuȞ5i}u_JbMOwKO\eZ]E34VLQ8[LmL;Х?'\†cPm!}XmFBgƨlYV=!o3Pv-kTDV*dY2v@,ak LH".E<q})b^% +=z{o=,( ؊m UP\U,.F{Ъ¹t:AE{SS64.7+tK5ַ4=8T\ŢNE/ a2؜d6mΛ߾ϳnmӌɝo5gb2xz}K\ut4}XmlP Һ䫰슍sRĝsu:4 v`uzŞhK5a=nrl`|t#nӱlE>~`n)VbѱF >tաay>m$J$J{(A,`a|gq} l^߫fޫhe2WxJfo%pIf}xog47Ww]]+]3LveZeh;F签&-_8֋O[ٻ ǭԳtv>6ņZ,YMZJwK.P/ߺw_x`+RtUsa5^h'}/nZYJwXsFgH<CϝG"mFB\'|qYD^n) endstream endobj 417 0 obj << /Length 1886 /Filter /FlateDecode >> stream xŚo6W}dž vXۚ4l+_H9ئ̹(RuDޑ}]~8Q(L뻄j%“ir>fx{G.ƶ fTm p=gPI))&E)&'S)Q-0* Q .K4FM wS(np sUI~W*(}g޻|m\Z2հ5#Oj8Hju&R"7Ę]s-v-\`/Gܭ]QpD>eJDY@Dt?->`R1˜s(s5d_7 zngi4RJi8ELÀ8̂ A)I΅ݨR__nú(QKЊCPߜ`]|s 63$`8 3G.F#RqZ e3GM\W2yUy0,$LFѾ7s#֑p>P! 1Tj7E!`~`MF-|-g( qd=n5p`)X~P#| @(E?pA*Nt Dn$T< n42GV 4CL%2GLV $G(ār^lOCa.i#HDǎéโD Ve8 $sfK]ajvR*|0P~׵-N f=SDrs [†!h GҸimMWy1u|N;$"Cӑm7m8^,lu6mJ4;Y- VӷcH;oPhSe]PGo*(82 і`݀ Wַ &rA߀=7 E ph>w%4cQ'7{W~uA|Wժgk^&vF@ԡ>)u8EF6HksJunG}hڎ endstream endobj 421 0 obj << /Length 1983 /Filter /FlateDecode >> stream xZs6`{g$ ig;Y;{tؑH-I5>"EJmg#{Th抺wW?KS5WC`4QBZ1"xܥ}ukz ǻ_QBz 80˔K %MY nbۤ p aprpdCP޼;}|*,]k~^&EfnM^[Xh[v$ %1EڑDVH۲?IZA`i^<ڹgn_s7|ySN`*t|{Q3K[& *D)jN+-3fQ:Ml8»Ȳh'U%M{(#RDx Dfvi3ʎ;ɣvI'z SEA Ex,=@T1N9Q; 82 E""=-Ed)&mMF/Svp?ʿ)T n f_QY[X,*)aD0mpǥ (a9ARQMOTmWxk'V_xCQ~&T%W*XɄb"}tjc}*m\lD6ֹm6HZckЀV >1˘Al+g,L) :=Z}Nx7SF+ҡ/MD6BO# F;0do*Ct># ڽumu4!Rc':!7ہ]o1stL{Fi6̥K{ٖP=YKJ8XDs>S|9hكW@fͺL8Bi`ˀɀВpӋlj E$Z0~. ?8^[! P>4k "7k%V%, dB*bv Qi/P^URgмq|E-G~,d%4ay|j B jr:OB @Ype/p9 n{b޶YY.IÅ:ij|^ z0+,QSk}m)JHyWz"L3ˏikf_½Wx"IWg)KMRJ}MDm.FcO9*!f}Ug""'L*ENҽ;nKj󠍥6Pf,ItZN![Od6P8&on0q rám}uW i|!?аWi;1>ܮ,6Do|kYM (![f̸FF' =X#'q8( ^Hģ;- xx14D#f8 n7-ᷛ ]X7׶Bu6~v-7hlC7Ov-^Qs{JT_lw66cxc^^헫>siF|Ag7^ncKqBB!|PJEZm FTnѾ>g;D^ @Q G[Gb-@0wccPkl+:wkQϵsmyA u*Q(s}Vf9Ŝ0Jby\[fq41]2X$1bI'`brSՓoqڤc5[Gf3D,zn"0HxeZ>czygC4FYi *&GPRMLc-%^󕂴4иG}>pc'BW^(`ğ}Nh^iU^4 $ٻ@\;!ԕ_Gq{?p;-ht:H. 1`ٿg>$:鸛%t-4"^Kxtb("yWp_ -~pur3MP ZF?R- endstream endobj 429 0 obj << /Length 2103 /Filter /FlateDecode >> stream xYIsWDVޗ83Vy*$3:J"! 8@B$BDC6~ۺNn\|9{^D!0I.o9b$JdO.7|z7HF?2$rӨsf84! Fj'8#@Z H!N69b\xvZ=/w&Ҧ:[?-{``dE0PugoFQrXAX`j4.A tHk#(Lw;u^qɱ:Z1m *AA'sXq滴ا[ۦh{}u&Nlw$ ug-5E"*ZMdu2mBy{0R۠_^4Y6~^S뾆0 00Ɋ@r7 +f@]f b--[üi]Wex^-VuV~*VFu0GuA< >,;t}Dl(f߿Vnuw?m#PAּL0w*uAhi ߟ*w9hc F-M376fl_t]PCxsiBjQ'ޕſn~nm<4kR dJa68//:jWf?^ξ̬pb 6L$0 nv ' lfbʮ&N U $H;)N xӞ PdIPa8CDTs=2ĵ!p @9l/6 Db 6>v] =𧲠bfkp?wn"Kd6>K˭oN4F^q0Eks{9+X|VJ@y +i}z޻d+ŋTbҀ9Z\tƷ?)8^b~Q nv[34}Gx/Lgw Hi .Tg@;R3pͣ jfq9b$cj(e?Xu}p7xi3k>hN4N qvْ|=LqnJmm:~V g8ps4! t[3h1wl˪~y(:[;}Ax*7pf7qyq?O>̌[VdQ =hb8{߸= e;c$ܡSa{/ƒq<yJ*З.( mz fZg搧E+7uVCUS\I (i]P"l=`1}4(s:lwnDM[QtyHnl(U1jF."#b]Z5Y+>lo bL`T RWq:<$1 2. >N?C }U!{]W|KxU0KGSg

x\C sOT%7#wzYVE! )--)DD[ ι+!"*zֽQ Buxjy^N.o59ދi ѝxr|W@; /¯o9` z 1ɦ{ץ+ ]e9m?p} E ~5XV;2DRNrPbvSy.e,+ǂ< $X,Ue <ъ'B"2^>'1zr|SAڧ4PIFq<[c@I8)Zc#6WB j1vztVQxN rBգbD) e 6Z>92Z5g/+k2oɽ;J~ endstream endobj 438 0 obj << /Length 1537 /Filter /FlateDecode >> stream xZMs6Wprf ߈ƞd<4uOH5%Wkw4)вh1L6) X%Ųˌe'z 80;q+Ap̌Fp(Iv޿[ϮWʐc.0[?r4gHf~H t6 Vq<ˬI/;!c|LY<[>zn1 8}BA$lkciA8q S,w6;f4iAr2+b[l1/TQHXF j0KKQr[n=:;#:=P[Xb∍@H4rdDo!MU`B>شK=PŘ(ܭo1ߖxuWg\qqA8VHO*PazNG K2^xNi3L%vRJN 8/ 3"?#p-g MW!FqbMZ;:h#%(0?Ez.r낋`L#<8R**zX\ZIp*L7an }Jk) ),;pi $&,L+\\ZIH@N",5Hjx'\,Qc;pi $墩u.Qc;pi $cn Υ5D*0a*4)4"rF$,|XwuPnZxvNt#"!c^TyE7Nmث6UAe)RW3 ;Q s X^;/a"^JFL~niԹt_؉6x9_lÍmIrW 5RX($#־IKcH:tixnEUST58zjW{ߦx f+ ICxE$/) endstream endobj 444 0 obj << /Length 1790 /Filter /FlateDecode >> stream xڽYKo8W9@-.A{Yl6@iMڒWR%K~$vl`9GG~4IIEt;1it\dFW8N_(y}D9J҄8qR=)iyV-"~KFw#1??&/ڱ<RjH )!T TI,||^\/q&HatQAwz9qCXjlH m*nKR( *=K[$,Rĭ"JJ]0CBuWᙷAU0b!$ș Z\&E]+/[u,pzH)$RR q]`&WnNfkW#*ɯ 0s_$8N{Wu"E ˋ8$(U}iz`/ u䬛-Pʳ3HP =Gs@, 4 İM ]6kIX;~3@ie"Ѝ 6t891k_nb$CrrA;,A}cS}:VQb`ai]F\mO)y Glp'5AD mpFrbbם n|ϧg>KÅpn1\mfy,y yj.[jKdDv: CeBżdau{3jͨm;W=zX*t7KA:cyڸYM /)k(!+~6)ҜfQ֞h̗E!Hf&t'V:0r@AprI܃>M!eR&C>2 jFY?hm)P=>Υh_?2+i?KVlee;wPrl,IcWD5X_ !9VlȵEǍW.q<> stream x[Ks6Wp}dG6$[qUwr@KDy%yi<2(YE_h44Nf N}񯛋o~8Q(Lj%“ir>o~"!l|oʐ ucA7/qb!D(E\d`ČN]ϕ C ,.s)4ϾJxC|Ӷm^3NA4%OU'aHӀB pݷݛՠ9̺mF4 J"¾9_@;HA+J4{7#FBq$+Fs2y74{#/)zJz;O͈LchD˻:|Cnb)%!, {\mF #W[mKGިƎ4Ra( Zq2?l6Mbmr.a8d_9J̕ju1:$a{{$rpЪ7oY%i}OS1:f+s Myy,jtZTs1FjuWiveǯD &JY(!#>gᐗQ,d@pW Śʐ[&qRwW>Ŭȧnzk0fo6[ N+:GyDDq*#GEvӱ%zE@ *2s|Bؽ,/+6,9tU"ʌ% D +ѕ6:}_D*,kkT4xݦ4ݟqY zL"VeU_6b Z:lѰSSf I$GDZ xxZ^kUyL񧿶X!cIxOa{*/X# 0'!̵?u.",  #R> X.u^vX{}jƖr0gZ!uvjy[@I K|7lv|6ivC6'FDȁ|$ ʹI3o+@]pɎKobt`$j HVN\ Y92qR9^\AzǦs)bØ.ly! lxYsim}E~Pf{m[ aE 1twLuz]WCLmG p1jVcjv =ڐdyv_C` A3%};- $=doc=m'?yѱ){}3{HFbj(,C BCfqʞaae޲/eNz+'9l0IHmeamqVV1RS($"tZdw@2 X0z[1t s+ = V0z[A5/b4 ; V k;_D)1dO(ŮȋCCs>tPma RE}N<^t1lwh?&_GYR} ^Wp$'?ea[ٲ"?rTd>F HܮDi|0LAFY{F?-S#t;A!/Ӿ++mWilz5ޞv!ُf^;QOF0<1k'#1FX1mmkG98,2o}vxPn6n(.PO/PPV7__)'2|ABBsJF?LhdF$0t7yJ;ADH O+"T <Dз~0JD`n{/E$Œj2_Y}Ʀ?ֱ`A>"TWM(jI!>줷a14fLLif&7z=7X>cĕ׿a endstream endobj 460 0 obj << /Length 420 /Filter /FlateDecode >> stream xڭSMO@W̱$:lw.Əēc*`Ezhv:3}+AΓ*98MA #RcѰn6m&L 0!UʷezU""(B+x&;.03%|u۫E n@Q34ݥQHڄfMѤ%[-{!5tT9պʅmi$E3b5* iHi`܇X#Qؚn&, tf4=z[Ŝ$dEDǽ |^v:;*D?tb-[kX(Bֹѹ#71lV~UM&042̩ Xg3%!& Ak񿍖 0` endstream endobj 465 0 obj << /Length 2327 /Filter /FlateDecode >> stream xڝYY6~RU+')qlm*)ypR[XH'ۍxqaJ 6___cqwo_qoIXKbfF0%{޶4<3 nY&Ag,MdO$f/xTWM~H,Yb$x7MRۆʥ42.DXmeSRq]'kS[}x8}㵹ߴv4ʺh{rGZO=NO7Mn/vbw 367BD໦qXG{?8KC8 ԗULa?(D{eo;z>7{iq=@/x:S_zKASfLv~)L;+pB,K`xZ?l.4xtvh$5SU5exvKv 'y[vW[eOLʦ/1l ji,zgֻD a&ڕFDUe~>y8y[Xt? LKA]jɠRLp4`?^D{}({Cټ+i '_ 3y'5uV`#zqFۏtn6%<%: >R N8]Lx0/C]PrOeU)~eŶ N4+|;U1Æ%iUyj֛VK 4c*3L_$(T,|Ai|; 0{F.Axg8dcgpRQ㿤p.y6 .Ve3,n.p}Hij $lF@n71x X1EWd)Vgb* 㠭etcVF 6-۽lܝzu7X nDy5l@<KU4Vcep`D3 `F!¢ǹ =Խ/MY6%M:&KWXB><Ը7ws`!,$ v--KS3Ԯ'@ t/D[$~s!1&M{+;!Oȥ6t(Djq"wAj'@K׀  D̷ ]{)Л· 0| ѾgmyyOk$[!) m IXfMٮo+jNyEPker]c=lΛY8PCB2js#K^)c2j H$z=ѩ{ pk-u=9 Ξk4o6;P x‰m`*!ݿ6 `YZĮfbK02UG\ŋ2{.aJ8T1 _ߡom&,<_:_&M@`÷AJ|k}}.i;%m~۶?SL3|q:}ٓgqwY_{b\7 )"t7} qƆK̛xMz[4sL!~m7 ilE1ERooCVx#* =`!K1gG6T3Z4HG'?XuA㢪)r8Z7,ZF+1UKUJ5[ڄOJ?Cz|)ZmdL&l[7=m1mJ9:!xס,bL n1'myڶIz`*0" wcgڅ쳼S~u+B]].R>+iiMKҗӟoVߏHZ7%Qss7c0"aP\m:l}7&%J{8@4n=.;󼸖vʥف, 3-?r>av"Z;0V] Cniu *''$RDy$;u֮n x'uۉ!elۥLf]?P>0xU?61^WN2ӬZ:wQ/2A\BŴ[gvN endstream endobj 475 0 obj << /Length 1808 /Filter /FlateDecode >> stream xڽYKs6Wp|)5cxD2!iI.Mc=$9,qB* (Ndi|H>>|i4hɛ˓F))eu3IgQ0.їxe}x^QFi.bʋ dNhPFNQBE)OY4Y|F)Q"tzEtJT֕_hd&:5D)"a{|,3xCXuԛ/MRA#Ntw(^<_CgwzZh7Dk@ L kfQ֠1-)=,_0:-^(W)_:.W緷֚|=|eA0OvQ~6wvc ziƞƴ .۪WK `){g7xxrHxILL Hm} `"=T<$!Yg{]_(JBi}v?oU>LJppWQXtaN@ixD@O% 59,<%#*i?oj[S嶨yӻmn2Kq:\v7Z|ҔPtSqmw,W^iEq84u#JXz(H?kGAaF]Ó$Rt:D Iw8ypwz͖Pn9`σwܥS&$*FUjwd45rhlF,͵jb[&kcSkEW1Mq ilq]c)sd] XX|3r\#k%~c>rw>HNn)09lH nraš%Si~)s+ܻ맊L]4‹,L}=Љs!e ћ>nR0z)BMFc %$ jH (sDK- Cs`;~N&pIoK)$5)ҠE;d*".PlPw80v^O[|țyZ.[o(l,n;4=؍8ǘ-8C[<]:8 rvi r]轃r#($xfq}L X1g'|Q Q0-!7y9d " S䃚XǛ-1k!}>7@F!:ϛ j4wDڥ[HMoq&Yl~̹43 (۵apQ.}zz• +TNz%\R2𤂁 80r U[|ހ| dW &+ ~&CV]L\gx,2W6o8rdN(dKA2q|GT( N^,92.M/c0_yJFGvK(n5f0a0iq {_++@7!Qb@y^]n`!3D1:/; 捻:EmF@ex]/M[ -<6( X^q2&p'Dh߯PJ> Z" _LKmX@;WihakwDz8:׸ ttw 8=-ZӺh|ǰ]ʻ vC.6yBm'o?5 endstream endobj 481 0 obj << /Length 1640 /Filter /FlateDecode >> stream xYYoF~ׯ DzE F:H69ZVUJY.vB1Crvfo8ZF8:attӈb$%t)1jQ)?)*4m;7 #-EJFX2sn !cZVզCvL %!&c@ !q?.g_2x^o2A/כtN jYQyMT^ģzrI,0ŬkeZߑG$ $fWq4o@bP?UW1 emף?< ' bpp VO?; 3 >;ޫ{ ]:pD@ NQᝀb;58jqn(8T4C:: u')eS#;p *,OfIW'%? [E'jXcr+H*E5qCaP !#P7@ 8l1w 1`alyN@0I8Y@G7W" $tG=GHJ~9| Oe~LAe: ^*+]wtHX@Go!'Xc^ qVt]'̐0`qlkgw :b[_n-+ޮ멽^$oq?/ QBXO7݇H>2az/d !TAaIMRioWb\;W!7amn?Ud]ڐَ MF3O}vh6Y; MTD47XAF14Wvp3FgyCF"M#Ux6ygWi0}p>99=a3 !a{?" Hv*Z =0 !66c*;s'w> stream xZmo8_'YSܶ l-ki (hk[^In~ɒ%U͡HESpgC888?ٙBZa\4Q(I&<Lg/θFk72$Ø0ci@@ qF21")$Fu|4?;? GcN4 ޗyP2ˋER`ggLnO9Ő38jq`Pūq2"VMQk:jo$SCjN)VqfjF -f/P0gE\ݧɈ Vܧw&*xQ%yL<2XB8"JV*{ LgE*Ier DRv.Jn|5-M}`Gxm]v1%] 4ɽF`_[QGa[-oz+ A*zDI]Y88 E>^~G'qi>z}uǑ& D FQG78_ ,D+$6 NB4bLZY8!k<_+WVy ]20`#ݑ H\#`r*kJ BEsZIt;q|BLzbN>Ǜypy^@J_ 7RxfϾ0;64٢_ `CFt׶ )W1 &$+MGJ#6KmCq7HkAIEȨՀ$+W!g[#AB!s(HPlAƥ-*a0R (^6qI^Իf͈@X@=u]Z-͸BLjw֍DmXQ0GS"2Z^,}WG֏GPQ%{k U֐ YˈiBP.: q!H]ՑPIqedn!Ut *nwSܸV˺flAXY&eY8JX͵cXs*irݾEAOԮTܧ{'}/LBI:$> B4pY$P:l|?Ԫm`dNxeMVĽ,+wMlSҽgsll|" )mC7MnsXxpnm%"g4%m5W] \&4)6,2G3~'jVݾ= ;؞@M*h`&Lg=@~cB:THr>SbIo|%HM7x}E=zcX&|U1†% H+R!, ܈LpfO/&QRT7Յ8% ̴j pg`3?mď'( Tl`yiYN#ހ 6PϱdmZcY< g)H>|UL ׸ o:ѽPhl26`odŶP-ܭ(6ZcX2`KQJMH{nB2.Ǟ}|ilɈ3ͫe L܈q6Ikw!_ݫ|a嫭4.xh; UCXUWf`3sgMz^ 3&ňv.Q4EԨGni^eRR9gYmڷjiZhMv4/vNjOBS6r7gdEVæ4tX|Lb%ͪ BodR] VW\U*/ԷEBX$Hjqf"$ɫ4;uUP~dQƳ`O%Iܯ[&E N"Y19!V] KwŌ1lϹx`^wȨ`žVКG-'+esM;äSat]ہo݆#q":ĭP smǗB 5 xE ۾hÕID0}rH#ɹXÁFqD vNR@dɱ/C/*M)T$jJIZdE;8Ӯ[F91=ƳԁsGN Yݑ;Qԭ;ƿtc~6 _uٛ!"uq9ic>31oǼuQ60/4xwc]ͷꉾ.DG mz4۶֍<SESA-X"oKϚ@Uqf`pc7i.7:ibΤM\S iO l~q /߾ld EMPpICS @4GW/_(,&HDw UKp,pJ .0"Zvvz Vkp8>H l]HQ(NyDu̶ͺaPV0 GCq3GTUid^kR SQưCkw0YH.^&/ endstream endobj 504 0 obj << /Length 796 /Filter /FlateDecode >> stream xڽW[o0~Wx} u}[6jCli,H"B"M;IJ6pr}LP [']IV?3sFV[*zzjËlg3%P49-₟[ZiưP F1A"[Y:ݠbJ0@D06_zf>LF!WmfJX$5X ZĐD gi,Z&K1XIr8+d@@4\oQD_7|F$EǤ?ʟĠh/eŧs<@;ӂLSBIv Ôڦ&-\s65#5mkf*vT/Mu)lh~noF#FVM\i3R+n\1̡2H)t Z=(r=t̮>z9'{ɧ%Q)ț`|%H~ 5uBZs2 —j \\'zT>fىN*O :h#8 < 1%: F䓂ͨfTьԶL rv6]Of2ܽO  Bci3OyݦM|㨂G0V6bP9\UmմӸ4pD>)m!dl#sGv :AX|*JÝO6BG'(5}Rŭ`Xű[p8Mpԓgb`@.h~EB 8&*{$'-#vk/i endstream endobj 509 0 obj << /Length 1818 /Filter /FlateDecode >> stream xڽY[oF~#Dӹ_Ҹ1:priQbW"$=RIe̓|:"]]pF#)H0IA&[Dwd[b2DŽL~#5CtxUʑҊ88r4a^}me.Wi^pV 1.i! "AHiJ0Wu|N߮/s ""l3(=@8/us1J D!A HEOŇ^ u5gj^KŐpF6͚wM*{NtZNɠl4n?ڢ1eoS[Eє0$_,0o勎|M2v~F0dXq8 MD.Al )m5{9# I0 l9S`n0'`mNA:(qYu&0jYe^vr1HK$o]1!8NJ+Y? !ND(p}L6QU8`Gca$U晗~}ە1.@z7J#mk8'!i qp CQD)2Hri9P;ĝr#(@yn98,i@7OcN4yBb)V+_اY ;ϋ?++Ӆ wUhLۼLkz)AZO6lb Ϣ̽iXǟJ[^8<LLsR?ss{),L!Sy?WzQxx|?. yUi kZ}^X ȣ`@A\>hL@aIg@5SaEL;&cݔ0"΋&PRg b~f_f?:-꾱h4 <2 4wľ.s&8 XN* XKקԲU=91$/""YE`dT6}j*i< +% nU'wp G00 Y7~Ō0f_[G)h&AΪ=H6۵kfP4__]Pd"MO X&@Pc@>522j}5`]?] ڀDMCWN>+,٤>fca_n ?g wy4I}@ӯ3Kyc?f|چ-oyfn U\g(qvnjfɐ+9:%U_4gi{zhj G2Bq@.acCQGkƫ< xd N*ywyw.?$?i>?1k4YD#9̂ىC0kf7CfA1;ah,}s0CKX!nZ/vnzί|¢pzJ`.8=[I-Oqgݠ8}R#Y+${ {h}B/ P[Ecus;\!-`g1 w9jFr~(lI/?Zy?ֈJkd05;/>~8XlSDh@t~2+ _|vD endstream endobj 516 0 obj << /Length 1823 /Filter /FlateDecode >> stream xYYoF~ ЇRp\i-:M! PF$DQVZ@ڝ-"]|;^H!0&j%£,zU*G&?^}ED02є!AƴsqL#两v3ј AOC8jbގ 8i1S}*oz3|S0#̎9"?Qol_/jz|;|PwtsG="1dHUmhLb@y3 !1MtiE0"8NJ#LW,_kDDS3/'[7_ˆ4uEc1E-fYج=8lzc.h`lP/SKc6*C [buxHN_L.>\XǑ $ H3Moh~'b`7rPv*zsBN"҅21a" ኈ4uFS4pDѦGA  $L" ORA8'h`Pw>.i`"#6@^Rא6$;?$)%$~>M}owE^o {uI/ki+_{\Wb5 x  agѓ(E<z0>hy+-YwibBN8`_F,_faB1qeq5g4:sB9IjŠO:8} FR"?D8i CA|_֘riD4^|Xg5^K GDXs]񐑶0Lj[,W^dlV%rOdg D%"m^ #X`#tFDt+:u|LB[].u{ H q"k!aV5#)hh2wM궳pA5?-Z{wa8 {}y˴G; Vs-:qsGC7 l g]ӾAv8mUKvu9ַҺex*A;j~MVu%*`(m"Ӵ܁ueOEZ֫™Q[wgy3}aʇ: Q)12fejM4Xwkv6-TהuOdv験 7 endstream endobj 414 0 obj << /Type /ObjStm /N 100 /First 872 /Length 1400 /Filter /FlateDecode >> stream xYnF}Wcܝ^#i?58Ba4 _{rѢlJd0]̙3%%1$vԕYr">ㄯRrB)'Dť?]`b*"C'WQ]e*Lrp1VE@0(;.2F1朸h~ $`)Lu1gxSI.V%k*DI!FDEXDd O``8"58R1H܈ fX *2bRpIC 8 ߈cƒ1٪* `8PI̊ Jdòt &\!K#RdvbǙxxS,xU Ӹl%E:| h#j.(f Y5wr54X6 ,JNRm#Xkr&jMNxI;,+&ZFER4@!FTm"l%ݨO Y :ﰪS udQ-Oi_s+޹T?_4/^< g8Þwȵ'ALN"AHzV0Q H&(Ԯ'V0_ajZ~~ u#@S^/Kۛŝ;w'=[|s߼=.\hW|Eo\kwk:WOח/W_ܹU=a"їz.o`pMࡽc!Z6"| %6u"F]k.su1hAcw:Ohcʩf [¡١>K*o)Ɖݬi R17$@}pi]]-}*A!WXiVƔǒ7}a~7\"wr[ .ZCݎ0Op{>Lo\٧1\g< $@ endstream endobj 526 0 obj << /Length 2313 /Filter /FlateDecode >> stream xڽYYsF~ׯ@ Fs`pxkb;QvW "!e`0~=HPcZy==}~ChwgWg/IT&RR-EtߔRXŇ8ׯ?_9 LW]$˅ 6e6e;xֻ~![VU&',xHpVԊ%9iˮa٦zGq0M,}ݮ~zr2YvR:c6R_3aU1{r+֑uR)z eN@! ǂ QB3$хP:oJR+IJ-]r[|캱jǺlhjyT[jke9#jٔ}wDXڏ-`Iӕi.u2OA(ofm2kȩDbWBESYb*Ʋ8 ;r[< ĮZE tz ߽yK+B2,WQ0y8pQV!EL̓9`>T>0ͩ LmfI`]7Dž@7 [_WvWd;5,SB6!q iQzRlvMjԘYv[ * Dp3mHzJC] qBn!5خ^_*@+e'v"nm IY084L+D:ERd!EC¬Vܦj]c[֭]j?ɯ˦ %@l:NIR7vUf˥: cvYM*N[;5yu1'5 c݂-u-_il%u9K;$= atDa@fSc翽ݳ?J)bZ0L~_Sdx^oIP[P#*]Тjk'|;9L,rap]Un7 e/P-l`3nsuHuhN+RV7OQNX{[Si;&Kj޶819Z6APl!=K:L 14= C2}$$w7dbPr+Ɵ֑ ͮEFWGRрFgLXUVn׭TB'f40ڑ]iЅx'~3""~Y[dnT`RmR-W:kZ`P)Ț"Ju5)dOdvAcT5{~{7*z:#0xLoj`Ȑ闋D3vn ;x̏˄![hm?n!ذʣ*,3>O;$.ˑ5y?7AHbsj2ʃs wejGĚPM3p9 0<kMi#k~sг.g_| <+PFX'ĄJfnD$׶Ka;O #{q?A- %"StW ݀ A xr5~ЪAiy`xĴpig?wIaW-O] q~|*d~ؔWrp6:XD+RTNS $+2 f 8i.}gIݫB_\},8BO0ˋ;,41,&)8,WȲϊ^Qd(LO;I՝o'd% h!($7RQK Vs_ZsP~q%J8,W@ S99켯4bP +sd'j`iK%FfȎ+tIDQXOKX}hŲT:8f j,K{x5 ${v{~eD? S ˏ0`4HVY&?ސv{Qb ­U endstream endobj 534 0 obj << /Length 2233 /Filter /FlateDecode >> stream xڽYݓ R3zwv:ة4q%R>N(BR/)Qջ-}Booq{ⵢ!,%J"8Kf$c2-wa~w/^K0J2yj.bʑI4740O֒JBHB]U:CbiLMY5ps*Vye3Tȥ,@7+ҏ)W\.U~y5LM!2hg/!81G=ETkXf`7y¡C5  x"X KQ\<>A2!#٦ܵ]y 8ݕue?mX[yQViX;H|حU+{r3hL9NޭTE gSɾn N MSsl`xλRJfSaO .5**F/ U"T" v{#0GW\'L!L}f&Em`sn'8z7ǽo1^?`d>)'e'#W=v !߾|{cRip|;ĥ( 1;GI)~e%`+PyՌ݁OJ3|<•4%xS* ך =rl3 R\7 * T>1N8䄸×0g]BGe-q{.<3o3~ϛ{:HpN߶}_m0IHr.oNqGPzv i7~@1&C!I(*2@kǛzM`BTƩ币$O~EA]ǡ kbZ aψPu ֿٵ\KRH`'O }R,qbu V"}ZJi`uzl^K-|u!> g'B{ɖơV}"Dg.P" w|z()bDȆuf;fs1+qŷ+oƌS L*_ 'd(<<[l?KǼBLIr cRŦ\}$esvX(Mf>.2N\ő GW- ۖš h5OohOG/{?_838;!K8u) Lә=fsKrE1sGnR]= aFKf d _:Ls7 Ρ /TAЪN󹙛>\ք!͋1eYaסRc'c%bZ؆zl-ՈEʒLbԸbw˗Z?ӐcPL??åvjcyП|_ïdcQt9.TE7Ň8įYPK endstream endobj 558 0 obj << /Length 1632 /Filter /FlateDecode >> stream xڭ[S8~gjEwۅ38%=R.đ#BI@?zG\c h DH FUxelì>%r0J4i+A[w<1[ )(!bd((ւaE|G*<E]Ve\sx]`gih8YNF:ܜ򡬲˸ݖDBb+tf5N1ՔOSXhF$AQ2q KcyOjwtN~HZajcxȒ^$<,wuV"O(mMn׋4+n5UGt̩cYB2g[Wr@ >XN Bx&UuW덊&,(սaA@ݼ'YLz]h(\'jPsr|cOI~mxq]Cd4 Oe (~iXWŇbɦDpwKFqcB@;^+;Qlvnu$kiL'fpdzꤾ9`V+0[1;7 F68 - ݨX,-g\|j) YAךXcFˆzۖ!}y_7}N l}\^A_5^$9PN+ìXyhGNRFG9rt=Br4o21bLkAe9?o6"P^^FGl`$Ok2Y9Y(ogKyZpܪtA5+3w51הG4xK]ft} G l/C>7k%va}aE9ѻ+Û#c9[b }oȴZ̟)LP1[lǘsiP?$z͆)fҙJV3f՞rl~Œ$fCw:t#M2ǧ<͗= C:`b ZGĊ6 Q:jc*9`¡; PJ "VĞ~(58<<œB8Fd[̿Zh=8`I\M5`,!{H7r?Ln98q)4Zqn4,Ga $F$o SoR &v-jJ4N(oi~KN ./f(rzꠞ2kI"waZ*zd,3kV{C& $ۿyw V;CI$U!zw& 4uvˈ z?κ{0+ۆ[-j $K֚qp? endstream endobj 633 0 obj << /Length 1610 /Filter /FlateDecode >> stream xڽZ]s8}ϯ#,d[~LC&tA#mWm1}Ȅa~{܀c2,t=Md#cBX)]~{Ѐ􁯟A(&,f|`/LD=.BOy/`#C1(<1,z$An|m9Q\SA8ზo{%u9L۳/^ug4Z&-@4v÷& wI8ZagT k)ݥb.tkm[Q Ē+ 2 tJrKq!#pB3 9S+T$Z(Tx\ߦ"S3RLT7oohlυRjSz62-u7l:4iXcI>`ZT=7WBJg35W̖ZB}z$@a,ɪZ?V}odu?b?hL{mI!reo`Å5֯wVuH&6UiAs^ afZnUt,@Бx7x \YP7mn''P4ƛᵠP%sGib-79Tܥs޷^I˾RqdR :@E[U'& 09V!:PM$lKH-Ln[; '7^F#[TBǑ5[hSwύi0^b;K^u\kΥf^}VEOzob5g/2zUNвh=g [q<(LjYEѥdK4N $`zZ~8"kFĞf^,x<Jw"<)W:Z%Y~sv%A_p"9\/#@Ė?:V6oKBJ:_A9oN"h%C[qPwOi-qsok̔X T 6Wׅ|$?o)L*˥D8K$j*I+A.U4,g _35FNw/e7< ʜ`l^t~j~DttRD^ [;H#mdp;P=(!F I2"\檾 y/[7.^;^rȗݮ׈þ *}S^/n endstream endobj 523 0 obj << /Type /ObjStm /N 100 /First 891 /Length 2711 /Filter /FlateDecode >> stream xڽZMo9W89ͪbca f ؛ ,\n[[nvXWRvg)W2H)MVqbNBoW-4)KlK%LYt%`8WZu:$<$|)OT ^U| n4Dr5CIQ5cc qkIgSC̎+UOuU1F,1m:)h05 [lr 2 cИ! PJ K cS4/gh5J%4B0Ds\бpI3/eSo.XFS ˙xsR ,+lhOgUR!NbNST'͇Ŕd)^ Bťj9LẌ́~UU'ͦ@P  @8YX')sI@N HP&J%y᧹" Y?s JQJR07fh<c&VLbeu׿2o!1ϟO~i*Hߪ/Eoo䡜mF/Jf}g+wp#SV38~y7XT? ߷{u;׽zq亷+w _x18tlDXeM|6_ǧ_ݻs6'_{6=A5p["ten+)cu%I} .0 ߰ _3 jc?q66otm6V} jNlLcڪ/aM0e|EQ&5bl Yb2f,-~jkS{:Zk;mrSkuqN_~j}[{+~@M3h7+$f/a ?N>up:]uo~:Y.uNjS8Q؀Sl%0 QnGM5jQAPeekԇqۅ.E; ܯ)A8yGbhQ}>N.>Kq@.Ëblg6%Rf>Kf #;cv}8R<_P-oQZ fK׊#`0Xir5No,6./_uw1HY,glfjT_M֔|W=vIDzk kj;}՗یEa u ࠗ`U0+" f\5JѴ5_>Or\E%*uO3HRO.TgZw߾}_mu|:|zq10}6tgqi}!tSTTfF/<,P8Qb`\-lJsЋp6a˽B06yku=Tz_L] l%8cqRd=խFͷs2ym"E+ '(_wDV3L#5ܑ ^gI!l0l05,6%mn0$;cF;M^nJW&4yk|jC&6yɫM^mjW&6yugEסrk& ,'JXW~)q~@0lBtT;x⑑T'!H_iiܴK?NIbl[k7aXٕqz0H)c232߾`vʯ@YlUN2pv M bf?ʭ VA }䖣.!dr-8F|#.U$V2m,ǏSA|ՇMc0&Tq_@iWBݥ2&2MK,h2[E%c596cmЦrT-lp}Q= eڔ[*Ұ 넊4bݗ1)!@&F#ꞼvYo ]#5rk",h7@["jS%`MO独2F1lShw=[]F(ˌ@2/2ge$ 2vBýe!bЫ%ծ[YVLcgb{2#lw 1_Ȯ#\ #N &@ M x> stream xڍwT[5ҤXIP@{Ej! I ^+P(U#E;_P}[Y+yΞ=sf9 ;}}^95L@--50 @pNn`(000)Bpx P`aq8"0E PG!aX v Dr90p( ЂaN@p )iáŁ@WWW>pz0,  І8G0cQ8W8]!m`~w&@ C&k&9w?_(儆 H;-(kp9~( ԇbh G<?f% a)Sc`P4rEz#ml˰y"Ώ`j8xDED0g j< e=(4_n Pxb!.0(` XHa5:dW p@-uU=-?%mGO)7sdC4wUc¹"I1W3啖p |S MPpup7qBxy8 }@d=[k zlr3dV)a AvNnT K_:a@]Au 6;.JBO~J7' :ɁNǛi{=[yriĨᏖi%,^6u nj\tDvSv8HK-R~d|bϾdo 12leH]a1md9>CY^!d?{bmo XX| &e#;;?&3cL|;<,+BnmPj,~jrHQ@}ߎZ=~C`.co)r4nIň0ZZAm͵1[Fd+j =b| b\Q=AQXwю9,"~x7A(-I֮Lu7x&G.\j\W߇Fe(eI~P94e17P}否9\\[PM#D=Lš3UYlY}%ls ~pB{=5.47uGf]!KHæA *@X5ۦzQ#lvm'6sTN S)=]cEFe)OxZh% -3Tsx#AB_Yik9{Q\F)oÚ6(+Lnҹ}k[x|[w0g{N7ӵ72A }}3t l`4QA+9-1ZCq6ϵ׃͡p֙[L  { W̶?^cZ]"@FemaHK-jw 3~o wKJ'E>MGSwi׸kUM"+\h^^]TeKnMYᨨg鹲ؙHM+X6B*x=[3u ǝne7D_eC[Y1*)g8EqAAH Aطfö:d3 b#qB; ԍ}$41z,У:iQjj]1O{b +wZCU^{z'̰(G< `2gT..3z4Mks$2$eb=Cj){$~j!> 90STzW=QUpNZ':WT;Ov˫Bd^Dž!ӜeD)K/#$0ǔcj6ʗ&- {gTu8IxFZWPb1 =6i rzsOJ5WTN8x{tebznh+/k7.OH'^~ti;k+l#^Y a}a )ltꛓ:Lz9?ޤss^nz3vH^RpüWgLHd2d[r]' ^m|BN_$;Mwc@+3DX`c;4*j*z*df'#H<3[D#͓a!wc /ᭅ^6FR& }ZM[NN\rNH%-#|_VRSV+˪=2~SH uiiajtC̖\SF-aTJWq B_*ˆ?Au Qi*mK |ҥ]^ -öm_32zbгO-03dDL4|ݹ_2i)SNrumn@9&!0,x<`| c 0kGYE'=[ĹCڱESVwc [NӲ3rw??li!Ǧ#wU4%*lD(JI`*^DIΗ bVmۋ>7I[ѳ-T kϮh\.L.77ce $A&԰PV|Dd64Co{k.^</W>p< xiXbҜKavqV*Bq~ \JT*u݉k>dhe0bYD7X,[FOOlTlJU#fo f6#BAގ>C_ܯ"iQbq˱" N.j=/rDvu^P ʴS-/cl3MVbmj?9B*d˳ľւ7);oup<=Byi6YɛGz0K|3Z 1UƛIvA[r9,T̵?P_%ݝ+IBL{.Ŵ]l!Gvm~)о |bE61i@E~cE \9Ub悬X8k LV3blzգ.=C ^!x mB m/ZKj9 t̽1Ƽ2ZVhNෘgs2JV&L׌JT}48cgּܠ k(Kkm&g-(\ՉSz]>cobe}arK4?sfPZsZ–3SjHé~9摆e!bxy*yjD[m5f~6+,ordZK%O8xrGT㧛g[XblJ);~2+<.JDZǷ`|U+Bcʎag"*vQM)oůK\ٳ~-A8vsu՟V*wظgO2?HN?# ^/tW=w;XQPF5b}|v,c T&cFᮄΎAEڹTss6sn앤zB 1v՞}K矦/s 8t˔2b,ĽPq(FRX֯-(]3CkN./:q?ӠTU q85Afz⃍TKߪ.dsaVsN'Uos(56|*CX)m&$q+JJ8Tv5~R[:2Ŀ v7M/)DY(̇TJMcb6i3em0LP Wa48i'EdV}X4d59jxB0fll"nhV&OKI r0g{re=]n4e]c,Rgk@B/6..S+5 2Gd%[]2蔠4Rj;E=V?$]t2.g9KrVZ@ ؗ|r/}y$% $lOBwqC n[;<t",u%o]:Mj&DŽm`Tm"KzÒ=(y3\BUzW4}nWt2,LKZ0 v3(V6V2"tHC=2D!?`0\FKSYly"3,I*xg`ns7ťHFםa.}V|W)^PM*Zb>Ԅg A"e*<#f֤ɸ9 DJD}InC$e^R^US.C7.t8DB4lT־J5pD+o&wLP?@ LؔQ)=?}򑴻(f vwlaBJgAZ>]u%nX1 qcssB3jA#}Ni wP 8jۣ@?\Ըg8Yx܀3sAiaڦfGt?,YW~`"'Zf2!n+zZŗ:|OHSVnUo4lwCWY(cw5m;R3xy:){$4ije~19TcZ5N*۝02VEbpj@v.‹ Zn'=-5e^p6E86 )p31ga%wj5u@?4Jx'PGWN'=EQmt\gs@%)N͒@XB.}QFbV7v=r?qvq-;3M/9XރH0r1|~i]ڃZcV%3puOk(,-puEmOu ^ӈ,&>,4I ^ԅh͗m$V>Zzy'z3uPoh`TM>*%cFZj-߽)ZF*;%<]YD> 8>nտc?~lhs/1b1uÙ]nJǜp QDB]>n^lD&5Dgvײ;Vx؋8 {O[ oII{]pyY]bxŬ:lf5Z9j^ekU*w ѵ!!91_gCAŋ;XcYԽj=f? V1Wcbݫ A=@/BnPj clM޿-[e1 =qVCW]d_#8-)7OJnVfZ_~rTuB~: ]/93ѧztb񪲼ݢ)$ endstream endobj 662 0 obj << /Length1 1461 /Length2 6296 /Length3 0 /Length 7276 /Filter /FlateDecode >> stream xڍtT[>!-%5 )9tI3tw3 Ct"( HI ( H7 HIJ|c{k}ߚ~sg?p (9#! %¢"Ĝ&P &4  !`S0v8@2@Iaa_ @u p1  uuCak q%!H 01 A+ !#$+vD ]yPA@? !+$A~/ ` xxÝ!Hp@mۀn@Ax r;9!=p(A A;4ü ;b ~e `LrBB=P^^P~ܲY EB0/_x go!S8BPqaaaIiQsr1z <." P8 ސ$#P' C\~1GB?l1rFaꯐH_Uws?@0@@D\)2I"a ?i&-x /߱BA2+|y|vYPq"pM-ALcaӏsd&!w6^u31 (]x}V3[AՉo߫nLZ69@Cc(f۔~dG#XDE̽4jc`g= THӢ,)}7F5Hf%(^Y? \{f|GZ]ZOmdקlBUރ0o(5}4-`m3=G\wOO/PV`rVsd~F ങC4}Hっn:= .k]RF\EH]9}[&͓ >PR7],T-gIY(T\苳 {*](ܴͬ)IАme+^``.W9"Kyc騬Lَ t7VgFm^J8Ϗ:om('9[h{~ˏT."4e;ZPH>TEz#ά[-}f{7MN n,buN|Xf0+y! KbX8X0%aWv:sda-Qaj- @Q)wּN1xjݥl3Ć;^65ԇrQewl,9TbM K<䧞o)c̈cXVr?a&ɠ\%"i"kYn&1mψ@T--R@brHY TW  ($QM|+lsmsl\c1 ^ Є/;Hqq,GPUPnp}) ɰr,@ +/;Y}ny _B ꪪ2$6iI𬟴Hȉǘ>h`MJiFj{0UƒfjkGY/;p,x46Ygk6T-cВ\4SN4Wf ^7M6k;e cDI@[JEd n\;z,a^%աOD)1=d[YC7^RC>XMcx Mp}U;2 mJOee._Ghl(PvLv2y v)e~"YJl%b3:5͝EEv6$dzVG0kE{9 X`1C ]U}@YqËb@ݽ/GE2L:9 (vHtjk4+Uiҕ3&Eүۗ&Z4(D':5dkru{j|zh5@8Lp@!%N}&r̹١B,Q<+M/ofiT.Gg_P(h-Vh<) *-IƤ_3G͞rLOæ׏rInN\b`v#)~Mz/<,JaT߀Rނ|ߖewCj9M y~ϼ){(́ F7.\/ݓ)moܧg49:9hD,`R;{-eǏmrqr?YBz=SO$UQs2RIc:*Ft- SDpZ؇EE 'cYH2zzF{׳*D\ϲc6,qPEҗv*\eK~6vN蹃?a5Qlc'Y ^†پP!(ژ^db%!Q58j\=t8x2; T`vDC:yl+CA2ͩEgUZVu dWy XJƵg!THwo^O;ípo7)=~uȤvT L'!dSQas"4zò&L'Ytr2x!0lsT98ɥ#ezЛRg}]i\{K|"X?(Tɍ.3Lp"\&0VN6C;F@Lx" "T7^~ C(yJĚ&|Qz~}n[:6O,T#*&+y:85%w6#e'm'qiVA׮}_vt)1)ao7^MXfԈ뾨mz'QS9YcHEQSlmr3W -pk,X'Gi7 NY2)Niʐi߷a(%=<RxZS%LT?T1kc*4vg iN| di {kKb_@x;g&qiVoF*żLvww~/6 }H|m[prd$AséXaG~M[Pc|1H#ۍ~kh7j}c?Xk`^:6$"}-Z0%m|xh0M⓬dyΈ>U1^4Hp45VLúd*oɭOgTCx]W@= ˚NX\irWx)߮A|XRTa٠p&ejh\߿yYfo:ljo/-B. i,Qsz Z^7Xv%ؑNpah݉׸"xj:^v#fp?$yI'FM-b)4 Bx\1s=rl Pt/09v.~">ŭ!e sC#&,"dmܡ=MS0sVzTڂ떇*ʻݿٽTW$8>Az8JrпK(X*Ϸvv`>+ƶU=uF]HV ȷgڊ&sGDE)|2cnsexg% Lb´3 Q1 U Eq}SOͻF5-}}}EhN/Ie] XuK}aQM'. fS]pKGrǎ$&V2;]o`!S6lEA^nҌnf`&?O4κr0SkZNav-0 582>q!~dk;W1^ oQ S* 82^a]jC@g/Bχwv6nЌ_\7:`'JzaJ0|u(ɻ7.Ieq?׀~9svJLBĶ#ID#c sb?î}Szf}pqqJʐﻢt xRNcI$@h#9!ԅnwS?IkZ|Oq),]xj깅֋4^چ:okKhd$d۹;CiJiC:_Z7MӔwW9$|joXR<5C_JlŷuLG[ǝ! :g3uq~uZ/EvB v<=byZR.z НT+g氢+5Qwu3dqLUk,icY d\/;^  g) eGFn &٬߼8MeK"NjN=*qe}1;PQV#VV~]GV2|oYH?۪7K;uS\qD+zH_ ZgSgخ1:}MDf[qCwEB`l>'\-m|?E H-qFp 1ްK7$JAfH{1%I.chW IgqD:}L\ӜxnHuE2qr M#s>38}cϥok ӎٰNN^eOE,UK" ?7-:u@9*|VYX7f/bm\ue á5*j?+(*ڬADQ'%e?;43ma>=wĹXM4l,.} ;9ޕuK܊cy7! OmC_'4qSؐ坖r\tȧJΚ*Baw6`dqYb7oi 0L̙T(չ#hf^ }W0ldٶ\15(7K.wҞ碑G6nV|z8|e~csI@٧lYk| 1Q۠mk5lC U xN7n1zbnWI~ 6hEjGz`] uiG}|Ya^#EwBkȲB>#DX5C} #1XqjG!u5:ťSZ?` yp?O{':g-!<ɳ? WݷZ)6aXzG쫨:P?Wd썧g8;bfc-Ntt"i\6e' WoNT 9KexMa[{bfkW>+gw}o8AW1NX{֪+*E4ea!8r❡E#VDύPvg(+s:vK)S!1S'R k+a endstream endobj 664 0 obj << /Length1 1473 /Length2 6794 /Length3 0 /Length 7778 /Filter /FlateDecode >> stream xڍwT]6" ͍t )5C3 !H ) ~SZ߷澯\5LZ\26p+"r꺺 H'_v,&} C F[:;@nb<js*p$wv#o`fxEE9275N. Az+=" vFp8O(Ё nWˀgkXL=CnA[C܆l nꀮAV 9/7  ;aP` ujH/$'"x%. (hauA"P_=Js 093D`Owo?l0_mظ\B EC,?Bap@jo鯊=;VAַ?gWU]o?v:yɸ;vᷣoU@ݝ۫ "^-(akҜ0u\ n@܊ r;=^Rf 5f|B  {;62xapmp۞` wu/HQ"߈v$xFxBx~Uov;Ŀv_xA&F!! ge %ѸiD8jdJMf䮧5}*{$:]i9mBDOU3z^ MS@a<+nC1gvq7Oֆw)7kwj_bR<%oA-hu ziYu }_>AW4F%NƆ/ >,#V8˞Ie~J#@TuyC./Ass.-c~HPqY9[Uu5Q/ rzML+;TСK,pj{$4_( 5)@VK|س>Я\&ܥW}s)_y-#ҍMo/8=&&+I:lLaqq[1 ((>;V9nck(&T |q t3"C2~SO nk,aM/.$)E<хO[@5UD!ӖbRZ>{Z!5G);!RqeITyjʛ'fz, Ĵ 4tCP_Tf<6O<3.z Jn`"FKtZ gױoIܺeA^8[I=}v(#L]wW7G`[?MV6Hw BWfg@3Zp)흅Vi(ը;ܪ!=_v#Gqg>mg\lqk_4Ybl560Ms{v ĖyOXLSW$rȰ~'a3uXI.k{s+7C)ۢyQ0[ K/X*JzUx(|emyzhE 7aevN!U!^tY!,fwz-kzRsDxhJXk:ْ.L)B)>²ȁKܪ`*Ew %{мlK=eh!{m`XvT<ę=*źeuGƂڞ\eQMY-.#r||Kv=mj-2LV)z;(ue$1y*zɈ9$=e}?kxH[|DlӢ!;OaF} ~Xľ&byQlWO$~~$K5soݟAe!'45|*Ʈ27ߵ(O[9ԐieV>}pX=*qmٳ- t.GdT'I Uay_bzilJ^KP m/|zzUY>El4}ŜCXc'2<>AbtDYW%:;zGH`= zK 3Y{hU:)ywBЏ{fl?ȼg6m;e3H.HGYrߞL%~? T3BSG'A0~ka\ 0b\KP:4C7 a|^>ѪmVǽIF6絫yds&s5kG/.Qoܩq8gVO=]3(rn{ f+8{Z~kXja;Yw-O'Ù.x/ڲN.=eؗ0U'h͜%֋JR7H c3 ^<\FbxMC\s4x@4*`&]ۅC2_JQɈ$[YwNQXYBJ6z3 F'zMLoƪ򉏌,|X C zqkdG̤7ESf*- pBYE("ղwŤbkд- Iy6XCxTULYO]Yvj%8&oIυPT~v~1m.;5Hcb :[q_psڞlCeզĶYxi9V6 ͕.VC,bSٙ !)AY-E{R\HK}MR[.|ӣ\z9 ;ݦS&3ܭ#R%ivʜo^*~aЉ;̎,-1yI({`'W;K>k6no-;8(q~{Ҏ/)Xv̽}%~-D ރ,Y񤵨J1^,I3:0x<&MSEnS}PLT&C:/ Y>1.er^$b!sPp!mW`Oasb8EpWƛ*,Wzv}2~Ɂkk^ZNdzM]+ .tm9рbH0|@|I׋{`yR/ QEGkL9K#_f/Nw+]!tV Sg8D}zz1 DY{:rO%5qU,#cBF6}M=xKߗJ1D&Y>Yĩ1n1crrײ?ZN ΣT)u+`dFmcmVvF-ƀ_?Yyw􌳁 cO:Y^|ԶW'wk!3х?29Ǵ3Z_{L+A&sA1t1ѼzCyӺP2z}f{_Aw{/Cc5̻@ L }P jaKG{h-U*[(RuF9ھcD1sAZ~z.f`ķЎ(Ȭm$?s5vx^0+*Yж1g;(P︞;1Qo󭙛-/c"No`9h !{I:gșO{ܟś"ayF;K$n:SxIMȻ,n(Z1G;gHiѴoR+2S{GaV~e~v0ўku&3٤0 o!zfVnrg^LR'ΰK.2g?_P]w8" sy?iH'dm^v+v!-!7M-n^ɩ?ԯٿÂzs^Ƭ\ڸex|¼G0@2DX+pbъL6ij؎TSI޵WT@k|J02L 0SGfL 0R 0>1ͷՎ>>?[ hUuREy?O8]{6-w)m2m9[bI*b1: Hx8컭 ZGz1 0 \JН:p$BARÍk]_E5lgKK|z"( K -sK9}O4\w] 07gYsTb0o7d ~QoBfS:Bp0;4׊Zp44Ho8idzYi$W`u6c_s*Ts{:{0zoONo! ڙ3CєD sPFqNV8sEt^"J#9 1[W=UWJJ'\, 5Tzlp) 7n"3,LwDɸXgWelt%(5yGdOCʞ$YTC@YTafGaJwC9S>zTV>&PSEw_sUdeT]3{wux%8Yfbu.MY#"""*H^X''ϲ_QTZ^NZ{aQي-zwf/7BJz6۶[.߼ifEr0EYgTNةxȲ]u8\H'g^w7'ɬ}R};ȭ'?9CYΐ'ip^*V啭+7~"t2j~n$OOW3ᙫʐ&^}wkLs]~L4fRb+'Pf. La/Wik8sH/`M9b,Gx 'WB CZpk{jkaZun#0UH*36 endstream endobj 666 0 obj << /Length1 1414 /Length2 6457 /Length3 0 /Length 7423 /Filter /FlateDecode >> stream xڍwTS6";^[ @J@TA@HUzUHMz. ( ze4=]B"!1)!q)  J D /#D!(v%; stB_-ˁ $));A@pq^ 0B8 h?Jp8R 7(~ A&@0v !hov pu' AWih!6 $ r'n 8w@a W:[T ̇r@(׌\o ps(_)Ð}9\8_c=a ?k}4@J 1A_rGyAh'?``q ] e_?^Oם5+G,lg>?~1a@R\ .*g}Oj_^o{}pYKqM\</BgNWݑ8_'rb 뉾Z BR tt-6R@0_|\ap>l uM!ȵz %3aQ1a\ ] McN\"T\ ے@"A0%nD^+7M-{@0=pu m8P_j3EsLf9iJSh.K֟* xDdz{6cՒ9IKcEq?Q#uOX!{n@bgyӒ3txzٗ&Ժ 9ٴu#ʜm knEiipF٩bC4ẘΎdr0 J_M̾.34kQX'JqE'nL" -xLv˟Xl;sz"Sx`v"4e ,K2(iTĜjk8M?#D+KqU&SޥOOWD-)2L#BaɌ#A-cj,R`vڋceocS*PvW[._2(Gkj[?{2lT6 n]jDX6IV&=Fs…z q@On":u(mlS!'~mm6 .>鬯ZMI.յC|uAK[>~7bg*[ ~wV #=S2v:$ Ħ33?⦆9NYqLO 9̳q$r0T 6e8|pQ2t"h:ZMxVKIdu#6Wx=L[ld$p ,&s+9iWfᥧ3놗C8ŞÖ3BKHx+F­6-7ٹiʫ3u+}s-?|t՘Y06;>;"tv#nGuZElHk*p^&4lpwI,JQ Ň49w!jV<Օ^fߗ)@tRi(s[aCB_?Z7eMFǪiD-elLt&jek쨦k{8~G" [q9J lZ>soa6i %])VsnS<*^-I~ӝ(MQ<TzU}my4fbrQg&{h{Scϊ6E ~ʽY3gK d46Ҹn@yS˩F ͗?$owE|f,O]tt+)Y5lJżkmG29Aլ -}~$ehqJ(;դP:|˽ۆs'h 7sِ%g8cNEsJ'] F@^ϧuڱޛNymJMO=n koct7~G~PU^&!MO~O9<y"fKGEaa ِUT'¬;aψwp¬X´ +^/v\ߐ//_sAyi+.|5ss3~q{X%g^IjcǤ{!:7d8oǖЁ͒?Mؽɳ.wR?Q|tYFkUaSGU&zkx,[dtu3:+SnMѩthB\Y۴[^% T.8,R9{A$֝:9fx¤otH}̰m%P4Wv]X}J"qg.EԴ[.;vGu)| :J@@J9%=-bS{"Oy\Dv1/#aB6s)8 %>1HP5e|m̕RYs^wnC,C]bG--- ^4/UF?iHBY +d "hir }Vq?OԾϾ,syШfI!`)h`:Ĩj{z 6v(*ycz|/i,1^>jV9M:#EMdB5UQ:Y~W.EMl O="X&ӳy B7Ŵ|KF %m'bNԈ@-2Kede,iHעAuކCk}#.<,=PcO>U/mGfBz+;6?Bw\cdDM8Ct_]9 xɾc'@Ei,?J^!=&LjnPꑺ]cJ9::jb]'HXV X}Htn/ϵBEf1Rqf:q"MbEGC'o&S7#RoR%Z}X {4י$!02)* oiqyXS7LZ=7,A{>+ikH"-KK]=s-#j{c{垺;7kCc0Nxjb8'_o4 :o1>ѩB[%>=AUAXKLG-;q\³Ēs+qU\V1x4iJ=yE-;d ןɛwwX0q{;x.88w]3S秝7ώ B陦g^.}+YQv ~!N0a`UtE +K +{f7vl;dHuE{e v,8͵.5/K+ NY U$|ahI6ȅv"K^Ps0}*SV F'W,s}-GJe3%[SKmEq]ɕ(ghxKkuec+\}p޴*򔪸y4*sg{OW>]So8( 0s>U33~Cѐ/$ 5mi bԴU&Ҭ|:Lf|xx?=dL`{tXrP*AWME mD뀾ѷ#cSHd~-;X7QJd c_ˠi63QIYxB*rnpn[=цNq|v'D̂: H6},4׭ ;mIcs%br+n|L1Wrܧ.:JX"Vfu=T^%8-l\,ScR!)F{RWmd4B|:s 㗸Z, Ol1ܰwqbݖp(4 8J+DF_˟픓qsBLzlȃ 5\qu]9JW[dLhoK CLı\>EIq"u_oɾ[Sc#Ï\$*\6 %Bzht EflUػ 4pƾJ\"dV:f9OkEvķnM<5n3aՔbYgԖv~3h9nˀ*ŷT.&b?ӹ$<@%FMDz|'䫏 "|*Dy\YS.7m$;-f:P]n؊HpǴX{P3"o%.b}{[ҹDT$xx .PHuy}U}vu?hZ5 =Pޟ<9lqg_H|Cu<'6XgdtB–`X8G;fx@`-h+1Sa:J۠G荷R~}Mf!ij8Cy(嵈Ї\4˩>Ql`i(jPfS9zz-c(|!FcSa}pO氰(ܮF~VGi3mۤ\1{i ,a yo򉱸&|L7%Ղ kJ]ІuQ6Sg]zqe?g9'"3Q/mԵVoD'D-=!<3%#@? f=?+ٶ˨OXcW6^6cٺwHș)_4Iaj/#9x"NG_?ʤy{ƤCw%RO{OH3/IEOd"boYWF$S5 9Ⱥz[|'Ѩq{d ~~e6DST\SLΰЖ]V$0!@t|8fH&=VG#Wґb\ u6ruY ]{̡?ȪK?X,,,w7g$tGacȃ{:v>Oچ9{^&HtŲ'.$֜30=wrhui- XOApqxILB4LhB 5ߋ"xK/"ܟ[c'*;>L] |\)%w0C[@z~!#5+(3Anr&Q6>U<7bATZҖ{'RSN:֒fuDVj=8u#-qutۜNR0gcia2+&{8|^dҽ\(ۧ>Ƞ|#_"vB,KYM;.F 7iZ*=G}L)X?)3 H%Õcp킔V0,SUmk endstream endobj 668 0 obj << /Length1 1574 /Length2 7461 /Length3 0 /Length 8514 /Filter /FlateDecode >> stream xڍT}7H#]n`06b4H tH t;繟=;g}?W_ng,z<{ (j xqYXHo E%KC D0% 4`!??@_oE@ uh4p'."Dr6Ȼ=  D:]QA@~r.DI]=y2( `{xJ]Ƌ0rz" H`P2;=Cu-GY7xq/GPoc pupG tUxHnKD@( hR:"*>O TWW0+?%_u#| PW^n|pX]/󋋈 /ȉW#?7ooUCP ABO7'\؃pxG`ȟ3jP_%?~_Q s@a~Q=b>-CSM}JGxE"QQa@п_p ']TN/ A V ԛ3+7#/췜Gt@1 mjj `JՑ@6QxTH !ϸP?0 D?_ 00__@P ELJ`( ( t Ws@^(Y ."@ί"\|Z]M2F=pQtWsԛ ܿzVDSP8)~Lv͌ >H֧#ĴdK5zsB| (='b̠A&w?1gd^C[=%2R7F}z&߆?f iv׊DR=`J"KhDcU>WHOb*qb]]9U:_ȫQG1ft~1fw>|֔X'LfZZ!XA7&9=cV{ QV~a8\8]BNu4L =tJ*@JB5E/ʌ!~`W!yl24mnNr4 ^siˑ8lPCUBN|~)DЈxHk -K瞹D|~jab!(K$߸M! fA]Qy7j[|2Ptv@8ؖU$ӳӦ3 XlZda}Oiލ~˖~PU)V՜(ܮ,زǣk|OBfv΁Jw% !|Fvx&^I >p)Lp΋i݄j.Z2?i#nvxMOtQ"[Oh?yDg-kSw06Ge'QE3EfzʇZׂmk*jTv:xQF_0a3QN;.nKB?ɚcP% "F7pxIoTZ3 W,uDzCf\1<= ,-s%i&ؠuk&4,BRw`)WS~nQ"L%;V"9H? 8; }V)awbV`O"SL˻j%MVo 2v51HK-pGmUuX1U}oNϡ0ػm>_KE0%g˝O>Gօ<ےWԳAlY!-uPPwa]Lf8h 1}S}eayV-BlT=/g˴eOveR8g#D (<6T SuRmc>7Aڣ~mS_&Y"EH1Azr=nC|*Y>3]B MoeζK9kXj=Zԝ-͘G.{7UrƀeG=/.ٜ8X.~oOY!^1>9&'nxFDKZ_a4?A__oX#}kT(~ef+/|- MT _6N{9qQAj͇537 W06Jpu,m4N} שC;pb^06SLdqs?Xc}-;Íwl,f9$xwٖa|nO2`1]{Ds!rdIEvgߦ< S&?7Ij @3՞@޸ġAu\{UEY&@m/-mo9>U~8]V M/iPB'M2PduOػӅIzu\ZtIs>G{>/wuIA\R[k;l~kӼ a@1z32LRpȞ &w{*R A _]W glY寮FF% t GL}VJs;YMD3EoI=iMӯ0RvjwWj=Ư:[L"Ax  )ŧqnձoƩWD4!4W< l2U>2wRvGP-74/Oju[D*ݡ{C}_yϭ9G|Zt5NLÇ5VʹoQBK4P_Q"HX`pEb)e1RMC<ʔ0}O7Xm" $!? ,qu3In2qF^68H||0=玸ןbWzۓ{!82@- Lq {}c|Q>űNs'L }ɤdXn||~Ìћ4%U݃6JkC Og˭]GVe<.l 0q A ?*9M>ts0@h ^AFmS<-Q0W>r! AZ{:/ω@/9xsx_#(WWzk{#?,TOS1rQ;y4kY@B%*S )doo~/"Y{jpaģ&8}z{'ܳ"o>(.Lޛ ̷4%;cAmZ):TF@u9aҔ5!w8Vbm`-,<aUwBƌk:hPnFN`z4i}Llڅb&e>0 {m/oi:R'&E^:B0ٰ˭y:, +;q)]2Hpe Pju8~zvg+ DP,U؏TPq7F27gl:kwd{G9[7Od4 eBu.#U%S؛0-qn?q)D]-BNb6|.C$:<PN!,~@MLfD;wavqa~[Ky%zi!w;M'iR;T&0mofS:ỤطEOX%f:B]7,c䍻y/8ɯBR43.|8TCcӶڽKv,4DeoY=W}N![ U\3OW, /0~@)l.OvANAd-TIA3C;©FM$_RZTu T:c@t=UuEv7s<["%Mq"Yk/W? 5kYx6y${i󬦢IfʙkѨ(7`QRY*s MV {vsux˳}I/8j/ 6Vh 71ȡ"}άR>plB-v7@oEEuXWB4y漞ScFVLA۝EC#rIȽ{RSiWwf5\}d 2ElUB#) 4D4{tk.iO%&Th[0|@͐Iul]nCʽ23D^5uIFOo֛/S'n_7 FIFqn+bt<쥑/5__ܱ:/ E /KeE" ϽT%5-L$Kxq0}mlvLqlFk&c:~-,SeM~* #ϯ+{ 뵹Ja+ݏAOCCćE&C \%-5D=r^Vm}I6*WRp\7!fNΌg KlyQrs^,?sK*3,|c4V?˵G6ԝOq%exBG75$#f%Qُ5c1+z*I3ls&>@;}͠OE6Rc NXC{yg^oS{+;dKcXafmz2p{*[]ȴ$,CcQPeɧ*]QP.%Eoчj_ӕuIYB88/yEe?>ʘ@;s)lbd;ċZǻ=㋦wDz)Y7s(,llg*ʱg=B qG{J*'V }T/ܲGs[`eb~j#NSY/;`g=7M R{__TJM\dqa}CvUYPiTh'|G6{cGXQoLtk ߎr4dU/{OUΕQ݁Le_Nfq ,ɦ П5p#E]VoRcXqWzzKholFs*f!2Nʽ2dcjAH1ARw1(]YV)|+m;Ǩ";>dy⻣8=D]ҍIfuQܛQ ݈h׎d-%+u\]B1CZϧAi?'NN[}|}(Ti]ɽˊ)bS9Uf$*Y'%bh ǤiL휰ZwrO&}ȁ)={(yX'6 WDJT!r>֐R.˝ǻ*߿ yW_m㍇Qʏ!ޱKa T/g:c Hg*y)#vOKm)tI2E+`w*qx 1zmXua ` $cYߘ@4JlĶ:D]wqb{qN}Ǔ\^eKgX)}?Q"%f}\(= =4BDZf𮒉R 7K"|ճPYfqF󠾭,Ӗ}+:CIs9 ۛ h%d1 /΃¸ rl $6OS$D̀@܇T&N}gɏ8uZOAiUWcvwEI)/?p WUd𭁞:|73 jA`:{qLC*y8_C?{t|(W IzSc)km?o۾b;6 I;7ИiF"-޹ZMe\[Ǹ^ŠNW $"Sʎ`Ujr~~Kǂ=Tf9ByD\CL'Tu?ԉ^CGFaWB۵aimjRZ*6 @/VRg!ϡ,AXeNrL3 Zy`5sGetowče>&`BG{jqo\Ko_l}58tUX!¡GsV~ x/lXY orD\r)RTH|7[%&s\f4?oԟzz|o8SOѦm?U|~+7gKq{C5`-[# Qf֭ h/H_+ ZmYY܂+k30((Upز8mq >Atk AFy V1 V<gfJ΍ӝ)ж*RW,K1UL521VQzg%'].J L{O]?KtBz%Ǖa=)mMΊ TiJFt%`&{-~f3a8 ~ ӈõp<ޮ3N\VI^aU Õ'%\LL~tp41ȧ|u–g'G/פeoˆø\t]MӇ̽1#Xwƶ)[vH\e<25u^Z gcdC,<:E UJy*9S+Ч6y7oq2&V cEl39ECŠ @r;dLT ߐ~H{jpL \6d,1|+6vpG![";K*jZ+ }fS9; o= lZ&gbim zc Z0T"ZN@Ö Pɕc&<IH##g@SztN"Aq&<Lpj] a+2ub qבǓ6;h탎]-ܾNg[>ŰO]" "vXUCsjIng ¡;x 0JߢNf q8"IHEh 5k᝹e-ZXq~yE%2n8[;9_d6>jԩyun^0*狩j_n3>nοdžK)Tb-Y!Ӭ^{[wMK4C{.4\T J7eP(K9Wh_=- f}$$ė? /./S)ǚ;\=x|ƠFaܐĒ+,j888RUyؔ5!rgbdvw.C_-w˻<4UDKUCEiVbNv!Ϡu mYln,5ġ(T/,D^M/Wϴ1>X>;sO,>,w˯D!aђS_QM1Ͼo\4ȳC#kѸVX*U^@9V8iOKΛH^VUO>t|xmᚩÈ?8=WV16rY5b&Auq>z<.ԣ;2>KӟlO#Wh^ ۽%:!3)a#5n7^"{kTT630ޟǐ endstream endobj 670 0 obj << /Length1 1320 /Length2 6517 /Length3 0 /Length 7425 /Filter /FlateDecode >> stream xڍt4\ڶK-D7z !E2D޻(QDF'HH({y}ku ~-D0o9c(C72e08DBB@ @@J0@KCQDJ'$- e mPp"aV`8@ :D;@+\h%@q`h[>EB!_%? q la 5 n0+(uc@#MX/OsBBr#1 {6k)vGp/ a`U=?0'4JsU/77mVCP8E+?ejuw?õ#^߬ap2 .Np ̍2( @Pw+[_ <75x9!7e@}`Л .PTF$$K No7b_#aS _ϿN7 OR**"^~Qnx ]0OanHM77ąs3%foy_y88s`G_(FпU 8| pRC!0_,-ސ*p+זH$؃xCa11:AY#7&'$51QB .7a7A# y+yߋ CgV2vՁg n['9^r{#\.+2> Oo-mp\.5Fuҳӛ1aPOpz)&z/͹7ZIye/RR\-#¡I&чX;u/0I#jOδ9F!y=#Ӷxz4P}Ȥnޜ7+pr36YT=7`.r,/Q=ПrU䀆#븱g3Vl$= be$eI*\X5z ,e!rҎBЫ"%TF?y4C1Ff|Hx}[Lq#z AV3||'sD-q me_;=@N[ Z% ,3%ouG!J֜(#ػ"dK16}ՅIٙa7 {b= 7K3ɓsOJ%~-2vL=jK_k1"_!T h?2q((mwo϶S\Ơ}J;rZ8ؿKne^ymsgWTAqר7?C|Ryn-kt3(6.IC&\p2a^ `:v3{msigJgRZylxd B# ;'I5 z3q:RB%I=b` K+ .,"Fվˎ,!N^#ϞS9ѻ2o4V D>*1>,a:KZ،Gr<2;5$~yLjWmB&_p|m}͎zꩭ#'1ǃh2oq1|v/@6J,,1P>/>$,81Pn9{adOC.:;i<{ư%q{_ :( "BNx(tޗh*v%(o^7*ڹ6y}&+aN+|sg,}XyN ~QduUֆ,D:]'CއLmhД5 6| L{U9_?̰妶\$~riH>6C9nIҲcE%RY}I(ۼ7`0#ayTbeQ" Qo`R⚅W xG Zq]@$xqi㈚l%yx'Be cRv{;bfj"/xZw h%!m2#y*+" DZA *׾L6C4NQRoa0t)k\t|sҼ  }C}},)[qL7^-]S;D{ZTm2w"Hy7jGc DwG] .3ͧjCDŽf6ﭼd9}"A|{Z&Lb}^x=p`X([%'<om't+R$G¡oU ˶씱ٳ|" ىՌqFo'5eۆ4]7*n('B*d?ajl=;l6Mh^IZ6u\)~![xYgsia{={]2^ܳNjSIe0/̧Köp>GI%9.wq { Si^t_#StMl%amD T#{UZ#WAF-E:C KYa'tx$I^|Yp.}0aF$;n*nz6b >۾Zv $V}0[?/Y^v^]޷W0"E`B~D&_oZ‘P.GPlJr擩3w~.hp \E4SU/O/J4cOvDD?|}ԹơU7C믯]O.}ikVc Kq|YYC J{s_~uMnq%DʥJj3݉C1SvSn V oR5)En2݊ K</|+9r+Y v]v&vwcљ4f4*zVaczSؠ,zT-5/"DNDDC& a\6 TY(뺙7LcWkA`Nmwo ӬmߦvqMe숍n2 A6Ij>q$\v?еL}Ec~ yZnʱ+v'pOep7Ӌ `/Hwt#; y?U$eMo*C= B^X7:h?-4^N2~pRMMJHrA1T&+ŴžuXjAѨa;\[1"vCw]2Z8rVj uq)dgs/lq(='q6vt(5[);-Ӳ <^ĻјQqIr2aqez{Q.AEpyŷ}<ܘo5 M\بM-B_2KbbKFefI֣-:a""Xl 6:vG^=>vŠJbxctyެpS[Ȁuy)Kvj{<]E=Xꇣo^ g%lەzMxvw<3s{Q/dP_0W3V5tur!sf=JnI7XۑC؜tuzW>umڽb>-D2Eo;\ T0Q֒%% "CBݏ=Ck'/,p~RRj,9e@ip%bTr;0(GS.TIOGJ*'ˌF`g-?(7zS0eQv;a u7WUOXA]}p1!Ş``U8NVie4Ԋ^JnfK=D\HĤ̷3ضhvr L'+7nM&TC'*+S '&E|Les3٨Y|*JX-U=^qfݲsִ!7ω^ ݴ5Sq [*VpJ?`H=I ~~196uw_-]cH;d!K֢.52MY}𬂎[Nt[x.f֒ vt؍['ICSC WB,T8ξI:흭S1]|bhݵ3\uqzku"[9E.Ač>4#RF;Hex?*AUDz"%OKz'&U6\ *|(eMKٸI)"x׉nb8K-a⭏E!+Gu)AC~4?>2IbkԢvu V}IڟGC7ҰwN- q[4s8{`&hOمpxFvDXfj3rl4GOlK2'"v-_3y; 2Og翁?&zwƹAT*zbY{@EFeC IA(ao v0y2ٜXcLDKN!>Q wudξR`&[> stream xmweT-]eAܝ A܂{~[箻?UwիJ'3])#`gBtRn@. tpp89iNޮ [7%ÿA qrpY<<<< "4@-` r$UUd*Y jPspY@@0vr8,Vq#@YZK\FUE -ɦ% 0[  u p`?^X+h#K7y?! h7Atrtvw`t w3T;57tq_Y8YٹAJ W{7Ww?.sRZYW'lvmߛikh0g [:Y6MښZwX4w+}co/ /;'twuV\^@Ke'K0*xfL?{ @öV7Zd3;7SKl6 4~6!rT喵8ŝwZR.%kV5pe06xC1bچ]Z>D^U;G6;86`z-9(0/e BlLdI(."P:39[幢Mr<Vnv!c v"SiZڀPZ]V8_ۡhg~زf'tpBS񰐲+۟@xVPGΒ3kNCL+ ԯ%ߩgmSZFHs8=w`歏_1<x9ӱN&񪑩js2Muִϴl5b.LNbĮ듇b<4^r8~A8KگAkYIY mdrgWqZ䒞#%ⳤHѼ;7\L MugCޞOGzqv˥xPK<+1`s=4r#?oC%3UbRr+K).`@GEJU[htA`j2(:uQ&΂>* q2<¶Ѫ٥{d\Fkܴ V'{EC NÅzDj1^ ݨFlaQd:nZW Cn\c#NN˺EA8?+JFëqy%LμQP!Jɜvwy*{~[,Q\g. |zuq O#W'=!lUNAG6*:-tmkSVMZ;h{Xrz ,,zj-?gb*O"4/[ yžUH}/ Fe?C >X h+4 o7(˳4wm`<%;lfN~m 6,BټҽC̚ЁI6?^@*P2;7Ϭj]gaAlu#D$=. k Q'}3IBg%XZf3-`m)Ohtd'N/Cl\MRեS"R|o.áj1#Up2,ᢁ^ORhtpGA!Q#鰃;ZYVd7yxÄ&nΥvMNBBo #odEN㮒nFOo 1_e~1!dͯ.pO[nC?"8RLM$ҵъoUjc\<{NAKL@ք_vB*7֐d ^`y=}!R8R?n|E#YG6P9k`r؇3t& ٖބK2׺3/ո%tRv |o?9m~;O_rԡeL){x}r5Ϻ7lteβ 7JjlS rE~1#ǧ [Rgvl9xY'Z:*VlD.GƼӎMC>cO`e56En1,Obr%U7K+\ş'.σHI9Kd4Hvo\P< Zn!݁^D] 4K׺ }=HYh 6R̽_D"ƕͯރsQ9~ڂYtai[7+}ƞd)H! THDLC["'χkуɵfumq 9)̈́D╀Ltu\jY ~a}g ?Giߒ `Ц9] ?, [FG5 "wO8t\sg7!V(<~dF/[3aS*3fjߍkSY,dȐᑔ̜WvY) tGl=3T)5%0}Sc5]Gbt~do1w@(rhh:l l/~ᓬ mb鑙V)fIw? ĀGx9\kꡓ])7v."77Su̎[jElCXl7ӳua{6(.2F'Ę} ݗ޻9!z?}tPz\!d_rwP) G^~2=L ƶ1-{?(ȁ.|tM~vOiKu)+rȖhR(QR' ɴ c_ۣ-W>9 ߸z]Sz'@G׌{&9B"h'uk'[4h#6sk2/_4 GU H1뒨r.+XiOj ܱ,yly(v'o얇j(O`w^=_O3FBQdI?+FxRGz7UVӐy3NUAת] gOsI];rfuJYsum-žOS_RRK1e8Z B]vE>#׳3H[{7 ]`WfpCQ!#ُӲ$Owt, ~qo!4TwkpZxf}9ٽyך]&9@ ~MuTRv~')*:=zJհG+ѓ)L)MI-5&zC7OUFK_.>%]$e='$ 5ϻ?1:42OȑOKҝ Ų:Hvr[=Xh*4\圻* byzEm%0HPP<+d~|@Q0#*bwQ/,o=B!![:EQ;k{x-th,B7Sa7焸CT?}G^8:$`5-ۮf\ 'ȫU\tSIoD,!%ZoN {'.4^4Ez*4+Q}L%}8J+U٦V6nJ$]/]PWF.^-cPlv{ϣjڴN >:(_=D7?yBJfe,>ڠ5ͪNNE|٣Hψ1C6>긂&Ɉ~G=$~_w iR?i6Jei=E;7 %FGǛRd,,dͪNE8׀ @ D6 "N>CT؟8 ib_7!-S"7ϓf:f yg;݋ /je'6D䉺hN=ۙ汾B]H]gMRmþF*?\m@WƕYhQNN;%h[G$sd}Wmi_'قuAllr8w% Y]2շlm LM7cPX*qdv=;$}oWC%r=CϞ!Z# >g9и:_e\Wjr3ԳJlEYK Im*!L1xzJ7f`35qX )S#XyH*Qb]%3=*'Y$"[s.])p=3Xhpouu9ESs)OJJ 'F#A(l0S%BwRSt0.N{̡|y,]qJNkC*Xm[EmB^%B͊h/cn-U{F,NЦr9 ċWSBH:oՆg1Z1ސ :XXV26)g/L/2A0Ewx2M#_F`80h^œ}{Va'IzҶn7g!=-{G3fꨰ?8rϭȍO9b&#9ݲݝ~yfN34*|()ƅq*zK\d>G40N;?#}Jr_Ntt`˝`yG}+!Ͼ׉ʄN ܍FbXTy 2@rZGr { 5*۴gIsf̫UV?} &:dSe1O.f.nճa!l%p.|D( }—zfLE^0SM ULiID -UcrX|BӋ ]Ylàg\<#yUnjGA5i= QV-NuΟB}Jխ97tliseAt}&\$zC&;  !R/zؠ_g3QWIa ' mU;J3>90Hf=@\~J o@b{qД;<)~b =f1b Q)x 7"?#(0xیOTO^Ayn:)#L`= 3+ySfG.U@,l oSOC:HBޢ݁aFrVp~L0ӽ|Fۙ+N;b٩Nx4O>DkOd,}${hg|0T/$d}YJ>Ƶt{ b&vXΤxxq,o~ThYgE{҄'8G$N8>@{w"Ŵ4"f| ͟NP*1 e_ܓAJՎbN^.2^}to3Ei -[)"}:H̘D.Z4Ihc[] ovi9:x-[ H\4 {FkDIa(3 ϟB3np9lh|\ᦪ}l}BO6A-Rc}z_V>hf E?j^שּׂeܾwMQ}{A䮉cDmS*bD`XbRݹʊ&/FKF3nS}R'$YlL;0Jafz]tL 2}]y;}=#"ĕ#e=?9oIFW$Ȯ/{\kO$d F4UlJYaDn\xVK< >RѪ(8ȫhrgb~ ӃE؛ Ŭ>^<.}!%MZRkyc0NLR)C]FƿZ[o8dCGXT^$lNqi7uEA;^=\?h>h|BZfIiP뽑'J#M&޸gճ,#QW.i~55۸wMI<Ž5Cҧ^R}{DxFL 7j;Lj1΍_2tɰ}Y]f!ٰQJ1.,A(Sj>ߡ_0+dxJ".T >ۅbW~,;wuz#0pFFvk!"+T V -˭PɏC=p>.8tR;y #|-E€03A0#%MdppxmB]‡^[bJ`%QY y 1<`0 H! z%NrgHNȱM} 'niSܘ-B[Dn%F1}P'eFk@2E|Qc6/q|c<]f",g¯,z ǵ;GdMK".>em;خpg1b.*rjL.x[.9Qojp`[X;}9$lA@:sXޱiRj[y mhnQ,3!ЕTՔI3Mԥ70Gx(ƛ6ܜ|2j9Rޖw1Tdt/mQZmOCz&",6Ÿ M0CXd[W5y@UBa"ebiGB 2@fESkYUtǒXw* F%PCA{O;uDcHR[0&CP0 ,_,6阧 ?!^UA2i0fYà~6Lj K5^hkÆ,}jIx,^oJ@^"CIۼ jC2>R59˒jV`sg'iǀ8Q b|Snؘ} ytƪ?苮 D\1vo‖tfd7R&`Up sT(:FbcO$j7yZVTku,KWxN!?M kWM~F B` 1atoF4Z&o;V+jb;')pNuPha!>u_T?@ĭ_ъD =߅yX %;O3NE <pU2xyBC]4E-` f)k6>NOb  %AY~${ܹw| Keu6 br w))!#8/(?-+=bkY2vn%R '@"ܜZv=3M_ҧT3aUhE:,vؤy\Q1]־(yꊕWbUF*s\ IpJT[GxJ\ )vYʮGU KFP,@H(Ƿpjv=⌷ޖV)lM_#(lcpCp#}ݐj=  P[ #N9z.mIm̜{fɁytB\Y%EF /<DŽ8? rVg {7'=2'H%϶-¿QWCuscE;Kd*⯈@Xtc, L#к׻_jDSX|ݚY2$.bk?PruY"FG&#;^UP#=,eCO'9-Rt<'$Ӻ5O?xl.5)"ǔOݑ #uͩ\Ԥ8CpɏdY[>-pA>[̥׻>/wM}R;E1C_yߠ#>KpM,Ma&ddD-":4 ٽ]dpN8S4]tNEHR:woH%Ǜ=di TG8:eN[RGb'%,onr>r=yn-duA>nrgWf"zG$x4${{OtϧVX KMc'k$w%'Po{E*04ƪ{NH<ݿcOm!&/l4 ӊ0&Oj2Ol+ `h]/ qO) ~oj_^_̺ = O6?m&&PϱlXl۵rH%KjM]NLAllS*{|LaebL1MGCeίyL2\Ni;w!R endstream endobj 674 0 obj << /Length1 737 /Length2 25615 /Length3 0 /Length 26188 /Filter /FlateDecode >> stream xlct&.cb;c۞8m۶m{b۶m;<]/_U]U]ݫW8*L\&"@'s[Q' 7@h PY,LL?"vfN*# jV5[+[s#333??N@ 01D5%T lhen578&0#[cl\N$f`k SWW0 l89rc 4rtWutRV KW33 `45/ܤlLl;Ꞔ@c?VV@ gk t {WI l\ ͭ?٘#=n@cEswrpGO9>tFdRQ%I߁Z[h`i03?^ qa?ugfгr0Y9L+]#gӿO-{@7яe[# r Hi}UefЕ-A3c+{Sc[ Z쀥dW2NYz^R3$ӌbZ~qi\1?܆VMŜ)W eC$Vawo馌- s9:g+N79#"͢"V!68cmAOOd)^o06TOG'a+q\RnCG C ZQ}4X'm'/\z1B8?8Q`a#S`v5O@4]?H$cQGD)<NkCL*l29Gx[(p%x$']URں˷u Ym9P$:C韃JNYdAb|oNJ0Q/%ȠRsWњH6#EBMgO_4uvT/WRkVGh/ !kj4<|O]V(oZ%၉ُP6QqOY0;vn#Tp f3*:eUr?"y6k {ig.6#nx5+7.KK ڦ3CNN~烜BgmQ̓K.Wj:ox0H`LC?OKg"~Ꜿаoid5 ^#d7 -] \<1rxV[xF)DHf'kɩ,şP^;I#iD%Dj)D m"pR]Pvx[t$nF&]ۏ|#s& gJIoՃ`epJQ\=Hw<֍ڻ!ܧ~Y}ff$2ചtn@+IC%L"TPnaLw6]M3XCUF.nݸ,0~ܴViœOWbi 1bsyRq ɐ5S'f--!>>Nd#I )62u7΍dƸ7Y ,(wJqEW tL: TRhzP#%*ow:s:Hg _U1feH44kvv7x~R \_s{!|<)H{m Fab1+ŘP„R%Vnj*NP4PZS\ "L4{ -GŘ $m B +o&2~_*M*2opOҥp|\Tj'@1xe\|<,6yB\6szg4#$w*᩠nS u9~?xi:m8s'G-tJ\51Amh@],Nz͐:)?ag!~a,=jh8K ϊ@tVf}a-\=PR 99pķG (Յ 0[.Ja L5w@!P0 ]JH4; 'Z{fpJ߃~@m1ڞ@ Y&{|D etPʎCqڼ(&agh"]pٹ?_rU{Nq::ƫ]b&g_Φ}Wp~=> \ jK'S=򀟠YQ/ 87rs1$YJ,NCMudǨCfXzotܚ{t8_^6Cʩ$,POc.~̒ ~ύ#krWQPe}Y~ 1lUJDa T % Fbc?_p.YIQ)le ( X1GOyN_ $:@)<̠9ϥҐL˿{̞;}(]K&HvIJ*9,F͚yo E]yd' Eib8ƙ|7ZD@(D--0zM n;!!(F7.R;Sv[ljjbG?]nHLƵҙU\#fנU/,_E 4z2`OI|Q济͆)+(op5LBޕc8ŭ*eY-w 4:٢{5)C$XXPf4İ\ mItT,d %:0L:# W4-cANO<:9ȴJ#ƀϋw;ש&N+uL3TMI?fFn*j8ن̵*!SIz+ݍbњ H= 2xG(aV2Jc݅g)#LPg󰒬cx+ $1U-<Eh^a[PɜC,lp q&Ed3#ɅyjP͑N9->'v40F22N>zJb5,l" 1^#Cy׭=dDش8/j8Hڢ܁X3Q3$!vDU3 FZJLj\ʄDkv~{d>6˘Lg|9AKh7sSw]<Cooyn '},Ȝ_ GE8Q'zlx'1,GJyGq&D_|>wZt1nr+]=nE,S_NkM&[VbI)&8XZBZi̒yyMߤ"5hs }vEz1%),'TL<@04?nH𰿗eVb;I,bv,kw(]Қ]": 2(y|/b{dHй3f9e fEQ@$ζ0 ~w+> 7UH.]ȷmv; Jy@h"Z@uZ#By-ա%Ӡ_ M?DݬRI H'|@I}Uzw|b0ε?- Ks%`ݡLd\>"iOZzI\ Ʈ,uxvO x;CЭLƲ5_ΠLЅ.$ TF筨Ec? E)?qTBű &O&/S0}Z wU>yKΗ `Ivڧh]jRQ.f֚=ov*|dչ;Doۡ\۫O*+E6s/zׅ8~M;K(o@o_.D穒b)x(C/% Ri5HW+r&ç]i- 7_#~i >}Bl"'lcaݴ"_VѠYKbԨɤx34ƾO+?Wv¡.(<4tf*d]!DLAfIDQ/.Knd"0UjIb.Fj{x.|WY$}Y~uLcG9DYqz-(C4:PW-"z[1kf;n[O$v kQďx4@y\#x\^ ^ ~Z1NuAUS`>Ap0$J[~P)-zX{V:_֟|)<>3=j{PVOwNDO@_o%ZooO* L _6LؔȲn=2);̘PtWIRˊܺ0N!S᱄iD1BRx@wϴ䦷Wd2[^I߶ڡ!! AD8y2i7RR 6œ r.\%C^suDg9_ǂT",ͯX=Pwbn.D?4Kql8-Ωp⑷>#(c-tg9,8DČQdyY,dh$C+5u4TQ6, E0gwT{%շgqExT{l&=X5~(`I(S Krg1Nzˆ5 {3w+n'F~g}" ")]:(3^B~aaZ/뾏4#Mf5 '!À\TYyQ˦̭.hK0e vz %]}y⩞A\ 5An ~yo_ݠųR r,g>{8L_lq>7k>c쯫xzm68ӓS?O>G/[%GxF?a ֱ |4%>P.Xþ>qٰ/,j̋٬Ip dq ըL+ ~Ii|#] NB恵IwoƤHve){pz!56Xjφ-yV5w> uDpm&|((urn\fH#sc~Z[+\"Rߤ~vd>kP&Yr\V .5W^+tL,UXaھҥzamc $~StksF-lm(KRŲ32y]VfrZEi+[Ft4ۧC34V7-u٠EVU?yfiV[y wc*p!:9csZA!=K&4F#p$~:&$/M<WsSU+W޼vQ&a[9=iUZfrCg-7?y#DzDk= 4Ũ+<9V0Vn"2f_3"tJP*~a7e>WUB֑ oI͚h.8E=C}.ɩ?YAPӖ*+w6~ebduhQQ@Z!g9vH~=,FݲY{/6GGF3%-$4fD8f׵d=r$XIӿF銏˧`/ʭFi(gSa7ͯÆ]E%pϵN+f|]W2M}29)XDvb[- sFLTYuqZP,]cP^R@{uLb)0_1&6zj)74HFl:w˗b) %wqʂܚt3Yג @[%eO[Zk:׼5qK]§ch8j@*O9e:EI]N('Ex4}syM Kl6j9I3h .x)NY#t WsR}6738NP4eg&DzF곬%"˔̺@d3J!3-_T\oSP/0w$Qŧz1~ S# J.Ϲ"X4Kz+!tT}^ O:!mr c+̏quD) gaQ},0 KS7;7KV NH753`ZϬ(+m8ZͶ>+X0erYy;.uThNC9v hy \y B!֤`0Rj6<ӥ'6Bn$Ldafqp1sa'tMy~zW4ݞA!,H7-i‰LdhD߯8fm 1&9hDeQ sWRX`w[җuOe#>0auבˎw؝FRR$e7Ѧ }B">g`0h\S]bJR ض g-%2qEo*RM>';l rb:K7q\ 7t0"Oi;Zh#S Ftܺh|Eg&M;^-9i4dc, _ \+BV;A^"$Oȃ ]ڶ xN2 pNppO>D} 2π1Snj*ﴷ)ޛBl`_Uz*wggI -L:4"*y(HӖ~4S*Z/ԡ M2j]5\"<\oH>r^/[CF^e|U2,c^N܎>ӱ1+z=ǽA0͢`ƯUk^8zs۾zt N?NK`o}۫5b+f:,AVY.D|݊eS?tw?CCKSlh޵ 8VY.3v~8<>h)^Ƕq5E8k@U>¯ZM5lǿ%1bw8¢c[l|% ,ѶUYx d"_BM4@lΨ .BOh,if@<&~1sN}GYO5 iex࿵T(Ue_qTHb@t͉.$*Zԩٹ-ZlEcˣ)`}5~)[G ej>f3L3-v)1bN'*B2b^ qe1CZUR;1Y?fA]Wt +=9~l!r1w>ق=kr5A_{!jr!LQ W݁ ,^]'bq[I-7mr wCCĊnwzVWey*Ψ.36yg\+?B T:?iZmð&>w_}=튔O#)AP~5AX0O3@G- 1ydP(m40%p*rѫk ٷ~]>*:#=U>~D js KILJ|K̚ߦJ}Z`3яdL%9oVĐJną], f#gxGN޸+-,)sliofG _#sMB(cџGg͉8#gU}gd +9z3ScF,ݴb&vxD_\qJE6[BC\"tc8,%kt o* j.e"ĩeQ(gSҜ0 PRs!84vwt5s[ JS܌7װBLUs9zG =1"mc3IrTzq?S ?.y$쟪#>ţ+M6"q҃g&ZpߛϳpjMq@x~nl=q\^i=kfY̊ˮSnK5AArqw Os-.MͫYT;TKviXA]/Iny8"\'~̖m>>LvR\֌D (Ӎiim~yR3=ad"+61<8J(E샻Kp<ZIhաs[өUϝFH;'/0GhM;NsA@}|B{GjWHLfFT\E vGjaD ,`.3'@Um+U⶷-E-zi'wZXUWAsLo)ujuJtT͘mW5_}qpUVH|.J_Ii Rw{ 9lld#2ᚩd\k8eWXb'ng\LCX>d"lg,b)hFR9M_+@mLXa"WuLU?wݢ@;H_S%JZkne6 CFU' Q(_=f 0ƫt4KJ}hn=/ڇk6p݀Ƌb N y AUgB6w?[eF9RO]]AZ.'x, ! &smrKby1ii5Zx=G#j=7VJ^y}ﯭSE&rBA/"UkpԖaK[>D "v7wFgU},v`H4 •Xpv~+]sN0Tج`QL[W.t$PFCM t6z&vx-#suJ6M'#m[t2%OߒZw,xs^}~}Q\vYaZ$#hmu֝Oo"E- }Ii퐪_V4rjI$ڶR(]i428a9} $Xe~?צ~mOIE(ݷ, wW2 9#g;3CZV i8G5q`_ 9#,L~jg,K \QY[8zTTHF'{蝚\rK|`aTm -tyz>}⑉OEt-WKih?Ⱦ'S@ܶ.XVd\[61"&_}Gїx~e׹qPa_ĖT^YT'@"|g.`O-rָGkT)@)(\bxC'DH gPf` iÌ%ti~(ܢMz  \4uP@ߡ#VaX`fc썩f|V <> BG_Ҟtj+?ͫR>8HY`6 JWd힆HkX_~FiqZ:!7s{1&D?AV|q}[d4Z3ji=1A߫Gaz#6]Z%;>Sz5זGj"W 0 1D9vFڝ0X ~a3/}}OɵRk"_f l)> [(̸FXbVzˉAU)sE+WE H'ٟy&KܑqY?l|%x:q l?"vA[f8|FysS6jQ)pzl42ƖHYulhGDH9 Q !)ؔHa*q0wrm΂+kdo&jù;cD{)~A{}#D![$Bm\CvR?F||HYqggnLAӘ&=1ӘKɳlG 0ɝX3XpS9P#<y9KKs몽qNթRә'#7VK`G7\ D]:j1!wD.:9w櫮x'yDk,ԊeQ/-'\o󪅖0,۟7ct]qXARD#?TאʂQLUڷvE^aJKBQ ~v4%sD7Plڲ SQe-M0,n|TW<ҽ$TLО5 $&58'M-k%ܪ /.Ll ~&e 2: ޾$k7TiȭWUSN"Z2cːJl+{k;"JG&OMܞiOM:ghQ.v90H&ֹ+jʄEءg~~ԚRvSWgǥM-mj^up JKڶ:]X%L^8X$B0"U_OekdAlvGlwP3\qj37,#}y*F=ݬ?}Tg+3oENLV/ީ K% ?Z]&&%sС0y7 %@KY")[tDޜ_g:L}1+@hʞ $`56)F&CH!2PӤCe:+߭.mAȒJ—pQ &2AŪE o\pXjμ^vMj|O%vR'<̂p9|^WM'/Is=+ғRܧ3fݯ'KC${mM"/O.ZIBS($͘Fp@:" d)]]ϭ !5I"᛻h\{-q(v\"5=^Kbr%Y쫧ِ ?U>BPG0ҾU4` Naj$4TXYFyi]v+`XzSE3 c$s&dL:.{MQ | 7w/IiMG\/H<4D;ٌ|,VRpS =5PK)[b<=Ts {tAnc»njtp↧dۦh󭤙GetCDP%|stTE8DŹ}4t ,-Qjf/6Xi˳wɻj ^{T'#< ,C{#NŠam`Y0o bF̆*);!=C8qgs-dQ|G@;)&iy gP/S%iGind.H  EI֧<\OhӒhMnzO cゕ$hz\;ΌZ~d槛Ҍt!MdOp֑<&TV5\we,F3'H51ߒ)ҵE s7^t!/P>滵 $v qe$咈qQ 2\w"o,6Vv-gmڜ5S&3ڧC_ؘVhO1tZꊄ=RL(ې8(? 79$3釦]9#tog]gL_.7tA+Ҏ׹+7ʪEX_^0Aq((! <ѫ\9T,hj18N84Sk" v[1P~3:y@a0s^bݣҬ՗26b&bz_Y2 Lw_wB gL57'>{ϗ퀔,t(ZZz{i89kbIƗZ3a>vjGs㰆P7L* W3OZ,^gk=^7T6#\,&Y0(TVخU`lwd?T L{4U40NGzƅN-kTr1Px=+L[`R~okS}BnTnPi]&͉pisRVa44kDSxdzx jG"\ FR*͛{wrE2SvUx \-|88qV?JhPI\r }%k`̍YkEjLOrf\l>>73!pFn7}*2`{}g$̈́n!ayZyNI|0p%伟~mMWfJ7#YvL]-Q38yW͒KTbyf_gdӭ8*C6:0-UEG`(tZ6NsM L6  ؈Tp Wث p#)2dEnD %\kCL^jY`_L573_b(ݽ PQ&LjHl}꠴g% BMhL^kiͧ29YSV맯ߌm7f( vݨRE7ԗ6sk~U Xp(X62S R>ݶڴʴ0j͢ۼykƴdk|Uc֤Artl2 Ǝ-( Ub?`|e!)f>{}_ +x}Ul:31 ~Fr*Zl30e[ԇ3>@,u D]]]1Z{ʯ1w ")sD8TʏQS xfbJ*Q<7޲]a7;2gLcH74M˖SQv]Z Tƴl`0I VD!jGA fu9W0譡Kr*orr/qd=P_Bb\ls' >ϘJy!0 +i=SDB&yJkpB*36@]~@/, X-8 4#+:t1ҸGޚpn5.x湏{r6λCmդq"K '.hUy 3/И(s1H])Du M:xa$SAG/Ի!G:TA:?EG'6>쥲Ƭ+1`g|B_!ŝI>n AFx=܍0qIvKq*p_Qdqt܆vNIթ1!xfq 5`+eT8?@c,d43ތrpѦGgXI鬂5s>/Ӯ*pi.bj揪3l?3DTk,:LKĚb^a7q]|O4`7_Fh;M%=YV"wˤ2V0mCO"}BzK>wQz5$է0k\l1X%!#c@|D]666h{giPō\gf/4?&^|y JX)j58 ^goRyN Ipʺ_ {^Q߯C?4_cASW*^/(t]j ݝuHHA;$[m\r/8 ,4َlu5 z.L>)P Լv'l1F(0?l163U" nVn;|h5X |2XM>fҧ2@z9 c$Y<粣Q\ū"(+} + gd)ioB!eG8:.LP "Xud6see47uOE0ewW ^ ?oN%|˨ XY#rGfŤF`tx=+>DD94C K>_Y˂I^5 tVX߱8ug0]8JSL`oSU_2{ ۆ?XIRlI<)a߱b>YqxlST r,.jrE:.{(kسzYr2yf𸲯E~bےGm'}|mѵ4Eu _ݞ]/ȴE/4F`OEbSְ6n? 4w EHep+́5 EIK=?zY2TbP9w8AҲHHdd# 7|?;;%33fZoIStaTifu?W'}[N1CZQr84j&3 ~;JF v@5Bb{Zՙo!-r?C33ߋrrN'1$D'-34~쯘aF1si#:QNZ?;68慻+!u|֟o@| n΋ӺXԨ)a{Ię;Nה &J# iR&PTHd2_iO>IpOJ3f:kr|0 ZN*IxsF9(YQ991@k.Vlx褊1 )wuSgF^p"ҟ{_? <"v{Ѫ5j A%H;\p+|Tm'P̱y7rSf`JYFvhqvyWT)1^՝Dвq4MoFnп\1T")k`f6PPݬR`  ?%q1'*!9WFQ$E98%j~Ra>|ڀIVH,BL6 5 媌m!qh6]C[|5!žt֗m(|BɶfkHf=4B38LS wɚNgtQy׊Htg:`>G>"]ۘ=]{>s'%0ٔ94&BQts*}΀ǘ;K"53=X#^iH¶i'ĕC¾@yX;> \o~)|b3rq+jX~*S/tHy<, &`LYt-ψNͮ}-ࢅ7LйX4ZZH ne]N*!k9#AWD.ϞҢts >GgjL4VPW⺫W U(,d 6<16C70A>Lkd:{R6Q_u BSདྷ-K;,Inpջ&=Vm>huۖ0\)60 &vPοB}{eJg&uȣVhDPCT VŸp{Za|QÓV&od7ND ل4*/g&CG;N<(1&RS0@ɢ\~s6onw`Q P.ꧯ4oiVn12M︋{l| |2'by/hSlO + ^Pa>[JIE\X˷ D&QJ19nea6 'sllu>Υ1P79S=ѧž&0".,VaF`N3Hn5_1C\4zD }]  +ܫFqcD{~\+{FK kdFun[SZ(=-ŖSn9dq&s5XaUө&q|sdH,Üq"l|ȘÔ&6&2p 3)U+wU7FI\sZYh ɮ!ZqT[/=e<f_vW\!B R(DN] M8MOAm[>3gʞ% N(VL-L]@Gb[Zw|eh3[rm|a}Dlyn<aHp fqv+mӭ> ,XycuSrɆ (:̅QZ GvF-yJD <)9?GCq:")QuA_z0YHNu ӏ{c6e.F@;wVBKҁDTWoioi|[7Dm{d?oܴ} b7Ֆ߻#^f],DO;Ы@EڰvhD+{Vckr&\} w7DJcl'jS+il+XNJOBӐ{i>mQ) 񨯴t`59<9K͎–r`31Ggh,>r(/nYFwaMx;"j'/< ϖRauXN*i #_Uu*:E`fn""_?腡X1@"H^/Bʑ\iahřyͱ6I[P v֋eu =6mDoc|LDU'\=MYl5R iN"VMT!Uf:;=dNPAﺺ[՜ ujyܔ(]-zRᙛ{zO Dk cx MGI;ښvaφ\'1P-V^M eahm U!tƽ>/Wy9AUsG^DJUI1"s쒩17bN,RU^]$Rc/B+| #A {۱ND[+kt6RȫYZI.q&M=[Z9$}R&{K}ɉw2[,Ԙb dTl[gCYfd ĈYTX]4| uMΜMNm;|'z0%@3K}vBgZii 8 n' 8n F (eL~זj[]%_ƙ) 1g;[Rd +%HٸF$9%v>/ɟW#]: ِڴȚ:F BDijÜcs 8i 12{~q[%WD$#-vnFvrX˴J 9l5I1޷יܨ6HtR1- p[,t2rdd2' y< №q>c䐥DE0FҘ`QgwWZZ#cX2GME&oδ mZ RB"jvz3ݰX &Tl%%p=(PsWcqMt!o mE X|ԍd՝+:D`pN0an 5dX?}[+4LfR-&^^ "3hDM(=qxj[C6G|@x3}r> g=P{ c?.ZK]L 3kqٝBnx %\;( ɇɼ+qo?e).H$j&1U?NϞx #_a?0z$zQK;p + 2$)3?3N1)kR('r/NS/Q xKm1@b2C=[܈t˜5 3B!v۳DZN}re]iRU_yO32!"Sr  vrj}eE!s=*ϳ[~fA2; '_ ^(yW-Xs@)[v KU./΄iLwlnp tKiZd"U 1Wr.P8%$7pd IuZW#ԻZH8YQv׆*a'M\JoH2mB=v!wæA*'Uň_W"%P?"=IgN[nR2t@%8ՠ0MJvfzm"iznڃ70\o%/~)&F 1ڤm7yTΝݮF{Y4['7˯+4C}='6UI7,dE2Sfek{>OņrKAI]D8:q&蒽oNFwGejb8wId-3SMRکD`]a3s]u1)ԫɏ3> tUJ |W]2Sw(0 *p^E .j}6i+V`QJ]EҍY3!2WPo~NυO%y }!|%uTG^d4稫$tBt[u*EPCfq.+ ͵;X`w\V'̒&o)Jdgל5Dp.HO2%l~7 #\+n FyBǧ˻׫$^K S%̳tfWmz)W9˂^S&, m'Nt"6hLMТa v_ 5}e. }!MT|$YhV>aPPUf7y/jmψH Kԩ#`IL ;z.6 !5i)~lPaf+nxM& T*t?-5$+V` [(}Wi|d`##лz\ 3ɻ{4 g\C͊O$iU8U*3j@H@[Y/`?8PɺRAsn /!ƛ OyQ@vKҖ!0U_,CM@#Rjt5r#,T]k[WѶ.A )'jivM#(7fQd߀`͟޵#M(!!OS`{Ε> u8{x4p$w[\hZ3o ϣscl/ bg 1]T٩mfY x8;ԝcX SeiXnmgcwGe=!J45 s-K_>q+)QR~;S^n..{F|#, endstream endobj 676 0 obj << /Length1 725 /Length2 39881 /Length3 0 /Length 40349 /Filter /FlateDecode >> stream xlsp.v~ض۶ضm۶mW?ꮹfȈlUt4egÕ|4" lnUۜ}buȉScA=wοw]/`˳VwFJJe \`gv/7n5if5\v-a-"( rY e͑ {eq3xk _'3Egb- ;$=5>RI@$ПZۧu8j/|Il}h)މf%`-0.<)*a{ 4-86_V* S3]3{+'!<bT t_ ~0#M} 3Q'ot9bl73K׹ X˷+h9~4Q[O 2" DGgh.c3OO7V=*_Ƞay$6}qs@mv0 vQsm6eu?|ב2[5,8N | &k2O4W 2]\\ Ƕ ~9~^r (] a\H] 8$8UeShwavNEvQ l #iV91py+ڇܿaUQ=&/z2SZd,|cZVl:펡]efmd3sՑ}g(AmḷaZbImRWӮ["z (jkì-5*| wO?* lÁb==f& w; *>6ÙSt vӉjSCmҌjH;0yaФx1;QRɶ 4G<7gol{NBNy6Wh@wb_3dcXWuAҪ\+n/|BklwI$K?O>q@t߯iC.ZP]n3XVC+\s e7fHs1"(fm x&˂Z Fj>?mӺSZr#DѺoE9a"`E`[=un&/HyFOzuܖ7XPmNβaP-?_ϛie*^ﱚUx1E^7@9W\7"#dWa6 $P7JP=$a [-=ϾFJ>ˌ^P޶g*ANDž<<MOaiYt=xx!J;Jԃ$IRŃVVqH1[7~%7tyjs#&}&Ẏ9h a~yN.J+S MR{]@y8{Ϋۍ$!Ixe?apZfА|H+V]Ė= Y,U:8@( i MxtW辕]}z C $Sfݬa#,G 5MX,&i2hruIo:}JZ+; !{p$_s-fmmlSD9s4R(}'.Őz.e{V vP:*wrB3Af~IB GG/ %@x("1::l.!ʑ ,"# p1 /WBe,_l_A %q% ը?PI's($pcPg~ԊwzO?%3r|%TݺˮRv8xDݶe4<-! N?o]!38Hڦܖ)O Pazp~R^jJe2=Ic? 2 ?Cג&y-4BQA0V(жɔ=p;sڲoI2bfR{:0mS4fɅAWNv¸BS RJ-j]9ewL)HvH~ےGBbLjlTy2Vh:nށJyWb6B>!GZX( `ur ` VeeQGxJUn!d .*~\A,,Yj>FGOqtcĉ9{V&9GJt"f;&UL7 fk[z(ʨ7ʵ_c:9ECENY7 Tsvf?T2Gz:,ɝmKˍTdo Q\LAz)r5}rciIsG1^5rOC)of{`M$C;7.1ݞBZcMcދJѼ#@d"ylx0=8: (ADksX%X^T(T5BBž"X쑭FK=ᑂbVq0­fp:u3HPcI-ȗ7Xb԰pf}h.*Leqgw*2e'ќZNwJ7o|q$oQר^*15dI.ԠwV"Q9XOڏzEP3t6Ǝ۽լ<e^kwKmlIjso$OuCEiܺ$2iL$!;[O_۪ oiY/: З4^AcHi*l6^zj6)7BU+MYV8_!9YSe!%o>ݔޙxK\O 駗y]靀1lGPK TZƢU ϶u/<) ۼDt 23]j5YF֧DKJ7RU*hB5/ E<nH79ux]c+h-R*Edel)sR: 6/Dii,陫-{qծ xb_;¨CmYQ[}h} gե+_m4I%CE30sBM`Ğ .4l FtU6nBzDݲxjw{Kp.|gho&7вlR$/mP@>4lh^Xʘ:jF!,%DTR3AWHGܕ,,L RvȗC.UAo. ŧvpiՎ=?TT?Εsg>R= 5q 0a۫Rn 8YӜU8l&-+!mIkE٫4z?o'sGb:}2c\u][ 6=Q]Z@(4/d:_3gr9`DM1)dN6_Җ-t3%•2^d˽lFEI "QJ2 [=)xղ%J P!=/t:[に x7M,O x ԹE fAlgJ M u3#_!80x%7?CV/jg6rқZ\o<'#$S78ͽ,"Ju5m!y߭#qL CmVqJz.aw&.s7Of="uO,3a緃vbbuљw-G#QϳPNre,O-l@;J(VG.O6ȑ g9w(/"ڒ@aqإ‰shnHYM:+ Vqf{0 O%bC4[srnsu$46"K\ tG+bSZ&#iؠVf8[%G;hMDS; m3"n M%Zi6}ܭH Lw7d(ض5i9PlN7b><ߛ6•YC6Y+ed+`$ 9tVUTK8!^6sCB1;]u="X{}T{lgt'{Eԑ #u+Pԩ53_x:՚iPyFd%1\4{ ĤۥQ\ .`-g?,,sUoXvY CC9B@&bڂ$9xK)UYb< cDNE9`67$ǐ<U+{~d> @3Po= q ,x!l-ejL∘ab>ds,\g T<7slaհ|kk,D>W#/؁0\+)3ZN%Gc_NtU DiC}Ck& b# 1 6!O'PZPox>8xUm6gi51*H@JV/CmAKZ,B?)Z\B^-v5`BJ! aD=:8\~@ dw 6/_W7Z 7 ?~_ 5=[ kp1kFy섆:Lv,bTR"v[ |)3 ;,y! r`Qڵ~H7+±`:΅l< +|e\1ZC}HH Dq5*A ܍['%ʅ*N#o2>Lѧs o 6l.T4=\Z_iOX0rQ/5ҿ-<CR$HLxEj;z6ywarkELmvT=JisvP* 8 -PR2Gt#xywt:[*|*AO|{M8T/%LJU܆m'n^D5aÇTh x>tj@5yZ~W_?*Sz}0TnO| yQ#V KMw 5:y4,u~O\mj,I}IR̹q/m3o*eB0}]6f*1}W2~Fk 0+cTT˗L:o`Od&=R GA^zղ=9smP/xDՀvxq~XQl(QԹԫM^O Tr6Vec%Ko~($^ *w"pVv+cpYZ6qr'7Vt<^a3&'*7FI^Uk\+%k_ō, uyȪaN?֟jCpOB0s!֟#QIqٚwnU,}vjdRi;2LGhr) ċmޒr^x$}ol=3Idx,,Pw~;lM̏evw*}`o8.!GNtTVZOtiKΜG\P);060~n|ٗkauY>V%uN,P*S-RmOi{0\z# rftP@?'Gu˛0\Oi+t#AfkB_tz1܃i_T/dO5>ԥM5/[taKpNF#ןtDbA$dVփq]qFј:FQWIHDAka8$pѭIQ&"4'NI#{|FG\W9WZXWa(Vm@[W|L=Lg[$:?[tu!-IԾZDo1*㑣%ő/SID)6HbT`{6?(J?W+CCl\Rwcַ1KW7B=WA+sDCm}Kqr^?落m|`O0FX| 4aǫp[3ɦ:9bH/#{9D(p%"oD![} zK~jϒCJ $''~m(-TD#INy^ 9( в{ +A {HnTqjn@Ƌʓc9ӈ'_/s6mI@yooF"NJv(cbQ3d)I2d'q8iWC8= MV[H#V]=[Riu8!SQ 䘅՝EՆZ@#H|q۞T{!,^F@TB6:aP1'IMX,\9vS7}|BჺÿZ\p؅ȏEec׳ym4H2WvFM }۽; >!E!P ]˿? =-ke%!UD eF_~E'E 4na<$ِ,ť7 ^Eȝ_s|7ӡkۋI( spW(*w 9,{}36jUuZ7%ULQbK@sKqkݴ_[KdfONؠIl6@E {҉),vPRSLbf&2^^<񈮜6 zuƋ2FQ zBB%͜'=W#~R:pVRʖٰEx`7n,۲iVHu֓n4, #P/\f?K);Β["CtV rxy ƒaΑN=~ (>cZo"6 ;cySB`ʈ4YQ=A;ҹPߩPKΝӎ snJNā#(z9 LAg"<}5U).!No7JJɡ7 PKfqk}x: -]&G*lO1(qrIKmg`ɀ1h0 + /r܏2|TShNf.%dJwN޴_ENJd!jtmYβup" IqI(^Lv7V%%qH'βjBQiiǨBXELyIrzkSe"1{v$h|/=@,FA5f'!Z 8[Vzm_E~CSޘoXvKI^u7tߌI(tZe\e%4V73#D}c.Ku<%pn?ʼĀͪuT`l&Qa#TϜ!Ԗr Ǎf{N4 `N(?k2u) ,o>x"PMnRN*sgƤ&t.!ZU7NMCr^]a&\EJ(EVZұ%(U"Іghlf uTWW\߳Žd-tc.Iɿ4irGI>k2uR㷼5W.f5K"Z.V3SqP;SEjHMQ~KWڠ#Ϋ%Y]1d- 0quʥ, ~X4&J VEhkBVgOoP*_lh#`S #h"G_!v̆:N,F>Yſ:ڡ0~Eõ-1)]r]Lg 2<Phe rNU8I$^#$;fdkm?~`JBشdsK+,z" }3{) $ bWud9 |'}΅^<XS)Φ),7bbLsHu"<ދ·5vjJ)ogJ8LNgi _A<£]wހ.-J 3 j(`+U C.mp9DX)wu+:m HOtO4_P40 ^hߝJjMj㥿]xDPCs^nE]t0u%V$XuW"Q^quQbo݌.UĜ.:,Od ڏ+"\-#0&Ttb4ъF#FM.Po>?x=LZH,~8)QwM֙2)%+ =F6/9tz(ĴQG$), HP҄;Q iH7GЇTe"@b\x(qt){"0L.Vh/ "3Vˏ^uMۍF׎)ģH-E9RJ\pT>xxk q׎V]#ANCŀc!籎OF . MuA=y'S 8jetoS֔ACrjJ?C `"$1 <ppc&TZ^k/Xz 1TGܳvE?]|^rfj%评`f|0\S g1J{fV`ʔUrYFÑ'yj*TDPǼZ=/)c L:,:Ϗo<1SZn}tt#Kt (+3&*^w|HϯC  #cYsܶ!kYom!LmGBqe*ہjٗ 5` mw/}QJwR+.ig񛂃!l87^X9'I¨k<ǔVKB=C.ۜ zUg" !Ֆ~:$ГO+թǀ7!g^dk}:MQd)l^bck^Ɩ\dʍEGZ^LH:B׊ ӳ 5BVh_i"FF=\[$`﷫>8CkDhXSyRݷt\9nvWa ׁvD5ٞ}H.Pgwsr|LE}*|(60/~uWjK ݋3(툽sANOk%ۖ73el}9pwԣv[~g~@iھl}%zJ"kG' $ q'nkpqUN@3}a 4pgJ"0F^Kp)u3/ַvk01΅r/H|hN,ÔR5!@)d[*Bq+ŝ*#*$agX{ aiya~v| Om\ࠕRw&>A`|Jb ]{UHk[Sj> '0,;t}Ƈ9Sg%B6J-Z.A+N26qQ.S`ewy6Pp@w%E=94)eæbsi/Qi0zXホ}~Gc8V>ȹ T |e9A S3?7jť^ 繤ZwM`8J2=tU^k8rpa$؎W<%=~ V1OW {>)I3YX;]9Ozq> UpejD;O/b8XTzgJnQ.kVAaZj% &S^_jQF+z;1B,QaZp=b j l۪YxDgHYu/]' SOXK_EK,j7k"X vk`=Q褪cꨍb ,.FNV˟o/yaI77y1>M,(]ƍr>>G4A)C8i ]د~BZ(j@d(n+\1)b#,> P0'ĝ1x:7Η^/7\Fuc%A1JәYY7Iyasd vuInvn:--s/7Q=l#SuQ`5> dk2.Ѵ@HQ q ͐.g\{)yqަ_XD۽ˢT;ԏWNOz` K{}2zhՉlSP5qH/(OJK] t%reQz} #Pтi?q ,8ZMhzJqX` 6S$ti3+I ӸqB/LG.t NTf"GѐP~g,5{ɋQŴocp_03eW0Uh:dR,wqynɽ2:](H#o},8oo#h6iL5n&ם_ϨQxvziފqgZ/xl&$H@MmӃ٠٤o4Pڿi4| RRabP7V{os)ة ;'ֲo9nng-Y[ xgï_Ui'&_RbޱlT#;EFTQfaLAh&}Ƙ6-Unqh}9DyHo!XbF#xt^iԏӕ O0"O*Z;d!=OtҾ߄$8ŏ:\nI[ AFPj %'yQE==|E_cuhȩH.8,@rJt33FN3Kg=yh?ENiF->ø}tpBu7jOj JYmϙ^AM~yʨf6e?КP<&ws3zY$Z {#C~Du$ͱX;ZxƽH>Uan&'<aMC\p u^^ VM/G8,b!M5㈟U?Xit7 ԓ{Zd?ω>#ݘ~x^?qXX2^z/P%qHkŜBfE>ԑZQ+_RfŽ٩"DJs"BKYxz',YkI;_Œx n6J4FMS<]e>5@@xy䡡\e G y,×}zZȿ*0aɱ5h ڞ\UJsk2P&p7Mmw-:rt=c&PcM;Y2WnPAJ*P'q@x/о$+° -K /a}aՓ.\0q J*?-vub<[eqMP+ld||bb,7T:OZk",fu72l@e>ő1@v٠rne{ ;{ۊ'NyJTBqVRi+KB&/ؘfG֜B6l^|mQV-)8qȸmXvc9&i_ N;, tv̿1nMAmi9W~B(u:*T;Oqj|OI-[*wkV()0S o)&ȜD\ ozTɚK &sY-ԕ]|11g{\dc4x*隋K"[+F6<ZCkH7]Ӈ_`:W/k#`c^, ,.۶m6e۶m۶m۶m:32JzaZǛT6"@~wv)b9,cRcf;L'P>nRpw;hJNbr,մ%-4T,Jj)P%x˕<#lYf"z*>%$6o+LƎߑuEpǓ~ sqAw<.f2.L`˗Qu6S?G@!AATm #= m_6k'}a2oSؾWrqUelQ09n\쫑]EM-`05߲JX)?Ueg_P* |Cwu{W qs ~W"-Tleݜ,T#De[oINm א/>bs 8[qO@_?i& xoJ%[_?*NQ4P_`Q#n"&? tlmo*'q.D> j'tw8:[`U|t/]3/^}y7j".FAAPN#|&GZ OڠL学ADhPbb >(e0FfΗ|p>͚HN tšJU,Q/֕ $A!SONReno*KutpèW#O{pba9 : q7_v]J\!> G_o1eþ<ȤJm<(([FFȩG+kXzԭDL]BTFVCH:M:5,HL0I$;O|e;a۸O %+PH&w-6waԽ/6(}7P ۙ4v:{p_}Vv[ m'H[:' L?PF~Qm"M1VL ~R GH^^`! 0ո| *jc9c(bl|uM~:^JOѳ9,A)eے >$-gs-$kThPix6Mj|M"gbN퇜ƭ/Ȑu 2T0enN߽Nn%,M\I|7gڔg Izv6FZTH@2q`SQuoYAM {$YPI#xqj,(31QyE{pEU_ CҞ]eTc--DeTμ .uGמ'ra='`'X HXot˸ړ (>F6 ?=]1ehƭ<36Lx3Lg;^>/83U(W$ zp1?6__،|l_l"3eɁuPzn|( ucBh s`|1UZ- {IL"n.&<4BVZ@GpahUa+f \«urYSeML-F^JĢ ϪlڟBDPxR֜t얋'h:X^izsY-!m#[8޵ZF֢M zM|]3nvڙ 1t8'W9t?XG882i99 {#o+Xn3_DD;VN]L*EsBJx_){4̙Ƣ"<90q'qִ~tg7g ͚hIָ-/XKج |i٠jH m[W:8NϛOKm f856/&F*)zsy0(?c5@5=E3IۼrVtJu8&ᚯ ++#B(:lLF (E*&Oq3[ҧOg,kbLԇI`mggpwޯR*P3 bGi<_-/:UPFeaҹf4tt;Iɚmc 2V&3FǍ6kRt3i0 ໙$?\c_.%_I"_asWzs25uqR,'27 @w[E9,d٬QKsؐpBo.tăh^>2ݾ5Jԑ h.\q5Wq+.[R]PQ%ˎ 3ѓgv!a]gr6p~?w3QjA_ɌIa` g2/U5vz}"5d|:bkHyU1lu Z6N9*$bֿ Q&P̹Aχ`X`R#Z[Of'd-GT?SX2hs?mۡa0>Cˇ:@dɼxƙjC8~58I(iJ"-Do~\&aǼ~ Q_2 jIeJzyO9~w)^47gfAMa(&e!=nCt)-A-–B)9֞7~|7QyBŖX+9 !%[b@9}.6={ +V<=0^lц{gD<񓉷oDva$xNBNVfgu6WVO3q8 $~:p<վ Ž4CQn"uU21]JVFg)'Cc|9ԋ./Lø{΍wќ3Vi"^t:LwFϣ/(yCEp"LK*A27| QˢD~]…ic4(m/XjҍF0P.Iתr L(2{(XlDo9vO<'317B N6Y} 7)в߰Ϋ\EQSLSl>_Xf}+Ӹ 3reɦB"lmK/O]{c'_>* ( "۠m ߎ/?s-;?ͅ`PLkJj?՗X̍OV \`xgߞ![EezvD9P_jeڝ>T].;G0hNAmv\;{ }3$m-3>m9YM?`^n=ޱ_]CX&O" eݴCI0Fjʹ· oDZ}_h+:؏::5!="}c E&q;/?(㻩DVLLu+zn;/IPIJsOI0lo}dVH}yo@aB;s}}ioD\HΕٙxv IhJ(iɁY܌ 1PckHS T}Sr?O hp!%Ɇn팏A+%S)~KrMYYYjr}F֭vKL|uUkPvhY 16૞c?}|dFzȽxFYi? ]JF'֬t+k!Qo $f٣zlL"Pqr9.^WTR! du)A/UJSCDd"Hl#bo!?+Sq!,'qyN}TL]ЈexF dqfũSE0$SF8;p^nؗm@'l@Zͪ)gX9T} qMiKRc%wcQ:^s76 WDP֯r=oXͶw_Ǽ_];G~4>nDٓ'O-ʥXԋo:4}GܩF9$8 |*э@O:rN5#b{<8x*18Cg">Ԁ[AqہIn{P/ІNJA[C'[YYT;ɒXu@Q[0Vt7 A{q mNєX^3.Ly5{i#垖 j.B}=p#H~YEu&p\͗A-xkXC$e!9[(_r o)=0r .bwF|ҒjhX\1f@gmFTj[EQR9bAO-,iͼx@`Yt(XfDmUAFN1t|E3NP"*l92aktѹjHeyKٻwso0F,bSq>tfI+!ۊ#g#byt/33oXDkvr%gwqɫ< lѱnfX( :+P7FJ /ʬ wM *9LERO [ f'C3d)|U )q9&"?]SxNkNVݛ.p/NF-s[!˜3H9ڻ,O-Ty06vR AnDLJ-!39U_ŋQb'ے9pʤ.(PVܮB{ִ}KK:@6oesZmޜ1:=Lс,g:ɵX Ԏ]T~"60N (^ah;CJC tlV~Y(VO7ru6ilq:ãJծxJ\6V!(jA7нS1ά~)@L!>DZa)_c/1NM#"*IVxCQk1 h M>rD&c,=^kCK f|(^Y/4wRL$lW.= *Y폊:0EG-{h6e;wC}"?Yؾt8 O1wo1,!X|C>AE(wbEdzn%/n[ J}|&c㚥0UA +mTkɦmb')T!enn.P]w6Jr.O s\(ƫ읞0QJiBdɞs<{˸M[fmʨָZ"n"@Ig'.OI嶐18*f~щ|lhc _5C $a|~ zQ7/9S'v{Wܛ,0f]rK >b"xG?!$Qۭa\b_R!J!앏SL-ij}*}AM0o\C$Ś GkQzKO-7|r}4,·oͷw(̮,yǝgࢌtCHp6˜vղ9ьOjٰ H/:]]{@l=aqVo9=fsu]gZEdBY{L qm!?X(8x˄yۨ`.I GlثxU0Dm:(_ (܂BLV/ S R8~~*2Ȥ_+2W) / @[feWRY)D 6\^3LW*"Փ-q'Ɔ^Jc/Ի{rR0 NLzcvia^>USB tͺf\ѡyqN~Ҭ+mdt'ݑq<&s:/w;; 1"{v:sK #Ϣji1StvL&0bcN纜hu^s=;f_;b̓LY^o#Ů@r 5[k•O!}n+_/tZ/BI8,h#i/ONܷΎzKP/?*>d>z}6=1q `kmAhyHڤ-|/s^L/+6\.ID<Y4< .A@T VEPJ: kwΖP'*?015"A9Tm5}>@cCgbi;EHwC>lsI~͏*|=0PPIĮ 4 Ȃ\n8 I5^i :ٵ5}3ʀdsjAcc&^sk\$9 Ϡ 7L]݅܄1}ƾxU|ưaHDkBe>.;DEi\.aY"8(RT$jx!% e 5ۢ_e&U[GXR&\׭/(%p^L|dKPT^].pX`sVLaDޫ|^E6&SrXKfYEc= ӓK ;6c$r-7;)2sR1r#%#GнPV [ I&E+i6%1\Tc 5xQ.Kx*;k 5twO6Ԃ ,Sx?/۰{kP*5n`2rhtZ(\ga葋 ץdD< HJwSC:Ipr^!ǜ ;\ӂ3rwBËxK}fQù3iU^Atln{MEnȋNfBfEhޏz2zK9|"!W.%rbED4wǦp2.q"v(N늨dWnCZRLWC{n3`,z%+!1ӧ gF@)E9lxLx(w|Nu(va*D2*o |R?sIQQ(< 38/Lg֮EQR03%^!| BFVi В -cu͊IGxU7`up-B9ka˂M.BqjVY+ {{k#c KhRB֟jF?y6T`mu.ۨ٦22CF͑#gZOl*-e9?aHj|Ø@_u [lvx&jNq^vށ-SR~;>|D5]p4JꝨcZd{!$gq(^AK'$Se*k i n'*e~@d=4_&MۍQgztK[K^NB7JF ͵4}kPԲ5S_u-]`&<2K˶4LI˝)Az\ƌ82u0h4-6Ÿ}}>yD J"H筥fqѲ4 7BmkB$4SJ{$ O2cPyS:KƩ%EOMN(93?*gd; NѨ$l^hײ3RExs!#@871C::84)b/j6G[Bȷt9Z?v%NkDS>E ?`+" !XG{TQRqPݲe); =,=[ +'8*0575E|4_|^nHn$ؓ4w8=e Yxwע͒k(wQ__4drkRZs Ŏ&{ G ׼v A&6yw$jm'e>)F3T+=5Wi|m5o01i7#ՅI-+Ϲe۽%=*J5޾}V[.n1}l aZCs1@gyOHb3;s QCcf fLr\ 4pjoP`;Ji]LELG<=&`Na miK(ˑM.8@5j*0g5D>+eZuLL"t T'FʻInɄgBOЙxl4iOnT3aŅ^I^aj"eۙkݜ9@T[R, آO:6gE+N=39Ƌõ8~i.~Kd04qLp̝I7 W#ЎyBrmZ=}PPm#ys9FyqF^RL]E۬#k81˞emcum*_s$|#Sٚ[7NZd%K?Xk_T/kP4 wy~.8eoWyK- qڽo:ޜd3$nܕ8?GB̮sU&WYܲ3ݔj|~[I-Row?OS̆d_p\FiYJVk@ɕ={|%s$/w(#B8Rbs}Ҫx@j5@_Fg-@Tin ?qK.bE:*cW>Ed6጖1IlaF} q\Pr<CcrGY^ʰr ãA tAl,3<_-j2fgQ/={0 = fX~"5{$pp>xT+@hp)lqg[ޫ~ `h)wes)$I\Wl&"e3dR9dDMEtbBb"S\ogOTfݯr;Ro |ܷeHCKL b˛d[9z I}XW7BmmHڌ0H9x͛m2otd)_֦0lű3?\-_$ChWW{}y5Ndp^!\v%[u%!='g0^-DC1/aGF|yV8Ul E*2j?Ʀ@q1bPߤE3ŧ#dGG:w:w&#w3 qaN/L-V0 k/Ir Zʵf'LPnhAۖdySgS sGbQIpCH`0@}VY1%yŕbs&B g|כaX>ݐ~LJk%i!" >'o ?6U! B,? 1#sagf JQ?h?,pA/FrF^Jhc)rZ~`6;F4X &0MW  tՌfl =Drr 42B`x?2!T&%`aqfG,]E(> 8X7.֫ϣK^4jDcHln'I'%Y4^sJc+,51Yd/Q?ϕ]&)ZJª>v{9~Ig+#qO'M:Xo\Lps؍Taw/6^#3$(E/^2b 9{Txuq~X*/3+=~ym”<SXlGgrhDay#^s Kg;NގyYqIap'}lwCߏcG)e%?F 9=Vc}S*jN IV{>a"USyHg&10u >%G:Bw#GH ,<ybG`<aj|bT ϷE+K1ݸ$K4ICEš$pQ[hԞ 0y׿||^`iKyݷ <(ѹx q3mp@ EM& JZ0J <'%lf< FI0Ke1!\2{ =Tv SQDrDjiؖ]J,hu3aH |;ɶ^Υ@ yע 3@p$7B&9t9JGT\)i阦Ju cmyP!=43N(%sB#ň%M s:[VQ -s4Jt-50(.["]]xr_X +9踣sZ_΂ѡkβi`$&-6Wf 892\]wzK KRhFL0ĸv?0umzzܣ(R٬x(z`=2j?v߸&<KN"WxFn>|^1D4賚RUGZV٪,ssDʴv4n|I $ݻgW[/_5hi ~ڕ퉯xKÜ+b=+ 2/u΍IjȎ 6Zp8VUNMMϼ* +M'$-sW(C䤡PKʼn/ ЧݱZo4vt$IS8}t,Wy焚 XR5mȸ>:zR h@HjHں>dDA1jNpsUv M;"Z8gZ^;Z*kč/Qp_iEĽ4Qet3Z뜖gN!s,mP.$cnb1p^n\FT 6`MJ;%Oi?<0cv20NI5P?f_kɿYhCXf ?ړJgs*+峨)J` &6[>M^X{r>-}aKG(=vmAfٟxnqS5b&ѐ[>2mKTSGumH&;@XnZ7.}صm幢9(D@#yf8c\_nC&:/]B9;-^Y;"pC:Ѻ@ U @(rX7 ߡ ~qqƤf ke˲YT Dn$RJ/sCy6-t"o>ԽeԱyUj]J|ͯ兺L#2+YqQAߴH k!miY4;L4CR9"ոG9T0d}9TȖ2Hwq#̸ݭȮKbbӎ8.`פk-%8^A=v_o61GV C9 LE^ κ:݁]|Gm S*T7tP;?WZ paۡ"֊ͣ-Y*͐}}_>`8ukZXI$b@ݫH ۠.D*CNGt#Xе;#l}?>i`r[=CNƳ0In)g6F&;@5 7q 9=VAX 7ǀciSN~Pe ^סYjpYfwpj \G':X+|K%'bx (3ol%BxU_Ud4쏢a_&_k]Ӗa%8[ؑN2BOK/0k\m`#UKR?K,':S|"e^,T9߫T}^xwM¬S4! |DɧfnNE@/m l*WBWAŨ9"mt-IJC״SUF7X Kי=(qolHTQpZ'*>b]fg}( r,Uk4QG阍~rMi@ȕهClyLbVoEfGemfץ<0M6M z3EJ4 Xg u &%\N;id0n፝9m%Hl)>$"5Akm0X~zGQdw:qkbԂPPࢤ(ty/8 h"5ˑ_p;H((!hz)-YAєETJ A+|@^$9`?=/lsGz޽1Gqs_~ dg2rqM<<$5R$^yӢa ˸>+Va:ܕeD76_Ӯ,m"Hb׃/}DY SWT"BbF=Rǒ50 ND-M ?&F hLKlS\]-fVy/{RkDxE,I}5趚UaZU{4UCׅf'Q64U1v a+.U˜>؂?k5ֺ@s4I>AFVI';< &w*N^eF1hr(!BjNiawx xHPB3:i@J[JweT ,sr½R=,%C[=e@[jk Vdm4"uOBWA݋Q&:E9=m>Dwۼg~gFM+0(:W"w"n(COs1P?ҥ7\>]7y58npS,Lzt{Z~LSO}/yǻI|tq hʨ DO؍Iۿ_kJآȪ(p'uBsf$ )^^4:ZEl#KzV2XaMܞ%;?ikJ4ZsP-1U~2Ah*ٌX9+b;d *_N[XQ/~Hhb;[lǵ}UQf.z0CM-x7c Kns`V6kr:Z# ??i@#cHh%?DM(O`"('gGMGܛR4 |$"YgK ;͘ H=u%qw{w }z]_ `!l? |A oRrr T& Q} +4S_B=37napzy ړ%1{=̳-g"lNUB ;MZtDxh OO֞ڹQ#f/$˽krRw?UTU7SRt2왱;]yEyoiŐppZ4/VTLٮ&v"Z,ۂl3>.'j))2Ӂ*r endstream endobj 678 0 obj << /Length1 725 /Length2 37946 /Length3 0 /Length 38471 /Filter /FlateDecode >> stream xlcp_5v~۶m۶;9m۶mgy޺|^굻jyȈ\T<Lb**LlFz22a'SCK{;CS. @ `fdd!;x:Y[( l M,m-j6n7777gWz'W>MM.3KS8R\N njgdhPp54X9R6Iv&LovnN.3sȊ˩DTv&\ak:Z"EFWuOD04v[07I;3{`W>?RLLaښ(m\]L&Nvyd_/0$] 1CY:Yz(X㷋`u܍M[5?'3ʿcR,jglobigPvOC'.+Zg`@_+￑e {x13XؙL,lLF\cW''S;,L0+!Vi-a~Es4s34+L=ȖC&G8*8pF{WĆp'S1D+8o$~5z7`jضr`.A SY5RL1eH; kOvT(Z?p4Hs7Fo {pdGZVښ L]yڇ"a;nqC[A,[+G: # Q<[;w\K_ҕz\\!73}7?Rܧ?5 V1<^΁`6ڌ/J+ N T-?ےƱ(O/;Q%hcdB:s,\=4Ī={= Eft^%iu8{b8IQ/[ލmjaȓKRVo2h">[vL@0e$K3K)K2.ٶ2&7>>FHwPRSxCg} ڪU΂cQBMҗ$B`#˳к@ Ŝ얣Uy= S21X^0q$=LD%Mf@zl։>.uziWӯ|'RCg\L#Z&_e؛r;:Mڳtf:U!xĹR)={N2_ Io\FZ[Fs/YLb^'w P*A'QEY7;*R-Mvi C+ zvs&|ptvw"Xj¤ZghфueDdhq\ DRۑr3=Wt(r<`,5Y1 T}hT{H Qj;9/^0%i^S۫Q=*7~R[9諨ӭry1_2iVMdpr ߵIM֪MuwQdҋ|D %5Ya4*y"T CoO%]k̉nZ dٰ@>$3Q>",8WkA9sHYgS*6h:lN>4Hwsj6\jul!E Elz)nN{2]A~ǎ3h 65[qs%'8뾊S='~TY]w`+--*RMО7W&A?w<ʇC>0K4cUEuZpbbQWnxp/߲ dh)hM߁!~6|Geߍyqxcd;}d &:c4B 8+.bAn㾜hz ~Ϧd 0=ى B78$:mPNt 6aG@gTXT'h:_ lȾB6.N8Q>ĆG;Oif3=+p7MNT18@9u;N#7Kʡ}EnL); uGuS"PHn[PzSuC}zE}U<{-<'UzH{v{Bjz7Dݡ_땔Nyܐdcrz3 5C ^^H&&E/' =9GSYarkg(ɀ[k+i<]VD 9_o`Tkİ+/}Dv p")SRLӟD{X 87V17eTW۰ైnDi/:>M(rB "K0O>6v ,w%Z! csYjtImOPRWyY|46[^`^lțtsx݊_Hi%h]i,ɠWO%ſ!;jUioaeNOܘ^i=[- Pg[gbq,|D#F_xGޜ}G k= k y\i57rYa~0:jzIY#5.Xoz NQ1qPJY,m滺_ˇG}"IQ SqnÜ1xw; j}l,- 3tZLF~A;)8Xܰ!iP̀L$%,1ZVNLPfƎydU撊k Cng%(*'!Y/A̍{ēel0׎ACGqkOټHO{dx*7bب掐O"J UQy88{zT6Z?J]iK$ iZ訃K sFn/ t=  $ԣ;u r<}3J/pͯmy臸ػ.~\A'op4؟nymy%Kb psF~6` .r$9&d!y`L{϶/\zϘx)M iNҳa] J+I8 7A"ad=$:qi򝋺5G1Ah#PM۫P+uM VMw hK_g&|}̴_ pM=2B_bj>j c<-F b&s&~ExeyhZ6g}X&A]&hml.D)6pl ErZ,y;7o0x]|6|^5w85UϽj;.^!l~Vm" vӦJdoML! !T?ģP!Q Nmr+Wҟ2zۼghfbQv/e}f*hb|QèeM"h|bt273Y 3A&U7dmEB' 3z |?}vvɎxtJS>̽צ10K(Ʈ,, ֬A%aGXvBCxM|=ݴs[4+1dn)e |wNtgX ?L,N+V ?#T3@x%ﳨ<\fl۸&ڍ 8 tIbXT?(`CRC.ċ)F: rg:,같l\C'nWX!j$eS߈&2҇Xؔ[]6]θh\$D/>V4a^^nOJqZQ_6+@1\x eWOЃ"c2֪N%Sčš '?\ەkzaD*~7[sr8~@!3TMQ{e/(`xggϳk\{duV2CA3ļLqD_*CGNMS~P6t+&lElcԜ~Dbr>.ק| Lu'9CfWr܋, LV=3Ka4,2u즿+nޖ4X--l6yŖTq-^5tsP8xgx'dR]<\9sQ~DtzD|u'= ]i1,/Ґy-MLPI_2+a]`o6Ox4l$,E# 6+wGȍVa9Ac?vVkf N4Z.F5e_kD''n}ޠv+,f~eU}0B[S%E/"*ܽj+TLUh2*ʒ4"Z-#G 3jz4?[2RB aKBi.jG݋gc}!f5WXPk#P1- PUÀm<҇ҷ˄rv$TSa#Ir2$ N~/ A־ N֝z\x"9mCyZ K% < >juYSpl2E"XFZGWji  iYSAid}ŔhY˂cńԭ㖇K>O$qY&RyJ2R C.s2YROdbF9 {b˫_sWݗ{[T\j ZYNDm܈pީtC 'xs{B-hJї$a޶.YՈҰr:&i v[[i&7!LУƛ c9:! F? 4~H+`F8љ|ir" +X4{!U"7x9WCFN(V](!%CuQoæt Z۴Twerg?Qp 'q* "}&0ScaI76esNXb/BKYȏ*eڼ MA l=gNv% FHnD,95[<ԗx%OiPxIíFm8'ҟeizQ lk~2٬7FW1a27y؎ui<-g=@5?]3q) +WzF+4RY? Vw"X'g!mgcV$9#}&l ˜36I?5&[( H(NrS*+Å4y{=C!ly&ڭ@O3F.Cdu _=֢j5XS)dL* S)G B:.UͰSܩ IZ#oUkE=ΦgW ,> e3*'ws6W ,SO!d!9V/c_q&/jv;[ZSlEf짭[(KGoAvɕ]  Ӹò `p\JgԿ6jGmk"EBLqq _@m{TXf t rDaz}ܒh~(䨈Rfj6)suMn^3o-ꐰjҟ)%|f?ITT[CXIH_KT/vPHLn^0YᘙrlA>Q` B" Csl|ҍ<[x?L+ߒz{MBz3ubMRp$OG0c*Fhć,`6'Q*@دP.-6lJ<˧i!rʦ>،w+z]gE0 IX z2=$%.w BUQ^se[c`2(-'[(p?]WAW0/ R"0~#U˹+4w:m + v71g@q@t 놊̛ Yos T!gNZk{51wq%>>ְ~7l7I$3nر-<jA俢'$}WKAqbR& [RB+v(jag6~f}RqL[XB^ p ;}o9 ccݛMKˣ#}jBSt p\_"q,6G67Ȇ "`Ǖ$堁 iAɭSQ֜h2 8w`އVP4(=F0b \"$^tcp f5K_bɨ6 gũؚ5/З|6e@}7)j;|I(6gn3)i&őcJ)b֫J ۡ=wL%Mҫ$O.m[6&BDg-(H}j[e p! x@MW%2‘U_d1h3 \YSܸyXrv V;0Klo`=O4y"/ R}٠dAl t3%VXf.4{WPZ]RZ a'h]qgt\; 3.s?J)o<(E~`ѫV%Eu7Z@ۦѫ!a8f9o=Y{"tڊV_KΔ%$wuF`ƙYvrDzk@ b%ٽC+Kv?[8M!iۧ-2)ⷋ:;9O 0hƬGm=5L4 T%c|VME0%HA޻6yF7sfH'|"c,>d|]#֊ 1H"p$"t&C9fo D[8~"u+!;c|B^nW|$7c"__xi/XORz{B1ZZL gƄvcHZ<ռ5*5&=1XXf},DW&O(]mԓڻ,utDcSPk2C-́SUoV];r@ ^%Cv= 5un;VFt0g`ykʅtnM PZa#ʄ?ڻLS4pn F3 mFI&}.4.R0{L˹34 'En4)Ѵ޷/s"XGFBjZr"V*H mDrz5f%`U B 9DC! &NT|;G%H0 ̯wQ Hvəy$,2go1is<jNH== K`YݡKHqYﯪ(p~<ڽ@WX&q\H$-ᮞXKLrM{_ߒ@+3^k5$7Bv6Mlr I$ȴx|xd1W!2h{HKog3O9`V8⪋kB`Zse@v/赂d KJdTSVvFC?{vF~ޑ2T3''=I&6uvR 3FM̺lc ]¯SV+0{a>QdR 2|@h%|V@VG2cl獦$Zqɼ@gಅ$ι&.aX $X]嚔఑~biVY"h`аq2 kpiZ_/{ߡ{M^uKK f}Do^6טP#vL f͔Lrwq/'X9e1OK2Ğ*/}7ME< ٟzȤxb5`p&agEfذa1Cq\SCnб7V< Q`Twz`>J wֽ yYh"( **BKHd/- WԼ,QhVzLA':3DŽp$zMt }*RbW\/4tjMEmsw\tGx ZzЁW,1ςr#r:y/ܰǕi!)x=; q"2⥧[V,)|ioBv%ɫвƽnt4rWB}>nMxNyC`aw;en+o=UGzJ siڒ VwJ1Z\d*t<ӥ׸o@DcA QHbF좝j3 eKS=;E]D6t{?}963/ /;(k1L}ҽæ;8A@a1ߡPzbD7[.m%ᥐ}׌)S1yVY…f["_>0%o$fm8^qb8LѮT1dQP]sQ9YIx/q6Dh4U(ǓG+YȀ|q02jǁ~SG|sKkF|q@_pUZ*CϱM&ê ԈS*W^݌p&(6ʇqM*a*]C6@L"zv? [>+M n%&za9 >#!PN\Kñ̫:U@ΏWd΀]'gN-cS;^f}$¯=;aA$z{tdUGS="OfhY4_!+K5%).1u[jkEHD5<tnv?iTXBi7ct{:Gzz67v7H,mg,n }[MƬx$?KM}8ɼwxT#EUKѠ6җI!WNDEwk6<8?AoM6xs` 'M[Z/nfw|A15_zBse<]^@wl<)-Z|'p 0>pՅY0l :O%OF< /Fn[ZڻhDh։dOTX:UHA{b18 Q(h ՊZs"w֍3rGы3JqcQ2Bjqrnv%i;]b`Rkx. xnY }yRErP3 dJC67m Bu)_!Cfذ6\'d'z--.Biy:Gfq떝g&^L0?k%xX }i;0M876%NSArw1<le{wc$N{r=o01M{rWBsY'Ӑ~vCVq-o(;iv6q2ȝ*ppP~*wiq~C!ZkBv ~jxmR>طH4HG_ Uq' 45EqMhcS7ͩ86RLekb'NLp,EP2q:fX1ߙQ-VsߵHÏ0Kf,+UYrQk(hYTjQ_~5IoaWɶs,(L9'i !?9NP+q8uFj9stO 2'Q{EScKo7Ϸetx+uBFrA?|@2ŢIL*_bb/v,*Q>@iIoڰʮK2>,/ "yqKgX^\uk1dX Z]: E(x]D>.hJ1# mnu?^÷Qsdwy"}0??9iz/Y#28{8R k ܤ l5U[h웳w&W$\>Q̚mUzܰlrS=ywTt(/A 'ˋFBNH|-XޚTYqQ3a)&-=pebhc{̕MHO.E=Vа]X=TUR2jhyf(ߺPЈ@;F+aݖM4M~;Z+AbvYKk56B_ЧEX',ԋuB0q`%ib뎮 29#hS AH4Ok4zx{Si^BFOF7Zٙhp^ s<)Tziku"&&T4DƩsX}R2?$]=l?>Uyi<>E2U浼dU RsBI*lU8`n1nIfWRƀ]V"K='@#ӑ2^͌)Txpَ E[;^X2X] Q{"ӳS[zuxdzy[v(CgB]p9ޝߘMڞY/:DxNX R+@ Kƈ\u]i/~:]_ l\~ ]," /[Y]NbxцirZ[@?:*\yaqv:! ~U><:Vh=C9%h<xR:%Q)S ^kxl{ /ZxVd2(K-=x 2KSGel},fEM,)">)-䲀C\n"gGmmí}sğ{:8!WZ`dAEڶO5=`┋h=[q2rF{\ 64HTx5njTBgj vrLh\l{@)X z{r3At7IT%CJ@ZFwoߣ\3b>blY~^lB^n.|.h:ipS/)ŏv",6%M%NwIH<p, jYQ^mPC= +ԁk'wopK1 #[6uFTH[y`VӉNfb3Tm+eizDẄduB#jC Y?"|Hz{k@T-K3rA3GЮ޽ Pj;\7>I15[\ڀFڀZ9SוH䧯\Nz,62[V}jێI${98>|t>soi4JL6ҙ<wfM,W#SSb\k$w]c5 C٦$uEZ`}C8 eYlyc}<F;e6Zݧhm+;Ε_M@:6rt%}>O* ymOy)!s XJXC;NMK QA:/tXSP׹=Ro iXG&^(jE[x%IƇ߹Uӛ?ӊFҋy'#][^0Qh,c;!wJj=d>iin9t@>#_5~8s_ +W]W#n4Mnc}3\ `nUϪ r NW^-kwlsUyJF6:)w}]:\ D`+tG^OO !C LO{fnYѠ(iP/^\+ Rǂd?ح-K$}J`PĽds_08T,34O yA{gmYHiB*kAƥ7={ *9`[:>0Z֐/gVú̉ʨR/ zޔ4-a ?Ů-mWxy|PK%$bym`*= 唘{?=-K䆻54k~}[8U`Ldf49@oNPdxpT<'Zd ǡQo/7 i3M4sOÔ = Vǘ.SYb DBR,>V)hwq7é/_[Ҝ'$59&|ncl-THܦ/nOz帴} \7GnH#4AWQkE)4l^Y 1^О]6ֽ+|Ўf8t{@u`骫=n9t)0 ]:^E"]FB8yݩwCL^Xq݌ko= s\+WAE@eo "&/GO=ݴ%teyx${O.oM' gXQLI+rvƞpN/$F m NnP.MAS-5h68 OpԔ)sEqlA+})tl9hUZʑ\ՙ=*=RUF_o@ (S itMzaXf^0|75_Zz7a_^}zva]d/Ȕ=.?K%\!Y:GttM(Uːs^ɑxQޱ\u;uwOIhI^y} b~x"ooi?WBTfVni3!5,[W_ AjM0T+[k?].'2PXh{,;4Br~09,)-WB 3 (VS{š5m 㖘ٙ&SOu89eQ\Ouun J޾U}N;{} w)CqG<ٌ^ʊ: ݔE{ 9e$;0Y<;q,F qqVxIGDɴl!;p-`0Lv3q3eDU'y1[ p_ 2KkߏTƃӥ4 %o$Fo03iE]J{$މ;I֡,S#ϲԖ@Ab-6]10p&I-'PNTTc6Q-3C-BV30Y$ȵ1>1ʭ(er: UZ8TS2P >u4^WjtU[V-#O- ϔ(cG[ &£@7 S툜fyMu9XC(}6,eIS?ˣ=&ZLU]Нه_Zl!ŝ'V^z^d`5vBˆbo閞ԜxԣH 3p#oj,]5ooOU5e 뱺5xb<:[iM7f/Se4°O;'A' $c˃o5`x$8&]/-3xA` ̯ȅRgʄ方Xv c.Ogv/ CS"wIG\C:49 Hj:Y#rȠBȏUyi@6tRhE㾼җEd(zEO9l4%5ZSW*IQ (0"\o[@76#m8a]cgGnA7dmVa't.G*,`mOscv y*$ҙݏgSD8r* XRyא߸\NHRO@OXfl0_szpb/#)S˶>kSLox|]Y7 o_ mb!"|EXJw?>-3ׯ7S/*oYUL">_Ϙ@ ?h"ARㇱs[gJnF|#GǸRpd}|v ZݵR~V]?l֭NѪ%.>3\ɶOϜJ+(v .VHW6/`c-P^puyֳ-,i9f71E#>{1oͷUzCq_mU^n05W w^R_7d&~jgZyrϬN"m.n] ^&U{_߃(yXds6e;D:}HĎ{Nꡘ!w؂7[CWQRf^6 D{s(f}fBյ0e+نk:ذhUXTȲ[F {)3Xցm܍!艧輝쒒L*TUON0ֈ-Y3b+6yP{FW5[Ms6v̪!*m!#gӔa6 rvե \KPx&!h(MΤg7_` S2^8om`2;7.E q `hh\~9WXj(k:I+!౭-#B)IV>mA##h;6ىN`!.;Er.dqs'/S7L`=PS3ֶDz ]ci~, Љ+&v7N5=O6Tv<%IO)#&\A۪ȁ: # hd77n?*+-yH1<Ⱦ?,9nOJnC6žm#E?F0b[jo^oo1뗤mPoA- ̨PSC07Ա/`qPٺGSygTx9 8*N}]W(J ^P;7uPF|Fb*ǥ#;׊"T-E?s*kzYGbs$$:߰-KvgJ,RBo8k2</^{-0@>I8C>G?j~iGXsgbGj)cLߴCnM!9(F0rt}i/dZ&{9(řڮ )r]=P9׭B8ڪGX[TLw/GΦE}Hxl '|^/x.=Z84??WxgZ.`VAʊJI PŚ#*=](AOdqV$o筫H21JsZ4Bv2$ ` -mQ"t//6k(s&ӆ+jf+!^mJtf2 gGQc(ϽLE$̲d__*X w{L-U H+Q gp︩=Y@jve)Y l_~h *a$TN3UQ i*Osg/VP׷2£/M TQ?}r%~ݪ1iLhQ ֓p௹ HRw$R'L)akBaړ9Ez!M>)/庡~CZ})5 V(O!N=wAJc2um7e#eqڅ?vF[#]'lGFmtw-nnyƵhwK ԸޟK+}k\4eDr4×Rŋ B&3Y;]M1^qDX$)GUgf@ HgrpkdF{'DO\ܞ2Iխcp |PWfH6\^⺙zylĻє 35|z a"V?vi'.%B]}D8A&#rY']6OV`ua3ϕnMOѩ/=ͨhΗT_Qv|JNOAE1s>g#%E]QRV(_[pѐ/۱#%&숵Vi 9Pdk_/6Fћo":zUb7GFG=\ww>ǜHYdDғ9yT7MKLf(Ƿ}HN-ޥ:m;d!W':rHLJO+|{/1^RLL],apqEh*Zf\Hnby @LȦĀzIHIV)z8DXtgD VKޫXc~%2OU0ѳ,xaͦVwĜl'ux?HQ&9.o\$|SNY5um6Ydq鈐P1%$,RΣb{}r<*qU!g0/lo? P-\"e=E6VlN"dI6xs=O@;67=!i74tm.L?|JCfIE՜#DF b`%61)^R"ٝ8 fƨ^b=vaS D2Ie괡z|Jy\Tp, "5ӾϷ! h%|;RV~BK,Mխ 3v5 t %,6ݿ4N.~d C0Ggs&Ay[!).{Z8QV®{daQBa()J9 $O䅭kmiEqC*fcKFlX9S1So=0Ӹ)տʱ{@IA )N掝t+_%&Y!|ˆ7Y$3ߑZXxY7xZ]E=,\Ym,Y<`/YuS,m>dAw6!puAכ<pgΖnRR|F$KsVMx;cw;.%͂8WOԲ># gp:^#89k?`v#ya1\k{_BD͒\$ v}`LUy~g 0c- i *˜gDS[J+cD#{+>Bj-X?x`+с}s P=ɴ8{o3nhNkAw5K ipG DeT$|3.Aؠ Y]b@|PG1+^E|╗At]?-={R{zv_񎵌Ok5T3;'Tz[^B"x8J.aE^#^yet^퓵^ O"CKCZAQߙ!͸A'=Ok֢2/F2nFJ T;yO)G`CujtgHlFv$NycxL|Go1bdSc4F_M~pOHKc߿>yZ56 2_$lBW껦7!( (+# u9 C.3P?R߻"`0gzTJ| 'bn_ `w* hA5zt]?K#?KQԗ!0I  |{ b8 x5'E }Y ZZ]=-qCz40K!z޻r2.}6ۜy,-}RgO,|i$bwdiHk>Θª b Lz|D #Fxc>Qg]LZ8{wD#VJb}q$qC)f3wtIr2Ii~3Ց x8eyLr ;qClC_Cp&ebc+ CGL!ǟAG%8{e(|+2DMo0M_=CC4|MY=Aڄt=Ccۈ:ԜA5[c?0Y>1:HGpd[ &Z8 ۯFzg!.H1{$_głVh/][Pa9ɚ{ jmuFSMAyYbusC[=gބ?~5d M^ ssLs*bge׶ݸz:wcӰnTŠ:!LH{ f[6qWbz/UTux)؝;<&zPƏc_@JqhGMk e(ctpQ>p{zN֌K'Y’inŐ'Y~Tod0eOt6F[g 6J l`?|˿v CsS$T֡_xYl ቂ2d9d"G$AEH-77+[2—.bHE8g "%6J$$5 Oe13>TR(1x~$ou(|8s#s\EkV́7*1@n,}%Jio˻vIxLa ;BRސ(꽄]~qqXj+ӻk  uJzv).hw.iAC퇩:Rp8[sK B{c*qPxOR4Oc2eaRF]to?K3| c9M[wn 4w7_;+]i&)CgLa@':wH3{sTtɚiS %Dg@)|\pNTd <(/ g$!pW"U3A*. ,VuNs ΍/ųDNS4WK+cdR*oq'XSlaۗڻF]$*Z)JR`F `ykft!A^ӗ[C}`YpĪ/SPKxx=,6c$9`;9ΤGXQTM<{厥V/sw~fOh-%]N~Hkjl#~+Q"I-^ P9RFUR)WCNlQ ^.un~ nnƧ("YPPM)qEE@V3lXөr~y#}ͫzVV02yK ;2{^heA OŮnV1*eـ\< -fkV\/o!*m8g1GwiVue_M򦾛͍s KWzj[ &go@ƹmmYryK,r#PJ`nB0[qhUM<m|@eb%>cT*-F+-ZNS*Ng(P TdWŻ/JL s4m{1Τ" !zJb)X~Y:lV>tYPOY[]Hپi<!-*Eʛ3kuJ`'D0s~j#ȣ1=x8Y{;I8>8v0fj ؓisTq2 >7 QxM萢6sďxgi%`dLF8v4"37B kwCܿ@J-Txu\EMhb~y p1V^ɬ3UE#}(SԇsHm_etDsJcfܯћ}f‘HeM)BDA=uM2* k/ek`_"YXhFxY&'!ðkN6 SZ(UY y|lINn / iS~ W\kh0yڌSLpOtYߧ2U1?([ַz/gEFۜ~kQ]9oܳk7"IkHy ўy<^&vZ-(qUEm6 h@VǦU{xJ, ǀ\ q. cmfN )ū64 Z{㖴p6yOaΡH7Ac%ic QWov͓U!UM1cЖgt f42c[Hpa1Ņ\]6b.b2 @u/m}="M5Lq>fEM[]Gq~Wc՜S^{uhf@!x׮$ͱ Jy[sXHH-V:cǜU\g<8in\k?@@)ٳA9;?GF 4^2ϵz%v2_}δioֽF1kMԸvf*{%!|,z]<Y Eu{}uPAit/v qO"QjGrY'RErft%!*s* }qS W-OV3`(a0Q&3woGɂ-1n{}h"WqR.]kl#_Oی09JN6G9:Zn5Q<_ʨZ2^Ş!J6&E Q&Z\F!?#pn]bIBF܀әp0)QP15DZ8(7?N_EZm,ïO$TӰ7*qZ,8iΩHPU86*dz;4g%uFJbiMg̔8ia 7y_pWk{sb>GX#.Sd4o^2e~AEHphs E+'>j+jË' g»(. ej@91MŠMc{+_7~NQ@찁PiL:|],χMڱ2i"q| Lc DpWO +BɮlT(Ǥ|ma8/8WڧL 6YUo=^WX]3w(d7Δ]rˏVgr5sI%Q#x@+OO$) `,dޟ@揣/+THk"n3G9^`(EihJd`PB{9ikaP׏w\!qmANOgY6=Bο?SpǼRԲ/5Mw_SnaÅVY[[;/(6ߝkҐ'ᄙ6Ē2_LQSW%yy-ޟIZ~x84?h.R b'/)'?n "%ωc.VpxQ\>Qw =7]3uYkO)nz E& +˻Z[\qF!ȔƹjщW9rF oOtJP!U޴aX S2.O4|əC9ϐYVmhN32l ̵cN'Cn\5O O2D$c;r#.kYMIp48i_G-B-ًHĚCm.>*r֮4p:|C\0ӝzg芥qz9U?/ E!%р^/`# qöG[bt|Ŷץ׉ 嬹E^:NߑwLL43| G>+d)YY'ӝy+=[t9Yn__?Ν|~R;pM^Y|"!FÆ/jCcr:IVI^5CCtn# .& e,) pY3ߺqӥ;)-ueXexh!4lE6D\LqOU}TR 7m:i?;e4mz)1|ٺ}6 qFUckvWI Ǹo|!W`*$5O9.tPe * ů%9psQhAT\QWVj Eӎ25׶דE"C+w1yQ~~GvKx6 E oڐ6bըQLOOpqQo ȤӒ}<rVC–_k<5,F<2T%x\+6[U{'nf' orLú^zRBm}P-6 ƾr`A8y=(v;h+V8 ۏYWM2՞Azt.^uͼVX-ǥ\F']Yw*'N}l"&gPBnW]* VBPDݭO0Rm`; 𾐾@Ȣ=ŋtqf')p!WWK- dTz$T'֤@UdsD9jRBi/Wp{Cr4ۣPH94hYYDBY:F)aN`[0}B19|"x R[. v"H9*5iPs#Exi8Bj#JD|AEtoc/? bqEQ6`0FCKY:OHdRZ"+MKeW7Ab눫D()BUo҂ohRPGZƹ#{ZՎho |dD{cvՁO ҷʣ$N*PG"agcGMZ V<%OUC'-^73*Mv+nC 㝲29k+G| "cL9]ޅzB\!f9Ŏ( I݂[ *wuIѣ*@PIbW8If c:̕[Ʈ 1U QmQ=I>1Nyʮ1?FdgJȲŃvr0OVwpH#STxc ]szݏK Zlho.Ø/}G0uHBi\M%Ǟ>j1߃jU /5wo-˒vG7޺>LFx{x/P07MUJ`uyco"줹""8e&_D Wڼ.z;5n.Y7X>45^ (#YA֘EMFk-]Ol5Ey544 Fe`[.3855$*9U݆0XAL3Q|/&|eInh͵7o<$7{#'}L-͗w_4Tkaß HZTl#ø%!ݞR- U.jfvcD. v,dXv± Mb.n5z9Y*ocQC$Hې=ҦVљ"}`M+Q2$*BZ嵃 CY:Kǘ.iG݃4kvU{ӧ~`Zq\) c$:GFү}"s$q`©VQs`&o$_&Lg6L#9R^*Vo+glj2;gKl#f P >TLrT %"TYbJl.*q~-.[,F0]C& /z)#C}~ f00{ E*7JS+ʱR3|P[@^ 8t̥ZK}zWТѴ)A^E 'cn6 CsFdH8czm]Ć8WCEF&I͉:8T)ѕe բ ] 63o7vwN9c8rVL5,PF5՞G*}3Vɨ%@Wӛ V7N|Ya=FTp:&LG Awr~8N(iY&j۾!kXup8!3j gAt&QEw`\P}!t;Wc#ܠ`A6KW~rh';'vz#D'Q9*΢DX^"D\f*Y0t FLFu43h~s@{o(A:Y^Ea˹LM N!JFE&@H2]WvQHN-q5]duTk`[=:oJ1IӨ2ao~K =e.as)`fFwRumWc 5[1qf+.RAbHk94!S= 3ڟYe#rV0J;#U $!γr3?Xw%ȨӹS+Pmc<Ĺ%qz{7_56B>5\@_r-~B.u7,ds_ظeW҃,`qF>JjT7uBfɢ]Ze'K|sw",; !ڤ2 Gqw?ȵsZC>K+˃1훊Mk0V.{HTe*_yQ*d* ~Qj  F?s=rDMl(+_|g)>Hc\1nQwa$XuH4 c%H*V]nܽا=T'L94йq5gWim⧹䶲lte$Gc RƜ' қ7mߐb%9vUA {:'Tn*b'ћy fG,Ah^Z/ӎBk-ъ).4^m(M #;}4fv_IUrqxr +e@WfEj_eX,"-/^ NFk&ެRei]@_#3J0s T5HRdX\ϋRe`!G],Zjb/ 竁ۯUMapbnN)ҕzHʇp K :G~hGו1u uطd-t|ORFoV=JS'ǺIIv͞QȺE_I\N>B'o *tl?lmFQkՅS5A1Ж6h4̋oWQ/0!]I 2+w t˾:VRy O0L?"B:a{rzz+vp@$FT!o=oㅠ/D$ȷm}WޝBSFn6!#aĭlzJzbsÕt8N!xb%ХvQn: 11J24~MiU~-Pm˜޼&9ؘyhᢘSby/zȜw'H$|mP3HiŐ_qfQ7R-TY^ d41$/KՃkSOsC?v7IzrIgd.iQݚ Y#C-^Ol'9\]A +iɍqK Q\mH*V rv8}VYM.$A*>k@H^swsCr~-Inue%qF]OĖMP\? tdo5ͧQy5pRxJ%z8~ʨ9 ʶ@&APPI:T[@ai BZz|zE0{u 4/qo}AGdU Fs"˟ŧ-cc:KI0b 6]$ endstream endobj 680 0 obj << /Length1 725 /Length2 24824 /Length3 0 /Length 25379 /Filter /FlateDecode >> stream xlzspmlۚضmۙ1I`b۶m{b۶u{[_խ{^zO5=P/  #3/: +33 3#h`/nhHHXXIQ9dea $6DʉDԒUمEIj @bne SR֑Q"R LlI]~Z[4$N$:؛Y3 ػ3wr#QPTRT'cR#17#g=Й4Icٚ:bca!12XX1K7{s\~7!P! Z D`p'nNVx 5_ 1D-?.+gI+wN.9S5sWg+^I]FN^Aa {S3+{ 5?z8aed7HXXdNa_DE=XYI8IXYHYy]S''=ߢL;n)_ujKHDl$촱_k=TAK3K;u<7;2wd&(0x/?*,|j6T_ 4qL!okʴ9g5R,Qe}([q+ R4Th_=jYB/`y;FBuL:P0o؂^\(!/K*+y7UQ.Ǵ.4]m?ř ),tH$*ۭd7ll'ʶKZRT1G EQN)ܜso?13-Zf,ĦK=~RF9] h4'uH[gtG{P:.qkD?cqE R@$)Nt (ד(/#%Xbz쇤CtB4kXm{=?тVSa>>˟m[oGBȅqc]1-uʼn2<B ݤ㊁zis`m_[ 0,>^kM1W}u'MHɟOYe2`7rČ &\F)4ʘNfk 3iUxA"ő8r{T -#b􎬶Hz>|eQegs aPܴQohY`|ӡ=2 }?iz%zb鱧UJ{J[xk639` ޵f{[OzжOi1>}wC;,GԠ R#EmJTG/+ADZCyYpb_' n`$'GfƔIEn]>s:-v;Ko'`U~JgߨۆKK@LJr9=i &`MEOrPM\͓@oΒVdE0ʣ g5{I<a; nT醩W"[4K td$%;q Arz[{;Џ U )(z^zi >pkLWҦDis6 {+[M !4Scuȃ4p濉*gxч^Bݏ$MKL;YϝNc{.EZL/ͫ?4omq'ͨu/* htA9çuY-nn)USճ! eYm0&?QDvA ǁn,nωJ'y&y=ucݝ;S3rfnk/y+=R }Rͭ!X3 >!%MP^OɹбF:2FṈwu] 2NmOq6)}.m5t,SW]#@Z ʽ:m&ɎLqj3QtFB#ﵠ=>|aVT$T#j?c^' ubӆK#\Àr!pK1mn)M8 i9y@ސsf(8~|~흘gdzElz@_?߈qD^8˕Tt1xu5m@v&>TTh_/k%]䗆i~܆܋P12=G h{o`$Ɲs$֊1KIߏ<]Vݹ43.X`o3~%3kD7l,  vg*K12TR'E)Fk-iAC3m'^o88&O Ѷ483I5A֩ᘾ Kz+th@ ^Ch5E9E0kY=R{QGA`0.=ɊPdtG_sY#qܿbo4:>@>ߡ0eGfА\:EQ)l/6U6dӯL26eR[u g>/׻X\&<ޛY/Y]T r>+\%ݬR=0E{E_YcNΈŅoL'A4#yȂ٨B1A҇`pJ rqo+nf^I(G@$Zk>v+Ir7(CC^6k2eHѯ6 CI<% Y{aI (Xgص}gl sBs,tEg`^G+urXo?T@ DJ// ($[eYs0>c]k[DM\|@5 Es\ឧUH8Ӛ˝"(^!R*>N!7ݳ- 5h9PW[d50)gIi \%."dgЮumxH=tEG۰ )Xz*^ڀC틨V~k x:{20A~|0v崖(&.FUmh2URU#uUr/2`~R݄DbsU¾Nc:ATZgIm%![c 2,Ltm,J_OgN YX (P"3|?Ht s˺ `BXۓ[4yFjTӸwH juh =$:w1h0'ߦ*Xsv1|I46LUg !Ѥ4hE&7qSlK \x~;nT,\sr6lH/0yOTSH,=`)M-*eWNaitں^c20W 1@h`% 1[?ymraW%I\11P =M\tݮ|e{͏`@p+Ǣ>Yh I.TkIHR?T&JRZZ6!҉h&Σ:xv aYy)pۘvkN-jXSmf(P0A"HositC>aYcY~QzXL3b / HI9V' :>ll-] SWGB}ﲃD#z!(dƌO rmdPt>mPJS'RdyW9۞'X\nǃ}7wMx. KP*_g$f0Ηg} 2Kcה٥8Ha<_/ Êx׫{Ic,&fɧK2O);󚟄S[v*1Qt,IX'f/Kɹ)*30jSa ɣ9OYύyF]yѝR +"l#sRwtяz3lD8F l[ Mrr6AXHʼn4]8e7ik/jxy1tuxJ'` Fv"y-aS41{tczn}>qV;CzNҕZ[F&ш8 q-7?JOu$E=RVr|A$l/\Ė⬺"{S0T ֧8SL{Hɚ@MԼ\z֥#$nQؔFC80ʰyM̋%cDE5YC5[\iPƌtUDW8VaO/&?WcstKRв=+=cXS+ݽ;^+nFW#[1}Htp#.I b,N^jd  gA({"~Ih~K̋c\:KIu% S3 W)gn39>Y1࠶//aYir~@޾e]~3qE*1tgFϔ^sBOQ)\5ZyCgGRX ]c(G/nV3@ՉM]U1.m>#EC:*ܛ?>i7IpCZ# wrN9-*w^EvzCy=(=”4, TY^X/5R|7~]'MS~KDJ{1>O iU[qn (@,rAivѻֳ.D*D.*J2_iCۮmW&##[2n2i,(z&Sa~)*L/VqD 9i#gNe~LDu6xC 2 II_3aِ"H\gzts *-vs<_܇܎h`^% C?*%6h79^Ox  p4?\T'=wg'`1ahsO'ꠤ*4 7D^9,ڮY (APŨJIIvB]4q9 팹×XuQ 3"Bm~}xҟyw՜B^^ I:g Ź9Ig0 > Od] 61>fآy3>vu`^U ,J}_ LOc;e6Z66ZQJ jlWtMS`Vt0:XU6ΘL;V:|p涉u=-mƜ(fͩO|eĘlچi1|(>2y[`ߏQFtXfH=|4U{o4 X:FO,ln{$tB'Q^M]'Y o z/Q=)jb_ .]1*fdƫ@7eGΰ]< jK*ai#bE=K2!NmSr͡lc$2-%jrvFq/YJץ͈_I&y >U5+np&^? 1-퀯*SͨRYXCDPG7Kusng+pP9~FCi# їie=KΕu/MČw砕-?H-y$(\F#1C"O`ӫP"r\fLdzs ƩhhF#w՛z7ڟ9 auXcDNckb"Y=Bb9GzɅY6pE (@#"KJ#jd_ ޟ U?3D,̛Ws|Ȉd8^Ր∊y6ܫn`(2E=]{wB ז;H?/E0p~9sKtxTcIi{cZB5$NYY>W0ιcN\٧sL2H0L ,ܽ{!R.]Ɂ'|JhZ1B`fB^xTnu:輓g)pM5dC)Kj5d ڣS ]+ix*)lV7x[`n.M)pXks=&CRHɡz_&#yKwL- xN7Gm3Őqm䆞69^Ʀ$ g #[b.u%c$TZw4q*L3gxr&O rI_c1gm]-0M2T1Tq-#9 [\YoEXAf\'H.7uBA%c>As< ۲rx^+Bjcw Xt4' -pƒ1㗔/4[jWVaJ/l5'==>힤},N<6^P[]4~rc[x7B]촧 &“&JB83ܝCqoJ4*Ơ,`Hj^b<(GdF/ަ! C01muޕrXoJ+7Xzgѱo-ZBy~w^i+tnysw}UjMp^_tO ]fPT%j(] I`ck9ؽ|7G'xheL"88A,T0h,BoDt."R[)1.ZTӔ/4=}5kJp?~mij0΁cfL_V]¬VM9)ŲnfTC4S{.Hyg5a+ą'z`Ng%mbS3FŠIIT+n JM2 X^Oٓ9=ɖp3u$4O8\ e0KN{w}uY{o6E!,X Xvz$K/N"\JN?~8U,GVd2Q +06K*zP{/l/JYW0S}2 601O/٧xHze_ #usaS?KR^5f Yb:}̈@f0IŔˁ6S]=_Dfn ?엛5a)ѤN @qbm)KAN)|(KU|D|IZ^ ΚFA/Wޱ0enWfE#(~⫹=) # ̹!Q*Y?5mj;x8ROj4Y-7`۲QPΈgDd7|ʹ+1/rRtt"AܷOXSɵVܼڙuts|YG[6{a$r;Zuh#Io I* 7f3Bs:2{)zSZBE!Zclá:2)Lp>!tD* 諘c(S wV1% ]tr_}kAl,q_EE7ptJ:W?FHjSпDF" 1:]6ٛe1jlBboi^S (U"Z^=itIګ4LvF jZCI8 B6R gǘ\oqjݖ¢DH\%g|gӺLC:sr`N܊# *nN"i/eLy S\˄zބ f=l"v\' bd)ӎyȦQQ'2E=/6ŭ|f[IѶ3陱Ze!͜IrZ&Ngk5D6q4,$e)P=vFÏ'–E+o̩ ;bt4IdS>IwE!^{EinȆ 2ZnԆID_a4or)_j&V~e졕8ʯ~kqAp>e@#~- !$>WDG%C$PH|@٦Bs Xfvsc2>+;?)5;*ڀYLm1}פht7izB GYc'j_ m'3XYrVQĈcաj7*08,36 Ƈ#j$тi+EjP&d2'Ӱ1@?eO8(ڐ3PTSg]HCF^jP ndB8;ZwCVυ &L S̽dU@8$ENBۮPeٶ3;nBiVJ\NOg7-^EJ)`LB.p;t@bqn9~X˝ks^0ߥٸ6A:e d︫<3În,;TIJ`7B5QpEHZyՙ"[64PeB͓B<&ZfV.S6.<-$o ;b߇aݓT 7°J" {-*^%@1 d ax^wdnp+Hra*]?\%xsw5 k0sޅNj6p<ȣ>$vMe{٧sR(4D<Xskk(bzsjzg8A* Hcyfp3]ϗXf}ga]rqFEx혚#C)KUO缰2DX yo($5uRAa 1Ә:Aw iOv}Nx67FǽY=At[$jͧ-V\NlcK+;=>zB~vSaF2újI&4#4Xe=M/WV0'"jx ߠs{i)QTT\"!: w0ޣZ4;O)(J՟XkJ69-ts dlOPhgP쫀uiX:M}mIK*tûX^/Lw"r؝{W (9UuapQpG2G6b0΢ϣoI%X"zbUy0sw%Ӊh 4REڦ)ʀ"EqPfR,Su##diN@&)`O%!Q- 1Lv%[?@O*kp:o|Ў>l!#MOw+X8s:b㺛dBoף&rZx8kn /#^vk M&g?F8jWz vE~~xe.xۡڣ@ *-rN!Cm!zNOVݴohHUж5IVgh\KUK? yR`sqpuh?ZOrPذuӝ+`\ڥurұ[I߂TP)?x^/;$럤?pE 4I }m0&)9#EgS28-)XOzѧSr}sx<#e=]Of>i:;^g@ui7'ADڻ^TΣ_.NŴ"髶( d{Y[ [0Z0. \0 7 {sn$QCĩH6^.0t[,O%cYr=cۡjBOv$1N*aFdbKCbmvea,n͢z`H*{j1P# uB\_1lƲJ폡&[Za nim vL®$oYzV5- ĨURޏn+C puغpIwWSt79y/yɷ|+]. fb3#g`iz9f8aK#V<"VGX )#BnWuMxB(ʔ$9J jg]FR08l+7*HJAx!(ʔ诼h*Kc'~O]{ӡmv)K?.^މ W-I6({Q6[xܕЁO7N)/dnSw"Bn9.﻽jΎA2(&pv`Jp[%)rb%xFkЕh&HO dNs =l_oXu)rvD> $p%?јg٤}E)~%h; pjNBιm>6]&8eP" OŢNNZY5pOt9I?ںtW [-`]V4%V<@!W!)p/j_]^#a`%!mQ5:MUA/"@GDnc*DO8l1w &/DR)D\֒r"OuO柢#>qtP9 /GRn9[AUb?BN %)[&,`=vl*{ݑtH Bn45Xj6M "ORZsˉ\nO3_69sk2er"(G ^J{.H,w0LSUPpL907ޔ)ẅ́Wv99d%yNo\^Ul4 xJEHօuΆ{qLi,c!ݦm"yy`S~̠֮s7]RtSQT@UrKrJd :ߙҗa#ƘMQ"4L`!t wi=Bp hDc[s6 ױU @:ysCX2}58Czkhz(VA4i2WHZ\q%K\IS;ϒ+5q:§x.\ç<<|0qu"^v|k ꈃQA' OuPkeѥ-nXP0]KL|, 0߸ n`ѩh|/+ҏ1uˍL#27kG50_0uMN#VwIEM3STp=AEjd1L@Qb SE_Wg{|,#uTP!i1u1 115* Щ^֜MqrR=jO'kh_+^El#3&¾DG4!:",-f>I ŶVhcˍ7<'`sz//-V[ Du 7>*G'BJ܁[/_.~e5鮇yD$N>,F}R#ޣDP:GL&^U[z(y0:&ZoGg* ءN <3:6jW~`)b{s3eļ5n~oE~~}塖yԤ~P&A!XV?} 72,NغG+MJo(1aZ;<ďWSSA˹a8}wz'*X?%7V0TO(w (@o?LڪtMÈ UuMؠ _b~T{?0Ce?.$9cplBLBJ+M ?o7p!kN_g1#ɀ] ਑"j[0xҜBhL\$ yUu*~D _IvSEr'!y=_nlZȓ<3Io= MI10T. vH502t̊t%5(p;蕯Zk+s}oT۬mA&WB³ZLh¼1$!Rh'^OȐQ[xeSZdx-d;"6ucT1ޫ_.J?Cd-k~)IlPN!oQIbTɯ&Jʵ( HR7ʙ&IO?c^c1Ԫ2sRmcDn]nn=[v^@QoWAYqvm8:/WպP[w2zBI "8^{9rŭHG]a95QgA;> Jk DkAR.qwVu6JW4y~*yuj+~e=9ds;qt3w/O +aTB7iԤYPO ,cLLrg^&ǡcy|CRm.Lxh鉢0&4d_".oCDR9*Lpxb*PK" )(g0SiwMP4b럪N+#o97[u}Ӹ=TwS(_&*'ṗSk-T3ReĎ^ō*Rxz{6;j6-toJnUM&|$*T9ktp.RڌtXN9I3|S.}Y%p*lݹdeJoTQyfbFV\Fx@/5۸nI@5 -}xoT5)qhd^}2V`4\\Wٳo@dX>Ha*Fߪ 'E E>6#}x9}LɃ+V4ɡRCub?D)l{?35Kݯ!!>dw8=;1*Н| H $vs&~~Nzj9ʴLƼP``&j8=27;ËCʰ81Qvg4=bbbܸT]z#q1"?fO] YT,N,[Mi T[U{>O'#7YM)M|n2PBNr ־/V$']{e_1oIXxD[:kó]IeɗFldJE?UfQɞch#rq !SL( t/ bX⬉5m)'jk+;,CIyQluDPb>MI磃,R> lNf3/ )緘d]:E9z3p. 6jzj駆OƊx.v t%/Zn4Z#ebgNTjYU9\>_1}؄Rb6`r66 Nha!0a [[P"m㷭sg>oO'Έ6?AEFd,=s ׏-u ڂVČf陭)aq^*Hסpf.2$()℄gI ˿A|]2yc']LD3viG+YXTnHMs>xPKxw6LϿ-a7.vɐ(̤9T2χɱHk yYdTy3RSf`^͛VD~`7kF=}`r-^0W1}j'TUܘ+X7̌~\ qFŸnʳd VpFPA-b-FA=k2iw=)W7~#wY,Fg*B56 INͫ׉ ;n胭H{XQpS,Q*)N z ڹS$ܡMM#1<1VAI/o|`F7^-IaM7ùig*Յ]B4BBi>/J'&矾r2LGOYp-E84E@:m>BGJ}1Rּ;9A:GQ,!VvdZ5z>)VP| _3<`UD P8 @l4Py #wު(=Ѳ_l瘞zjЦ!~I +U¶ˍTv˾:kY KSZ"_Q |.7ͷG3 7"߫mq20LM܏`D*BmJ_l0 .`8 SN@s-cMv'9siXϣwgOĉ^7{gZ&WGVm/ (g^Zѩ,Q0cPi-JBHX<n,aTr*<2"*~Hmd &w#wT?l+$?#E5=aي3[~q 1ګ.4c>|\.k4@k*CuXa(A wkx1qOhQ!{x‘O_g(%[.UB[$wlWpzPv5mboK&/ a$Y^yV4cC[J{\|bO@׍+d9)>hrzE`ِ6](S--ef`liX:MilpGrlx %CyQ6Fo{}1XVbD"ɍտVM[:C+'c} 2z9UE6E4 'cFMGQ;[\+DJ4<&[_2>}zHXq :vO\$}v;R<dz[8cNT?Lgaڗ~ƞ PB;$` qvŖkU~wG(](W_ &f؝V%=j :NsH&zjl_=͞K:ABMȎr㶵5Ct}e)4ֳ- ig{g]ZRFߪCͣ2|wѮB]H*x@qiOvPd.*߹LqaHa+/B)(RHeBVxiZbBL;`Z-M/ 'vJC~$Kԕ !^#\W礖J2fxfB!Xoѷ:B|p>kh҉ G@ <'otwWSa6APx)[rcLlJlI\rLtzgZ־{U#S .`?c (CӾjoFjI%ԩx*^A6ij]KNkk8rˑ&iGxٹAR;A$ëh"O<W}yیnΒ֋h5!3~= \xD{ c`rg΄IdwEmXB+$2gиցEߍ3:ef5u|@Ι$ l`n5"mzx38}Mjƻv]kyࠊ\@c >F/Ii mb4*-ZReYuETIV\ Q(zDe,dQ%M֞tG<&vsd#}}0fȼK$״,Ae$Y=RI2%W2u~E"ɍ!"湑yC2Ud-N8%a':rԦ'9#Xdr>wj*2 ; r$@*\G B5L~pw2P|Y'[~F \ A$qi^,&=TtE9B%wkIbQd&b?G|$%b^KOXLިf3{$]r(ҦSbQ!tI:{aa Go`ǰy9EqzTS|U-fI\9JZL6]VBD$!ЊQP ]SY#G$#vcaʀtb1;BORT 닌4Ob# ݛ|hDs{? 4]JzoQe΅?NK9t|NGqаlvSBe{ԻR٭337/<@o2܏\4`KĀQy(N.Wҥ/a41g72nϣRO6Ioҷa05 1cZBڳuw,_J GG? ܉==F]IY8#J !.cS. ѡ& HtQp?AO/eٷ粚YJ$Db̄#4ԁ@ג¹G tD =ѹFſ7qVEwE1NI_Z2oټhu'oAGhEA46}?p4wD ʲMx'4wbAbM6a6 D"j,{ܣg(:عHYͦBƤp0 gCRpzU; L4&IE7J_q/k>(c'b<<3ݷV0)l,Ec= +^i*Uduӓu:^ϟ7s.a𑦐^IvCɄ`A5"LI%;( ;eL%CsRFfZ C[t6m6,(l[1,m]%"wjm>r0F e5|,xҡ;7^Ի]Q=64g^jqQW ̍ʰm*z؃zսF_IijH(&R߁-Lm^@maTcd{٨ux83ֆƕeΠj#e'sv2)퉝 &Q)h8LB,nv˷ Voe,׬#Iu)q+[n$YH>NbPx>z@nRnpcIfkqJ.0 YD6Z'gꍂx142X.L.&W:7ArҶ]!Q|1ΪW9Ο;CR& -1$i]FA0dVR"Åp$|t064ux goAG:b ѿajnQ+b%.r]A`n S`+$l}./2|^rOmT [TDۼN&u$SiEڛWֆꣽ%:R4lӻgL~kҗ0]ek==`4+ ]KF= #D+/B=ڶTy \4jh4lcygFV[qTUb^>w[yV)]l&"98Aڡ#F$]vN:yL~qĜ6.zfT֤;I|eO:Q˰a{xنvw5Pz;/⿟xK˅]K)K)N8n*6̒|ZUֽly]Ov:hұU&*X/"E~Rakgn5VYeQiYdHPUO endstream endobj 682 0 obj << /Length1 725 /Length2 14207 /Length3 0 /Length 14768 /Filter /FlateDecode >> stream xmycͲmsڶߞm۶m۶5mOsڜm687?+3Vʈ'XEDD PWUebee0ҳ8\,D\ )@`b0322D<,-\&T6FNu{{7K ++??E*@ 0D%j jlci49fN8{;Sqr7;7?̜mrbB 1U)@Vr;g&..?XcO?=,` 4enRvf C~4v7(Em\]N9{S_ڻ;Y73\CY:[zM-]XZ&쪩]V* bv&v4r2aE#LwLϗ3rq0kDYtL\:vF 335qurڹ[za=&K&0+D x`ͯUҍNmW6Fu-(Xb ZZd.ٳoܯƳx5- 3"Sme^$"n(y<܋}!ۨReG0=9vHNxKvw|/OM=wQ{|YWAڋƄ|̃|Fa7 R6‰+Ԣ{"#m-tUU5.} ac.tsUpő) =uȭfC`UQf#:Y9& g°dp%+A ^is.孬կwN$f•)) Tn.'̦a(uR" K}*cdEEK,3n "r H@/_dd< IgBt3+9¬+$EgSĄKҒG#BSR)qxuA^)yh ٿI -LaIZO&8"J-G^cWRPgkM0#nb+Ƞ z! RB7&`2q;sjE !LQM LG 'o:"s,Sm On2Uv_O"ZY ƨ& 4PRDΦM󦻳tcTXgt%/))xpaIi凔oD~J+" {?UU>CW!aj3^fс6+mndw1Fh;apI]*uBӢ0~f,8:nP㸳(5xeČ܉v٩cǁDmGlCx6xe9eس ] E:40i' &Xlm(s(-TKq/Bm&/(>Fon"a%'B9`lSB{+6ƺ[qM8_آ߻ ιPu5kM8xŘ^2T'mn0 [33D~`FrK Eck\q; 7sxrM|}gTA%jx>2-p$/ ҢP>DE|2)g{"Ueos6.RDr3ˉz:mɫ+6SQh5O"?<IW6o^6gvOBzEL m!'Ux^5 aDԇ.׺hK< 18ڒ|PLΊ}P;AA/2&ŝ)"{c-%Ty?իHzchKq:x,#L6H+a3r0qzpg|Eu/F)&A3+taV*osLv畃4 GR/!AӾg琾cW g颺N.+AN"~ōXʊCZX4hR!#>޷8eΔʈ캑CʠCiV?"{ھ7Ηj;ud^Jy7D;/ S\[_i%9EvP;+=s:ZwUd& :yk13/  H\X ]}Tx$>%V-4IOsw[?m+P6sC=mU vF鍿Y[G[x"fj * ]]NGDPbhvyxEW~"C9R{P(٘ '|Ua/*7(,(!t:OX(n3-_+8ٻ/"uRdzVg[Z|Q`OS etrNٹA#?o?E,F}@n&왤ހҔ +iT mVB;86vМ$U37.)uM(ztY5&t=bṗ<qB|aB hҫ:fsD% e ]Duy$Äoܣ)ʧ'YZm]RFw 0M)G2"RLЍ / Af2nz'ST91q Z܀{4 \U-*Ź!-ٟ8º޴jz"qWsOeG:A@ bpdz.pܡg31_޴0%D%ҡbi#38>T?zK 3އ"ikx>gu#Y}IIGKaHUGwH5SHڄ;O h!QUq1߷ju dfHdx?iDzQX.} .?P~vLVLTMX%@'y'[aMjQW@К ~^ h+8I!AZG a^Xs'|Mj qbIb:/|I?$+}3),X#18{ PB6ؐ&A̻ؾe}RV2 })SRPs\&gysŴݎkwZOsATf[$r(Gt8k{ Q>9LE0kUǭ̘%ϖRORiZ[AӌQ섹U.mw&cG`yA8`~mQw;c c}7ZB%8׀9-s*&iX2V$P?NoU\ Au0D: k0w$|\oyGĜ_dC 'ä}Ŭ%}F?I9v0&':UOć/?9gvJ#sVAteg哮#,[-KoVN @&;r<6&2>r.c̬@jEk{6$MFIX:}lO>| 695>fm)hZvh&M>ߌ4neQ73鞩{P>{bK`Q_LC-HP7/3㼽8`itV;X݇]$i,@=g~II' +8qت<3aLx"Ӓo ʣ/0m~]edZ`v*%#\RA>V@>Y"jqk#!X]DS{Þ k63,sCFY݄aR:dWG,FYus#0śtf%rt\cԪUBL WUj̈ciYE+ Mzwnk$c]liw||!P,ޱ.ͪ뮸&Ac6]Lv&~ Տ?;ުrY3 u1@-$ᳪZb^U q46_8Wۢ5/EFvҵkީ^$;*Ѥ/Jf~[*welKra"ߢ!0'GsOWyQR moQiE#ZK_osK'~bt7sRH+u,6Rb1qOjj[cHoPv;GmY>!BU}%N ǧ- :uk=aQ,0ZӬ`R@xO{ !=Xj3&w~ƁQî8Cƾw6yڀ˯Mw W!{4/NZ$3[*}%h܁P=/`>ERKwtpV\. 阯x/9%o*z柮eZe[c n$D+lxq8YPF&b ldsχUwU//G/E>@':r9(^V1p&knÝw0'=._>Et= [r"éqK#qyF2GČiMC8AuքS,OcE8N%*5'e֐7i6Һl3)]}\mJߜޯsB%H d_cTw>B/Jrs!'onkXn%7Dv%P#E"g+{ rknS5-0oU@_Z_0hB`&#@(/{苒VKd`~ݫi7Ƌ>Gx+^EL;p_#͹W$,m_Q ԥSk2@>hÀƉ%d<b Z̎:¦FlyO;CN9F@e9"z1^5ί8 +3rggh rh5:1TOՃL=MaGˏݎ.4[*W6%*#%0J9oJz%jaGV']}ҁ\0?n0Cf(7ρq@߆#qDsZ͘5l삝zav%,cC!N1ւ' D  I}m3IWdBMu9ub<8c*&*qǨ+1,2\a|=^Y5I2HBy}OQ]{MOEw]nC4.>,OzJOӪJ3DZ #Tmx]2 .N] ^x-k" ?xM5HͮACE=Dӕ6sEDJhǒX ~G*A4pFϞ\jߡ >kW=;XTGʚY&2:k~'Fkb_l=^!<{)֭"Wopf؞r5gCYAimZ6cZVa6~Կ|9 oDb40V4gG- s81w*]pAd3yPtn6e!l(yOCpJU:FG2눕vq)5'P%åqEP؀G##mL!od>kFD^av${Txu7=Uu[&xXp zo%zG.ru(shq;|슪;JqM5/P 6Ih0JiOOGj.6XNoKZD˛7ɠ(֌۳hE=d>a erK/+PϒxҮ=&ccWy4M1lkkDkQ50Z6["5d踃wnXsrvxD= ˾]W5䒽Ms̼IP륣-/7(RәNNf-λĭv>5Rm\-Q{1&w"@W2IL|~l~1^w$(͕o[t6#J5s1fsnHK߯9Ö]yGS,!prԾ|<_I14)i%rC [6AVGG㜔퐩!bE~Dž 07 .y7V/naٖO=ĪmP3 Nx EWVBRH2bT#xs\*Z{Gt%ڌ PdP~|Ҝ Ǖxa8?gmUY]6qHfd}ӟ/e S nS% jL. 3L N)Aژ?$vIh\ɶ=| IHm.Cg*VA )X܇+6c3Ot`2f̈́yarv2s..Z<8K>]-+5ݣ=4;R*#9Фk4u@n>H~$/LRª;iWi-/?۳d|35[( hN u'JO_I˭#XowJZ܃f2YY2Adi@ P}͞,uz2OJV 9U(A=5'N1~ a=(JyFQHB,?J=0]}Pf +ŋ7Bx1LR e"cY*T=i0"OspFl9?% !UCơ紐:8, mW sglz]Gj Qx,J'fG |Spl8ϼTJɔb:>mvj]4n9ypK9s7&屴2벏-M,v~b6gpl-M˽dGTHc#.'+9 D- #/5Q4 9 mt1;otdZZ̀S~]hm[XSV1@U s ^/Кw} 25W vw*4"슦Zb8' 22b^"UǠAR.VUsʲ5СΥ_:rOn]>5wv~ :o9)ͮg01:RHd̙$#\5GLM}$u:WMvLo'oMwtk_+@G5I`]ڔXfv@FhwUef #B Rp1`TæOʋuLJe }2W@ArŠJc_wdzK]>lxŒh0lʛMWyZ!s(}Pޯv bHU>dW2;AELQS_f '!9W"mg;Τ* IYJ9f h|/tᵋW!Z#=9!TvVJ|am0&<5i|9CߑEIԶ?Oj%t+#`oR@hľC: $.aέ٤ sy]3IkuZ4Wrynu/X[褵3G.q\Dueiӡ1& mYtfrjƟhB|ȓcy`PO`4Ń6]t4cfRRe 66>xaDKQ?mɚTiVdL:R f0VK?sxIG,f PP18? ] &Zl#Sb+MEl3+6 []3][鷱=jsd|̆Z1A7dk^>1UC,ncd"Ep oH%]T#ALA7m^K`Ow~\#h!./}2f0E,^-y֘pŻz4=em!Lb31(.Jx13򰒖vø$Y|g~) j7wr>,T֑2lK_i2[c6V#!K0,bEy/çc)zM_+?((asHv5 =qmT4'9j,hd< VQS[kPJ"z \ rÇp9_ y|yѣVv5'6r(C+ZK2p"\U7y Nw*rzHp\iGelG'gгq4Jg ^E N::jm DdGICYu%B^. l*~\dt,=%hqƉ6V Se?fbrǃh*??mp>WW*BՅƙ4$!+[@Q4lYM*O3Ar5 7ێ2 *⨛JT,?@R\EV<o8BbN=m7 0w|Xrq!ie} Z%Dnzc52=fU .mUoeKGcxbkqn4IS j8kꖸ,WUL()# `3J ĤspdʳltUGH:fOxCDm`VE-xޝlH MS~Cgr ذPJ%YP1{G\;ޘߗ yrgfl48ukRڥ:ޝŌ+*܊o2՟0aH9U{-\O<%Z"l YdZcXA%XXPȶZ%)mȺq T=Ǩej 1A DOo,ĄT8^%ql26חeѵ| Sӵ܊/i+t?b73 Hr o`VfU*Acg,FnS˚|?UTX'*vؖWxInn˜E=\( 5s&Qif?'.%afԽq"$ eQ_`:ҋJJ1aᡅ:-׺{d? %nC{|VԼ|Gs6YJ q\7 mpbs;oOsPI̤s#*aN],@Z&V ۳5"u7.O;LҠ%G)aVS~&HX3]Il)|.~etA+Zu=Y ^T=|eltJLx3ptY ߯PW;GIz|Zbqat6PTΣW4~ݦ\$ Re\J>=yQaJ, GoDX~%ӬYĒ1P#3e9?l/ߚ`r=<%~!_gcbВ3Q;_^瑍4DP@Pm_Xwh?4/Y)rX9Bh8Gr#NoR1oz6״D.%%YF]Bj}IҕޯAzԃ̽rV&J;S.*ҏ!MJ7 WHfAۋZy-u7GHV嘄.ZJ>[6YJl;'^{Ͼ׻C]@7еl7"ͬP4~ЭiU%z;AǒeON>[z ݨϡa, q4a Z}$8E]~ݤR&]6ET &}Q,,@UO&cXF=lSܠtb},u EQm5R=10&W? U6Ce6S%_ glpX]RSMm>wEq0i9Ռ,l8[[gVe ]d ܼ ^77w#7V]>EkkzY,ҁ7 x"Hdi쏂*bm\Wk]}%D?Bt:HP8"lV ^$&PSQpX_t9^,d^)n%Z@B O OMKؕbG!>m?<|d{tIk>kZB JS"/4oEӣ"c!lhq'{iA`C ?UqIJ~.O'vR2щwE{/p bW v|Wl|:Th!~vqx.8:HDW yH%k*91Ge7mmPź]xZ['pJ0w3Xl̞|)-[Z/d+mz~4E9CL%`SQ){H%\+n2෬>#1m<4a~Gf ?tRXw<&meh|Z+GX"Y7> stream xm{stgAulI:/m۶m;ul۶m۶mgͼ59Vڵ뮪uElmi8"JJ Lll:FbbAc}'s[!}'c@@`!ڹ;9 Xll] \...|.4<4+)̌&VAY9uqQ2@A l`en274q4&:U#?ظ;8f`k VQ * mRb89r66trGNcO_ == ``ljnCmLl,r9;_|Mf;[Y[m휝ҶF6p`T}ks+of;%/}tr;ə;_nUXohedT$(#m mmLNw0a9})X(t4?[% `IMfd+3V&#k`lOfu֐3")[8 rfJOrxyZ|HN +gπ{b[@?h|"?D{ 륐ԻjM>6D LP:)um_b)=J¾Y>Bi+feF\%M xi,0ʀew$851Y^AF>B|oJTn?8XX0mx3ڼ{^:{6\TM봹ÊEv F+dym>Y2+wE`6`J b"|b?hgzkLoB; #L!|G" TeqWO}:N:u~uS.6?cN$ *V'ɫWq=tNxܚ6ic0K,oXnjǹӬe.4k[!Nn7oև=C_xRdz6oBJ3!D/*yͩAkM ?;dߎM !~^Tީ :/寺*cDe۽C6/'|YR Nbwqu|rd76 ibŒ_OBpFZ,@􇨬戁Gq7ۂ2?:RwUq@aѢP?:|)x9u I-S?r6(Am9&ūŠCH|Cԙo}}]Yؘ7L{*0~/EfTq^3CjސЈ;Md>/|_EEMFtls-#*j/L09Wm7ņ/䎕dY'DOO17ȂʮL0(?A4cv}~cSe#F3c&O8NBo(Y]n:S_3j̖W|Go18m J}$U |]9O& ׈Uە0߭鶤y) u;yꧣ?Y\yx>tm0?'Pi_NЍ!BQJ2JY;鱛TrnIt5,lA=z l]}Q0*I!j`xiTpOjݹvӻ`tƊx(&xj{xD6ZYWVa*ˍ']Yz!b*\L2Ʒ" _ )a #NbW_.pv'o(?Dl5nT,bi;4iQ( j7(9<%A ^?36mܦ7Ejy~Ӑ̳,˯8ܓkex+yC %9e K+]>dzc ~ Dmt!69ŭȆ8i43MѠ#cl ދ&|saec1 eL1[T#iS'Aʐء1 )Q!IkƹAhbBq7B2[]c#&t{&@(;n` rFbҠt/ȵo?U.UO ҏ`Z Ġ\lZ.\V;?ٚ1e\S|XRȟy :-SQ)-(&ʄQĩ+n)n6xKgn֟P9 ~r޵Y1_>Ax܊,&Q6өIʇ!n xTКcϏ5;P97s P4h9!u`'Q5 fBd mg dm,nh˥v󸌝1*'gG#wV@{]|0Zڱ$ ]#Hz灻&>P-LE CLcf"E<A`qYz"#^~(Z KA[_tӑC;ֹ6[a%y49D|XVcknrLMHnsxKMjgMt(luF!?NluÍMVEM* yzNxh`F> 嶨t+k* vJ^<WgkX&B_ydcCr\v~` 0)=?h7{NXX ɭ&xg5y|X~M..4Ol=&LR،h]plN0:OgwBN-B%!`^DfZPXUGalms9Wt,Hb⃟E S%\==, ?=QtSɅo\t|mP`;5»;wFik$Pt1fb 8Oyjy34D7w > ,]/%%K6XRܽ((nN123l:vݖ,$ʊøMGO CT>'|NfA* eoqރ+6O5‰6,pCWmψBvocfvd=v7q=z?>ɕi㙒{ ŗM ų}O|!:D.ܾy~ݳ%utxY';@GWl"lLLsdmptg-XCz4ԥȺ  Z7adnW~=2У(ˡސI;.M \2i@-Ʃ~5ZeL<6E.VH0K]{L;< v+9LJ"e `ρ5Jk{q%\-?ؾ%Y~es'A[4|=_h:5Wrؽ9 Ld;c c*Q;+~e"ErQA )]f8}pBH? PGVi) .Yw;3&ԿAcS;Yb.7X<6$$_fM ;I#tX(yP-B[Q(_ D0*mvOqWvy0!~"'$T Vwb$8~0Ҿ'FyRB1:-6PP3Hf_9˒zxXL'xEfv<ήg7]=/|y<;8Ⱥ|4qf'L 2 gV$/4|Gq͋GͱD1<@02U} 3 ?2[۶Wglb*.{ /Aw*GYYUyw1ĢcC 3Ö)B9T=S6WbH_s]eOCX̵eofNnG"GV ٣ c{ 3– R>D'P0Ύv[FwC^})Z)D>#jL_Fc !/ĮdLU 8Rog3)ǗB x)\ϠUsQ+T7๲r`w(W /IuV-ޖ]3s].g8clIfylo*]|ie4E^^cxՑKI<>~!! XT݅j'P/?5 sN9̓CܓZP{^*eK\ɬ=ǘ==āh`_) lTbg(_>\>u'tjQ|/2ُu c*Q50(cEw,Ąz!P*wef2% Y&. bwtpFcar2 /RE}uJ_ϟ7hÂjcχpYHvQ9W xY$}~b*y6 s&+f}#mQ5Rsx*gn >7ȩ};E#pXX(7֤O Nj^d#;.m6pr44P\bKX|0XӶy6ry?+i?17 e ڦ:Cz#%/*Hr+L$"X9 u*gzUe&˶kWS"+Wh8$v R@BQKBY~* ^I /<9c=,/ɻrC7QUj%B ִx/Z8VweR y"0qٔO1T,Z̤|~:IIUI6ZT462LT'WhEDJiwOrÙc[K^n/Yz;s`"1Ǔ}q)MKt_ Dt.I!2,V$c E׌ƚ_}3a L~Yòq{y]&YN1͔V'N1Rȡti< wCPIA͜VRe}t"<'W@yxXe#s fXE4 jBR+NvyKEIN(j iWGYj7%ߦ!.pƉP >!'!ɰ.jez5cR"=GoG? roGOҺ5SСQ/b!`Vk55#\xBUS ;qEbJ=_+;T8B|{nZr;uwNk_092C(20/^ґw*ر$rqYF5k#^L@Գ)k{RCrte~4;sLwW{)Bɯ@r.`PSmKgk,}"$do$."cbf%V`ظ,sqQX.Gqq~JE:'3&LI/'&w"M2r!x70.?Bxk <YL>gE!R'+Y*d+M>׸n8[vŧ3LZ4b;V>E$m >ϥ?!4@0 KFn ˳o?j[s=/X *Zc8l~ GN^%?12ޏ@KRRhD+^\?f"4lZNHZ"˼b웅]pK!=/8-V G\S\jb .p(DZkgt0mJ)ͦ4"$nBU79.x]lQ*@<,aC<{LcpJ~73e!Ae,InځߜvcㆫlesV4t)!7Ijp =\B:v<&2-x sfOIn|ֱR(X0ˋPChHaRF.V",D#qۧbڕm2ƒ`ṳz(Jh&M@];CgNw3!EI?<KKʖ mΔBw~MrƝfeMÄr;G; РI3|d؏Ǎry6FgAm'Wt'<}pM. +z*Pkє('VQ fxx׵r aoSaKhOCu$Be=>b1>JC5wpr,]D)ԱQ>hB:2*"ȸ9g :ҨPeƎB>C;vbѥ/QKd5#iF5MMiQ{;0l~ػtc6WL<#iOӽE^DSV k) %kdE9`w߶m خ5lb~2uҗ34%M A0ΈY1?\.Qȯ75=6s+Kwo"ʁa[$LLHhʃw;u$tͼB,ǘi ce2QgU3/j^ E/O9 (IۂfW=`F#pt2B0> ;2r|C}|G|41Qm;#y[Bȵ ]V뮋EBd7!,8}Ԧ8@'k;`.cZPrJhxEK{- 038x" .Y}uHrj |^5mYUB:= Ļ@b'L򼑴scEjKy8DpÈ~mPdm 4gxfoVml6:Pl_xߋ(·52-"W'#>^L3VMa|VgoRL2 fіh&WcԝyKj~s]h󠷛pJ(]T෤WZ>q1f O=|^텅ްq[C ihoП7pZ߅9M;py[<é}foKTl%;s O C͗>t,azW_f}!WbKWԓ9g7RmB-<–H"l=r'g_ Pb!XUOL`K8RNu;n⋇̌glFް&M{ ;~PR(; ;;C^jG`h~dl q$h/wϼe>o` gDĦc_0Wֻ~+$gX`J_Hb!{6{\&?p<]DnYxiLmϰq>/n%&cbrMAEN[U\αIpfd5z`\&R#zZhhγOXCwXϗ2SrwLvek"MEO'8=\䑛ԞbO[O+&'ͷ}b<0sr 5ۑ &0󳭘{W'FFi }oBk%"DwZɡ;ӗeL%AQ* tFWg˂Ƙ{X 'cV::*yKvRl)߳dur*tH!@Xk^Ei!G W{3 5h2H:|K,tW4B96^,2+&yT l5]Bn*+etߪ{,8J|O*uC=m/^%Emr s/ȧ[G82f'W| }!^EX!ɩR 2v'6XpJ%jX堍{h5k"na&2S պpL=~O}Ρ?dጩK'W>}X>*̏[g]-'qZY&xxȤdd| دokvu¡uWU4< LDܝx32G驁iƽ+,ŁP n>Kjs'|Q5vwH!%%L)Z.o *> &2>:doht, QxBY[K9%F&Q4!P*\Q$f{fp%b ݧ,}Y~W $Іx"M+W%#t8T v"?[$$"pHݼ/+{R9浗,y ~(M]b B{4sSnM8ZUP%9[LY&}@5Oxj"i3irj1W<Ȓ{oǝ|#Lٮ x6lƇri_=hX %:*qiϨMNo&޳"Qϑ3B r\g٣$*ݹE i]jzލ}LXEw˨?*/ )?>ln\_6p{R@5NNop=M‘JAMf-П@gYxCH`l\R2i +-kdh%\J)j ۣ Vj }0+96TL'aw2xX,1Y3Gr! ", QXDb韓Luo#ca2=Z@jb;\_%cɇI&UV`k'FJ?z2sw<4OVK.lһ࣡O0kT`oܫ$jd:k3޵t=KEydRf@5~^}vP +~kCם%~~2=w$6k ] .x4np틋B8?9lD0yI>Fػ eF3WR0q(>Υ ڿ e&{AEl '۝mj=w߫3MlE a)FZ48Eh=מ#BЌ'oΙ j:Ɉ~"+N +a aRIӐ_L0Bώ|Ais]¢ 0Wq;6o^@O۫"%dTxQ BSOsL(r Z6wzlV U}M9:%dED׿o!֥=>KaJnSjBYå w/)@4ݰ87he8E`Kyƣoxh<1\%'߰Yv)=tIT4uưb1y~i ߗlh?Idڐy^qQ3*6)86ax<\EҵjްI;zBwIW 2 hl0DBV j9 6 ]ĉ_o/Ra=DX3lbC/ C6U'%6B\ $Cm*va.e6Fޟ:mDf uME^rCs ptIZյwlFb!L3̏j%{E#w},tH4yӞ׼ #E*O.RkدiQg5,Mَ@Ne.MTt<6 W+!J\1 }`3X+P!tY-IS) >,/BeŲ/4ܗo^1%* qLc^7`_GlB"p(ޏ#LIMvjw<.Djjd,tšfeMȠ>Tf[ F_~'>],\ D~g+8lE4П8yKl@i|hO{qB8A\!bJv+$A<}ϫ^&r ejMԿ%Ja8=2:<׮-`7r <[}JWSb8³q>·NTXSRUF Rz[ɴ]BEѕuQDuG(*5^Ty%%2^rAROT\y6Qb, ␢ !_ @LyΔ>e}.G (j*@]n#ohZ̐&[9νd~"Ĉ:[CU!T_FٍĤhhU뼗pd8la1 zӏ1 o277bVP<֝ޑrPa[qqt-lyGGuWmh >KonY24li{Iy6@s v3G*E8qǴ a Z#:Q }eHDz('˄]t+4,jX"yQY_J}LcDYv`-1&T=q kLXO~m P"]{Jq~<3M؇=5j/VqAm좽ZaGT3¿o= O(.GIʉ 5G~ $ XR1=PxcX0Z, >-3SN'$oĸvJ4+OtR6r|r. |wh/r0)`iI[R`h)JBqҺx@mmU2 ~iB?r 4U{ 'T۾۰/KrL\bC]Ih2nO;FK*c}iyc%iEpԀnf!?bteNL4T(_)fWo v79wu |ߩ%(ޗcG'jc3* G+{i "#"ˡ;J[:kqd*?eFY^eEl}# ?NufXu%[]N=XdWhv "=~w;q=.VVdMh* Ƶ B;>p=¹ COJTtYկ(_tg~v[;r3;K֦P3šyB_xlbrg-Atu%HVq倱/496G>m:<%vꯅ_y,"U{.ڄsDXB}+&3CU>vܶѻʀ}Vfn3Cak? endstream endobj 686 0 obj << /Length1 1608 /Length2 1974 /Length3 0 /Length 2751 /Filter /FlateDecode >> stream xڭT{ 'Gd! h`! 043/`mnꉀl2h oڄ(j3W&R{⏁L Z9af㊊n;ha8d큝9rJłFⶃsJ/7r[G]:htE`3waxHGD>-uY$}wD#Oz[.f^:9+_?͒NVQ_qElU噱:g7tޘlV5?"m *ƞח /ڜZU}WѵǷٕeHD/WfF uMbڦK w2^yUޱ| ͡nj$c7RSBt~7Whhmkn{=ɬkIY7Lt粠ֹ'c!v?)˖)v%upF7xK\ g|е3B;b2S!ҢdRĹ$*#˓s&}XayO/)R~d̴xW+l8αCq5+ BꄃdS^J%:ZCʈR(kmQWuHWׅL9JP8]=JU5̽sw!|V~]z.kHYGDՐ%盱"֒ =?b mh%QKl`#,o]-vJYVb솟|׎Q\Nct.˼*u%F 4GڽeK#N)ʔպu:ԒjSa}aHP+zOD XzNJg2`dC9~P\0 gc>6ʟ+(KbvN(ԫz2eFq8v_eN#?h\^g2[St(},W`(ݘ8P3ƪq2r''Dsnj'RNVM!*~KP35.Hl&ܨyf+6v7[kkՙf3g{sPV+M)gKiɥ~ޜ (5*~/^v2 jp /ne%ߡzv,<889\#;zVGTS ˴#ma1SY+xUm伝|04ƘxoW.)i4VDZtf,p| ee/y%z+%%C o'Z8f?qtr:*-f}yn 4C5卭sz/I *So&ͨ4!g(W`PF ,nfg[? = 0|h  D>WF|=HJeUWXh%z䩸}X,uI?v{Rz`끡悕~<"_3KPӓ[d]˛i'V)hck Gm#ψ]ӻڦ֚O$Ȑgz,- !zqϨ_PHk?[H(V9wSغ\޸%gHs]_c>~P0T)qYbԉP#Mם}1M&@Be&c1hJ}R^^ n5}r]NM/ֆJ^ endstream endobj 688 0 obj << /Length1 1144 /Length2 5332 /Length3 0 /Length 6094 /Filter /FlateDecode >> stream xuUw<ۺ6:ѢGD7m0:KD F3["z z D%%Z%W{9bS<a!tGՋ 1Xx%}G..t@cvpk[ ;ׇa<>@+(,~P wSZgRUE]IoIAWNR >tD,jbD_(ad @Mr, Kjĺѿ:G{wyG8/h憰"5&Zw0B`4Ɵ9/nB#~@?83g+F_ tGJ =tbtzz^ :qU 'F+ԄWAYAk${d/RnQnfbV?eSՍ* ]TEIhkGl*S {X0=TipZ*КF؏o<4$f(+'3ܘc< nh,O<9Сv L0_޵#vSӽAZ䘚];V[#'U:]"_vy@h9)}y4DZ]a֞5s*}\`B|ͮқ;z83VDa(NOۚzeޙvgq{ie>1[2) jcj:/CF+EESQH5}}tf߆HĨoe\F߶ R[k9]Wإ ԏ5 `M>&GZ}߾Yh5ˤ(A{jmTq~dBoO酶ri ©y'`' (r +/*dJ-y^ fl E+Wg2E[%@.b0l@p:|[{!2OkT)r:$yM\"wȬ7d[G=AA*z[ *${6!4PQuEc]Uuirۥj)trڄN>4xcP,ɽDoft6CmsηW{[s#d=F4'>m=|`J GESru[i4s1@\ƆqXD1*Xv$Tq3cg|y6|vHw<0cmx̪2,ܲM0=ӏw|'=YLV)>&_:~b;"W.(á #,# i}&19s4k$?8e39cZ='r yC%ێW-g{ʕНm k">߱|4sWXvՒV">3Xe py3q23Wqnէ)^  Ws< %쳰>{Hq;>dב:@&1-91 *MM~/"_Eol'= Y w ʸIіMZ2|磻2Vء>g $/u>*c12)nʪ%|J;J_x o MOU͖L29c nApYkw}7&vI}跧[Rd|m#߰CY:Өd6RMܘixӗ^K2[b̻"E7|B0ѵм*1Rb*%]*~Rfg $[K5wxx?C3p$/mrZ[>UPɷBiV^vÇxOFV+#ߎ mU[9lTexpB"kgac~u|:h+~NİMyBa'*mX],.}Ѵ=y!vg^~Y%kMnu7è<[*J%4B>-J_*?[qѮ$]WV>LI4&DS8/z&h$@i~1^p{Ewf\!~l2& \[\9:|$ךLYz$A ɧrOW>hEڙm=uLm.)J^9I*,?#o2=Pc^T< S)^{b7eHteToAevYDyYʪ@cA"7l &7ECZgGS#'G񇂒5oG?u[e  lH70&ZJI81">"L<  b7-.%z=XHK=5IOf9p>@e]wn]Vh0G/&d\TS'dWXM :ύ]P+ [GmP"/XIG۔ >}]-ڈ@3g?ն/F&"֋FƜܽ5nۄ̊ I}^a@uC떎R"֞K_5`~ؔdn7xg1C`!&@z2tcyo.At` 6p#o8sZC ɬxK>gc,T.+y HA͵iD_}z3=Sp+kάeEmŕ}] OH’|`B=-DsQ-k 1Ŋ qc*%ZZwZ1zg@z-arhxO@UC Y8sApЩ|Ϙ :0P#kN5xt[ R$, xtLTNYNm} $V^J<Śr .I3ho)~tRd G#j QeO_ZzHYp?(`\[<#|y! ڠǯ]*''3aV ي({$'H)_^G7Ȝ~vkV]xy**ml6zҼD:Np>5UN3rR~j{6xolv|oFW[) m=472;k $e |{2?4]Xu+t~ "t=Z2ݯlb˃aXYblte'zSwʁE" ft60 (8xLԴ_+Wm[+P"r0W0u`4L-[bv:('דgQ %zaL6R&N E7`X ÂHE7cͷG_թtD.n}Fb3?2V1t53@(v5Z M| 0H' OLwo*{xB/_&y3X7*?h+:[Qj=x'I@a>zbOKTc_~Q!u,W>+L;)e Ǻ*ͬ?.qtI^q5J,u\rL^Rw/èGn.ݠxY kj=Q'&|d<5Su@4p'xI?]Pi9D#.5xf8s1gY˛-Bc1)v6~fJNR|y4iRdS XȧJ|bBeʩk3N~y8 龫ݑE?_,w\<LAİUĖ)~Xr QF t1cKZb_g;/E*$ yYc3ބ[̂}t ep_4oa ^{+yu.IUl"%= t}BXv E8IHMP,K&pXboǏ|KX`WM3<`.6ttK ^mCgtݓALwp}VCkhlz0B z"/jՕ̽ǵBiS&Sf^S ]jDە4@s  իu1qvi|})Y<:'ҍU{OFu{ ƍwKJ嵢_OYO1LQAr$=ZhW)j1\+cC?r1u]/`C6rqbjɓOY%E<ic-qZ)Luҟu4 =6)3RdBS%?{mVk)ʛL>@,sI 1y5׌P#U(y, aG~xU_,>C =΢5@$ DVs)a>EHFV,yGPyslSX57>yW*?çEԞOX ҃7&O?Ǽ=/Q:fV-mVbͼ8\.w{[zVm .S$whRL` ǷT"ǧ{Wϐ Dŵ܇ŷ+=9򸵥v ͩӥjTwW -dm=M58GA KaRSu*YKA-)#_5>GD3`l{*RP# k:`b'UmCz~oL-( zl7k"ϑ}k ~xRv=>uiiꀞg92gf'Zg-~@0d!x0^ B̫q߽o'{z4Ehp wѓ }"^܈;Y߯m@{ݕֶT Ի."x5kq}5m( Nk3flFC3Ohi@ŨK.mx뽧. `H5uދ4QlˑoTRgC:0 xsEJGLy>jM~Du~jY>s.5{TK>⛿Љ反XkӄeFo}u}lYS*[ukaV endstream endobj 690 0 obj << /Length1 1614 /Length2 1050 /Length3 0 /Length 1860 /Filter /FlateDecode >> stream xڭT{\W.*vbP^(DKEk Lg&Z\uVD*,ZdU mP<,7>?O&|~sfD˄8iJDb_ 1 X\UijXMa<1J5C$RTь%q;nZ~_%\(8pbu72 S*L]e:!;;^nҩN=ղ70ĪlׄV]ek[(ӵ8<:6ɖݿt]6S+]kX}Ava~$ c,W$)%wꙸ޲1vU?dAÛE'|*_-k?P}#vɓ> ӔStkptseo]kSW(/VY:աqZTzOLuM/ Yk:}̿ Cngfs])~z{m&8m)Vvvi6kfmYu6ئZ򚦟g#q߲e9!N] +S/Wf|48M5k9 endstream endobj 692 0 obj << /Length1 1626 /Length2 15621 /Length3 0 /Length 16461 /Filter /FlateDecode >> stream xڭct%\%۶Ymۮ8'NNlWl۶mTQo߾=ߟq\sgCI b4H]XyIL\Uv@y_;% h/n%LIXYIXxxx(IĀNV.$4Ztti'?<3,I~q.!K-DLIYGFQFJQD `p2%Qv52%2;hÍN$>ͬi͙/31odg;3IMm]!n!'`@ggS'+U%V$@f@SZ/_3 Z&3+g[cϿ98Y2'qX;g:'ֽ翲_\p,kmaeϮ؛IXm7su_ggh06z.Kߩ'-&BK*]1$c{ ׼gpxGI3q<*MC )P?6 ]sϺ`זOvA?ucZ|v̹vċGNo,~39UOe7=l]2=MvRMk|I׍LPybvz '^'Z }wzZǣnU[g:uu(%}4d{Q ؅MoeHW}6/'}|`&0k1YΖ+W= {NMZZ=LwϹH@tZ]D} Sz4G|ˠû"kܵ)as2÷}뒖ڬ H ~:&{ꯂkKNs+e"JX;^hªRu~ΐ~V &g$ˀG=@:/mbchxvbwNNcOpl%µ-]%*4=>d&Xgy6[ =rj8&0czJ4DŽ>z6a0V'{S*ۏ%#0If7EC{'73CdI Zu>/˓dd1K2?C`'scѺKgaBo+He;{)0MNq;*p,5 D`#ĥn0FmV9p(zr΅"5= sF߹_Jp_oF=~~4,%O}7еAeAoսgCyW1$}B8[ (l#S@׃"L\l45 vE }LcHYӣ˩枩Z.'VU ;l Y\gOSJN.teR6seÊFNj]eXӇiAVءӗ\E8E݌:| ~/;/4e(vۀY n%ykv0z6]a[v*hm OXZw2 /q}hdesE֢7KwԤΐ$B37[pԡ%-qW4v-x?aťjN+iƚu['FVݱ6mk@~J ˃J"nqpv6>H^+ł5},;(Lrə2=Yc΃ c0jtOb2b%6HE) ?W(U_9 ?v^F dV>bI,IBD"ܖ>A B+TO!RDqQ%PZ-zJ;$+|/Fd-OD1t JM2;Ӿ3#26 k,e'X}lgu*_M]ԼX'gߗ!Ġq,-҉|/JcQ:Ra!nLLz%" uL3eɯN#+7RxKrjVX1`eE,d8s_7eے 5n6F3#ZVxdSy9NDOy7 bcWєlV5ԉőXjmcA%s#]R[CS33nK *\)Wh dg`uM*PxTg3^k>~7`FW7|/ߤ1ld486c;Uhhtk5wuiybH7]h'Ch86%VwnFoA)@Yq Uu)h XUΘ]׆A*ָÈ]Fim6*~\Z1݀VwQ|咟<5ײ/r5 if2A2+G߼PcPW.*D+ ܲɠU542VsnzZqgG؟-]ҸU734+.`̡M,.ye~A&JI'|(y*:Bbh@ .MNh1P.>m*9qgڅ,LmtڰBEpԘJN*t|:[9PrQCߢbEx4V38wszݨj#젬1{,*ߤjkسͼnV4.F8@(DP6=xew *+Oh#M.xpTSzE~rK(x3j;سYal.FIV9Wdݸ8 wc/*Գ i?Ste3*a.݇q B}̋;)ZA.K GhsnJCzכ1e<\z=iE%F'HP#:lv8Ųt8>F.bGY(K&HU 2>\HwIJ24'RF1J+OQJ4-C%\(32)uZn2>X g1 Wu ȟp`Kx@$;_fÕBXlVT]u-[z{|{2Xk%U v<MןZ+z ,[=?=Fp1gG6wZ*`?hp'PnaꋭB-ш Z-M1USOZW ;m^=2a8``yYZv]Oa(wȬ_:kQ9lN_gC,_|8\*itr^w2#A$X~K"=(u~R?[;>c Ys4XSnNU1qV0_[msÜfdale..Ǯvp}5sKe4ćŷzhGW{ +72”DwG1KaGXlY)bs( gNb zjl1~n6V7֨}"Owe2 5[jRDIS`-Kd~̆Cd3 +A#x!N"+B/eǾ#k='Bņ00C7O*KzѴ\b_3Ћ5P[Iv@^5aB1<ȵ>}Q8iT)M,}P _v.)ZZ"ԙ C[ɘwժEHo *9I&t:d\[Z2VRe{+^oe@RBȱ~VO{NQmp|?l0l]4Ju@LMGqcNkQ P7e ` k\n6J !_Ĺkq@]M@!Q~hW//H[5Ssy-#IQ4].n)SFUgqЊOBйVfqȓKGza#G1?}fJ_!C򗡷Āmo&ݑA7eì0H.>'+ՌZaWDb@*rVGk:E-r >b Jl#?0<ٻ@??y6$K,c2&y%OT s6Ti@+cjY9/fC(9Mln$GK+=WpofwZN7,@zWZPmvLF ͞@4i9_5d+VH+#[!ijr#֋/m阄fkٗ$G?+S{eYM eYd#X'X+q5 =L"J+pp%́ +3RdEVˤ_hGT1bahzjwm稩'WɑF Oяgk2 8ZPNp~>O?\u~J 3 _541F80{[) }"c:A]M`*tLd2n6.(LχVpǗd  H%F(d.PZ0+(9u#)* UݓPCHO&YE1e{LBDnMQ EJZA,m@^Huõvz^oSg9^MkxDތfwfXh7qd 2%5iR^_R: Rc/N>?npH^D>ٺ+&=CVb7H]4ǹ0Aͨ]^?\;}@G2tCGŧ2nd_Soں i_l)Y‹?H{M 7@P^#ۡDNHk rod`R/\$pcm24Dc ta糦 sFA…8ZtlMCa7b7 px$H^z@[U9jJo Qk5[rW,H% U(PZO؏:CKM߻n$}nL=4Hݹ9i_(Ѵ~4{XDB^< ay4oy8(c*K[˔W$u선5¡, Ђ|[͡Žce;{r@*X:fEhL|94 }K7Z*-qdJPNmDR{o99!x@'F1wm ƚKS80aE dZxwt!䁞d/?qF$фXu_u$c,7'K!dN=?NJ rw=fjE`{E; B}*YdOKqEObpB U^v CUg ?y6p)WP !E /"yJ%B6f͗:ԛN)$ЊyJ{ $-~UvMi%B Pk[dH^gԘ!GR ᇿIXsƻIԛ<qY2lW h,r9X/_|SB>r˶?ip%靓6z'q9attx;4}AʿQݜG(uS|F^/Ҿcqh.ɾ^"4h\qyGIDu ^ '{q{D]-^Yg׽J0g{+8̭'oy*ӿm^wDYei-iAmp+A[!I*HZ#A~v2 ~k^q`Buf^d@(EѼ926Z"'lb*WX)S~8^AX (';'f( WƮNEdAwAV? [Z]r' 7~HOޒgv2BsJKJ׀yd'$訦wTd˃SGiN'/0W f!p MW%U^$Zqf Q.BFYAJL+CH1j.=#H(_^=K^&F+Q7Z\;Orڌ-EUseHW{ϗ8``*PeU`8nn,j~TYmֹ  0wcu uuBznS4MՌY*Q;3>"waw\eOiH!?=>ZW bVXpgzTVֈ6 N!h#%E3Fz)3$ <31 , m)(ؼ`(Sf? [ $bAD4 aFT%Z\[zv 66+9蹍q"0Ro3·NAUw2rװ.$+O^uNBbʀx~4\ p:{N:9*@A7sD;663*m7!cA _R 2f?t3ibeð`( *g2<F _sPۺGm U?#=R*@g2d-S쨔}XHsꈒaDRV& °.@p>EN L^) bw ZZ S 5_F%O|iQ6oJ\aQ5 p?QC]K3I.UH.+[׹OeI͒6M]` Fg?if1͜1nȡ3ep~ϼFgiŖb]ݠTEI:1 yŀd&=K sX0UmaGXك8gN&L"{97-lX2?YGk<8f tWjΔANǺ/ih{Vξ4S@ȥgT 6ohIY^O:n6-ÜٌxO^'visx=q}@1\ߖctu;J2PqM9\j&W*n8jyKV6W)r}fw hU/)t7ί8)]w@ۅ77 e#wG>WZY ; 2,䮉 gG# t\Pj^{cz]aŒ%XO #wFc+lQܑn0u,p0$Ǵ3duօ' #m?GJj =Lk~. :6f 412n3hє7|x~˸Pˋ7MCVgr=<)LA}~Vܳ^輯GJ4#"2&+hKv'ݓ}}0X'/nX'0do6{x @Q|kQqK0y)BN2*;1nyQOhh7گ&yVKT7p3*BlB+>Q=l( vnk>H-8ĉ. U>n]TUIf%Vg=a~8p"ycrVfΨ-i_-=Ngh1E}Tk%C]/4v27v!]3aP_ Be~Uw4, O$gG OOEhH#߯t7C֫RХhx:ɠ-kYQJI0w;R` Byܜ6(LG60E1F 9c$Ϩ*Z'19Y[3`Ćo =FZͅΧX4-#'y5mS\zغ?e'n#1 ]HzMb!1^ >Ku}\[Y<2["J\'rx\)ERE|Eʮ(HO2=!gx<]RP ݰ0zRy|vH lS7숾2{#JKHaWj\Q껳얃${ oeRAYR Pj\9}$\2ԏ T koEhjY/p\zMds7iiL1D;)2s S%]8bk''#pK&Nxe?7$Y4*֘4bЧ<"N\#rtMb#y|fȱW 41+~+FwCrD}{B{P`4i82o(:'-4[o4(-o}j|h|uA03NMQr]\2ۃiIbBL7iJ"9\&'\JQ-Bx{|:"jh% uÞA6!igxwM"&`EJ lf7N -RqɰknH+0Ma3@z݁ /).m(Ÿ8Qg(aa0ͷ޼:T$RH`J^G?5~f'!D޴]Q/A?aT2^I_5Z;ѼCp0D.3 -k,\MW24 Y7p pK}toy^2)()I@a k ]_D gQ*Rqy&S?ҸfDW08gYkO &bی70~΄o|]WjC z;]4!p qN ؉[y!̎#uv\XuP(X0.hlzhB+Vvt9>|-  *~Vkg!?4"zUH B]/8*C)ť0IZmnΨmzjZqCV}M~)(Kqh$Kښ1. ƅ=Kyw (bl릳"l7:3kW6:+&V^Ã<ȅ}@} '3]BmYK_}3[whqG(+oCp?O3s<[e4,e4y^@ЦmΛϼV»e #6bbM=HE $QgYۿַCsY_YwA@k^`R ahiT-2giG!,ӳ0?!> ^~rЊI|q'vŨ 5͢]=g}[?*FEX;U%(M]Z'y{q}nGΞ3 ^=yh(#lo:Hct qqہfIZ eB_b[lrw &/ğhnAhhMY3 fB"ߞ~zMQ?KɘI fk $ Y?0a3yV'b[>~fj;SKB<0jޤPx"V>gaȼ]ǟr[+*r|u%"9#楪@֫@l©GX5;K#-!qu*a3]zFZ7D M)y!ѯHYxطiIv y.aD,.ox }3c\:&bSBh4ɹNҍ齯PjcB7Igċ\$C0}lo,n1UKKybqk:)ې$I܌(2]R{!;LL?[׌h 5OgP3*o>˶Lm JČ24Sş0+G7qGķe#{x/':cZ (HBimԀk4eZ>: u=S[f3С14ݳTfajy\^0+:Ko @s_ҒJb}г(;I< B@ƮD[1v<&v7U_ÌTtxC*t*]aE!RY[H:ŽNł,hV zn8;`W%>XɫYhr'!+(ZYαb"2 G]'YZOZتH3#J8|nu`.O4[_$Mͳ}6`/Ke +tșNK?kpOz`]Y].ê銻a#Dʌ0ҏ1}JGH)b +͵eGN611i8dKa[+.3EYuG`~ ;ԗ=%8zbU;3Q3p:/缬Rڈ%pJ`y8*DxjC ۻ:+ s7# )j"U߲3 Ovo=S NBۃ;yzB6==/& g8XI։t攮UthVڌ;R{lA.!Uäks"W~͔]J;37 C~#+n!"AJW:_ӽպG^5궋0q(w:y֊]=pZ蓏^:#'}f_^i]4! FHK~ i@Ko,qP쭕WSiGL5džQΟ\)ٔ'emG"J¸<{%Rp_B6r,!(1Y2R|Th^eK`3uu8V=lw"gmwQ>Y.f0`GF4Ź{FljW7N +\pe" *)U۪|{f=I_1p<Ȥ9$e}jbB}޶w3O[N0'vk[r2G9\bs-8X?~h.^BX R1MDtD>$n}|c'M[&ɫ)ŮN];?c(~A/06ǸDq[ sS R4A^OGvF!bzPpcJ=UVA-CxVhlLy" a7$s8k4s調T{B6՝]ײP R}\1 5,̏uɳ4 J d@U;8*2nͅtL۪G K\f>yfݨ0 ^ZlҼilbERAs3&.@k~/cX KO8Fh,vV娈_jts[\| )7.3`NaM@)| aYei됰%sZt)]9O);X%^}:,RH^ 7u pphF9EsBg61Bq|!42su }֦wQ i Kdey쮘EkkV~ Io5+ 0!D^,i 0*AO߾}.MgVdL8z9`Ѽϟ謡ܩe55磼%ajXm7цRd72'*Ѝg6$^/= `#\E|{0vLտXe5DP<6x":AOYxI}{gm-#pe075+h{%0Mu6,5>;g ׿^Rq endstream endobj 694 0 obj << /Length1 1630 /Length2 17903 /Length3 0 /Length 18747 /Filter /FlateDecode >> stream xڬctem&;aN*mkǶm۶m۶J*ەӧt{uO\׼kMNL'hlgh"fgLD1tqR㔡S21s ;-lE&\uc Gp03wP*Shz:Y(>Xۘ:vT618L-M rJq9U#bhma02u29}[S_,A'dobd-3 `ug;? +!{G6u윜-*;Ogs?,v-\)_0@ ['? MN@;Z+ ' [̀hbt46qr gzǿe?spv26cbol3 [8fEo\M fo@c;[k)ߐ;Hoz/>Wh1kk9]2@[=h?Z;3o[mRHo9hg8Z[ؚ_m112?$[ebk_+K׿gPQ,*gjd!!;w;'3&俀, tvph_t ? 5;mS/ZncΈ;2=+ù+otZD{ |4ľIп֮/=|.yOoc)RM }H Qv(~ d+C8W^كbgTy0WE0sLOZNdk9Eүc#}x4q@,ߔMF \8Udע$y⽯=1e\} 1 I]2'M ϩH5tJo^4q[esZ4GAQ^ M0Pc;\)J2@$FهF%}!\n.-Q@@2< M5,uSrƲzqt?%Mꈜ ' EbǦ+Z2>EO7]-q`tYƣiTS\/V.ߗ5EiٰnV;~^vPjV_$a27A•_ u1= i)vUjQLVݥmR)jg~'1 -\嶝aEAnꚵWAzCPcߔa= o^lh5nTK 2ף"Wb$8eg"C-MW#nLZ1'X"#Rf& \?ĽIۓ{=:c AeK d$~pqܦ/D{S<]~ͫ-&A]ܖ߀% ,߅b1@-_ $脜nL=^OÊPe*at=)zJ:!nN3c&m ]إu]Oz3MK9jZƨՌ Y`:$2_GzZLݏ2qR} OGjlYj˽l;fU܅7۝oqonY-3TxN,L[ۿ}e2&",iqpףXhج}7?s4G ƣEy(JeW)!?yIpp`?Hv+3d~{ |q?i.Sկ$d˓"@9w)H(`\gX8%IMA [Ux0\ʗUL9b(Eβr8WM"~ד[lBR0C >! t:3H?S^KZ̻)J-.nZ %ؐXГ+~B"J +Js,rO<dO)(']s~g'kdc+#{x4[>]dkѶ p7(C2\ 懝JCg bz䂾s%Fz)3Bk9G瀗-( -z;|*QG KLRH@,pˡ)A,'5Uџ1*o@i i3}o7ua#Ɔ"_u]r!fb" "'nQ&7K&[,#lmӝ}flbXX#]fgx୛BMmLpjz4gܺ(:ṗGToq% oĵ֜0ݜw`QK$_@{bYtSw4xUldv"RÎ s~ɫΪM$OOUr>j)"3G3]+Ge'3Ͻ: u4*!)0ei HP~#P880N<3{@!|.\dRbc&%p7NMDDŽ\])B+ lqrhZ?7։>HӬ/]~zH!W8朻ag>mʋZdGʈӯžzB, V=|;>!JD_G5Jg? INj/,n7&_xrIs7*цAdsIT᷈?f,Pn0`ߛ(D?r8,]ǒZZFɇoXpm)A4{cynJ#]no߭{RӼ6U$5!{ NÅV!hnl %"W(ek]sC?%[Цm߹6޸tVh}^z+'!fvZp3}ĬO^C`' ?zwG^Cn*5dU-Xk"HJ:ݬ  n6 U(BA,+C¶ imoPja>2զ׍w~fI l+ kf4rWjKY!k(̜nilqBlQ Z\q}c%vsӱ {X?Aש~+,x P9Dd}CqR~JzY=[7v ʈa l4Pi#tsJFBypө :,f%D qW`1J Nb}pwӳJA}v^9dj}5ɷ[¸oMf{{1WH8B^! jgyb[ݤ%Qb C}l_3lIuT" "6p8/[\KPJUALf#ϷuLo31>Et6O{S9!eW6Y|ZWߩ|FQFR_/UJOPb~/?.>HFm>!,o^(E D3i/]F$LW=NVH"n{ISh~|ֻzNEl^nO։y zUYdqspZӕϚAX _RL`,5tE3gP~ 4l8uǗ"ҌVRCLGh2q  ִF8oT"[Ś+=CM:K"cm0bzջo$Z;57DQ< p6扰3֜6Bي&͟HDm6M=@qMr.כw_| zTe\߻|f#i?B$4 4PNE@C/;qUj>^6-t*pQ6hTr};{-޲r&LG 8X5)Eu@HiQ_ vD~:uya+΂wQ1Jn#JsnE[T+EMK Q@a)KW=^x02ŔPCdASkqd`GK*9kxDTG3祆8-0RfO;m7x--Njo7+1[GGTsÇMh'!5zӉzrV:t5青d!tvV/">.3T_hdƣ2|Y۟7N/j:ZQ~nbuc x ӾQz!OG⮆;0H1nr(&t5"FF}[ޅ~0>qq:1zp/}Leތ(F{JrhYTJ,99T󛧟'y * |*?o#&~[EIQh F^.ھ"ٹ0Cpf^_s"wи#wraqSwX؆(ׁ--q`֍GOVHcTqsOf&+B>pVe=|Xy5u(+`H#e2X5 c__ # !O٦DN,m^ΌL2k 59(E-)urKZ:5 WW}ٶ>S=E?jw(LKR/EGK>Y1#-* GR5XM?A!8ZQ *M36UVI=d ;UYԱ.]( o@]CS:"[m$PS'R YצE }5ݤkB9fM\2LyؐF!)h.툟z `#Nwzv`x{6k<)F¶c-=Gm1^ НD~:Rͷ82 寫'(C׍}C!ܺOE/[?p,6Ⱥ?F*ḑW^-ۆ;MvV`\C$B),!G筇pVX6Z4fc"1Cݾens/KTo} ګ*Cʯ#Sē$ri;:B)s|My٘^n KS+X%G dq0 {Z(XrmnեA=O䗯< *b?c%4mu6+efkeMr~לϕǰ OHm5I Neʴp{a]XR$=_luy)U0 K!;]Zuo5;[I<WhC(TV͠cPID5otLIm6Wޡ/P%.`z))X=HT0k{ 1|ߧa\ ?Yiի Q+vI'č*ay)AwGcMd RpM=$y$ [T)6*tξci:,X!tyrM^˷!#B.Av/a/AUVE #mc!ǻk!{6xֳoe GVz)h]T1HB;T[ &Ӊ^x&])lVbo{ZF:&n:]_V Ng.'h“51Xbdlےsp\~6Йe2 ,yI]Ȕ#R5Եy!iS Y&<-j&l7ģu3IWal2ClA5Nj< ϔFΉٿbaN 04gr 뼣D\qmhWTkK[TG}WP$fշ߇gsKCjF{{WyH3wn)XRTӸ2b`LߊUE2~D:ӗqpܕ&juB蜮w(FDuhI)ϐC4̽YVZžx(iAJA5QԇqLp(ĵ͌NSeU]UNEmZrU* /TԵy}5O ٌxZ.tgCP2nNcl7?K|E ѹo [,'pc'xx(Ծܣ\v`g[ixke(?ζj"}|ǛXa//n@r7Zb-A-xO.xcy}/"* T+F&#j r٪I( xXxyq k~mZ.D*%HgO9槌xPw GV<) 1CnN,cL-NJ1-QhL_FхC#|147*Z_Df t̾?sPH0S=4ł.-ʪWQ`U9pfe`µ!E Z Y]Uo+w*o V 4}@~伢CPj-LuׂO0Åہ[YrO?,Kz|RigBpl-vph*&pow5 #m~n8zPo Oy/#Bgy5]rWL)GQ', d5ۨ 򺍹YpΪVA;>jުx|9S. Lr՗oTLh8,в%]gN>ksQeBQ&"u(}@-A;m +ri.sMY ;yn)qވ75r,pzw,^3-Јo\Ue}uвǐj4?DaQQ(X[=zfCqhشf[Sb5IFb^򳐯m;vJE+T|(rvY:F ؝N1Y J0^X +`|qtvRdc\^"hKd]4;D l 8:IN'i'?f%Vj UQsht Fb.k!GQJr{oj]&9E؟F˯U/-Ɉ]ɰ'c[Ph.-Bw8C :ȪPםƑOB 3]C_U1!1'^eI|JPz@[%K]Ө#@G3|:a_IAG}'_RLe_ 52iyF E 6\?5&2SH3 3Uqk1K\&1w> dN\-c.OW 5Fb(Y_/AL3P̦Rﭼ$oD)BPS1}IsY$FkMZF^U.n2eF>k#$1l_kh|ڒ4ͭB>ߥܧ]<'`يܷqХ`c<&VP0J(pmT?X~ϓH[Lt{y/0(} =db-OMM=LVhV䜙 /建FͱK5>jO UmILU=Eoxȅ\2ys8EVk%-Bw~,|߹ +$8Xs=Tmf őֿvi^~|v$0@H؄aQl]Ѳ ŗ8_7,H֯Fmw!`$g,SCI\?i"}lÛ/`MZR)*X$$ԏf&_ѓ0Ql4QQkQ1cʺ&9qoPqod7VeӜ _#`{8䗰˨rN5P<.bc;tord`ub'X*k) _L)xy#*5$/Xa갹M6NĪD_!8`A[nȎ 9bJhk4|P0.Z;xSO9oO9]X .gVQ-õ>!1iDқQw;3FS|W"qU9]}bEl$eMGhPu,G874cz (Xd>\WL V;wnBjc -@7C=5¶JYȅ%Dtc@ծlO➍Jg9 AL)u^mUFM4w`23E=#x$b|-X{#Hm+gws9 P(”R@Ԭy5tZyH޲,𸄊gaǗv t#`V.-^ dkhrHXQf?;(-2$lfiҀJQe&&~lъIzpϥo!΁E)!xS%QqiL\J]W+ߪfܠPαբѽvu+>=V QZYW33 U ryn3%]%@k~q_킙c"HP)3vy"Ĝ[W/&<&+ yxxjD>MwmELPm!5uQIϯqQ &sErx)So7)sNn!v37x%j"\D-F?buÇZQ֜g,zUf^d#I@S)s?XCM L"hF a iu?H}diUKUяll3z-a:OnYcs)7n9).E$S8eһphjTS6Z`τ ۚ@Q|jXeEjw߬},,D}χH)4ڳ;bX V4V clƩ 7=̌-1:% /Nd'׎R\N'6\ -8n8惆z\ &^tNگ_ěcVXcL>Q~JvOPS6 aUd=,Y̭#a];t D֚~oHƄ6V*1)[z]cxl~?!3:ެI2፷IuQ.31Uz/pO]:ulǕճƖ+gf78i g\2іELd!(P_I*I_%4OI;L&j:[?HO4>3"h"gSS}tzrAwFkv8"J@c0S%‘}ŏ$:/ W{8Iؗ=lU #}:b.6|` 2x"S9Mgqo?47R`zH ۉ_bR{63 wyHOJ\饹Y9%R۟3[SnNd-j^35[T6.o\YuʅGCʼn?:rB@JBFem|F~VoC99̱h>9پ,Ԓ4ѭQ"K;Y3~d25>aތ܀.}@ 7`ruynvOߝ}], j>[U=}+TiK{g/zm⨹3HĻ49 7/n!)ߕ !tj7/ė(hê<͵`K_6F~q{7nŻQTwd-5't<{N f73BWAۡNiBt.X|ԕ^DZST {If4ҽ#̎rKX.PFA6V%a150~iC'w-'E-9f&sD/s̮>UzMV$v )co9x2Q +Z>AXWQS;pq4vWSܙ0x 3Ӹ-'GC[G>W[\6>?;FI6 Ur|9X?c╰\w8Mu;α@}Am=,cOHd's>tC~l_-e ?A3ϩO$%J\8Dw+.i0A3A6r,tPizvDmJG"PH'"r]W;ÞؑB"U N&KXFǵZyD2G;XFY  zS#FF'3,MM>p 1\+= hbjmaIʸT>6 $1 }T8mC޽ݭTX3[?p &϶ےH=tu шωRZ1iO7eJ*^̈́;"w>}-c@{K5&m%H&( Y8e[CC߫"ft83(܆$gɗȧl%#E o2j `4 X`k߫ffUL;J*Ncm5اp m+'xYb̨6TRGX6Frë[E@' GDԟZ})Q_6j0}-Jcv/+re7;N{kge7YR6~fLjzC3#Ⱦ4иcn+R@>jӎ'dK0SiѡGf{Jo*(SS뾐ϠB;Q8f֢э*۪ ԖEc/"ƒo ֑Kh fDh{pPXa_-r# HwyșLẎj=nU!$ 䍕 xqK܊[XoXSV(_ؘGFǤWg O FyhMB I?!JA) %ۮwqнጠow=<ڻW n-n|]a`A"\S%yhR|dZd712z5ZTkܒX JE) +H~}txh3M[?%EAgu4c "$37],޶<Ԑ ?Shys)T_uG' WWu7H+6Ixܝ_cL} j4SYliTrg6'wRONJA-7l{-L@zWWk[!F640z)Pם[|Wt:7DօR,14'kAyk\+f:~b.vqc^\u+d1Ceܳhmo9F'62h|QA ZêIbV涞P@ iu^45OAWt!:[=#\ݗ@S(v9zpX)QXƵe\ˤHKuKmi 0n،I%υ7"ͥ۲FŽ€z[|~OC?RUT`,#͸moe[9+֛^!\^BK{{3XTGͅ΢{5R ~%e7=y-,17PBٔ #<Պrƃ, 6YgVW畍a`wqs|Әwk F3bzAFe}Yy)l ĐPe9^dCO ɻ'@*(4B˘ cV3{_~}/3-WA4st}i31FwW 4 r+I_^|[3孩h[q]Bʓ %mk53l&h$є/qnJiW(mdZϮB'‡ ͬoꆐRxm𞥦@-c1U4Q$Bٿ+)ܩ4;IDU\ E` UGLlh89"X,W4Okcab賐hEeH(nKA =5lFCvՐŔu 4CYڄI`lwԭpႵB"Ll01v[oOJ[6ęqj#2 y`68 +|17ɢ(b5lOFݵiϻ3؅d:~%H+S iLCo!M vsE8Ӄ}"U͆JoN Se*#"УL;C7c;(ɳ4,^U8,ϫn+ޞ{EsC^ҀBD|cӮf3ɓp$hqA3Mů[gpDJM1{I2i+u Q3&b!1rz6{XKډx 'oX$}Ml08KEc:A6@x4Y5YNg _6l /LLx>h~(+ 9@jj Xpڬ!X6޺yOJS}8'GI[5uKM샯a?/JWq& :ks1"LqYd^ұr+lܠ a+7-DT hf`'=+A0J i%.5SCE;g. e8IN6~ej:.։i tGm;QX c&dgmᶋ,wV~v+2qSVmcWŚ-]8"V.]Hlz2A|O<y a5NI8AS[h&,Ffѡcb";Oy2q?a~j: 'nLU(EkV;M$踮8ֽS/K+,me]S3ҙ;'w8 ߣ8O@xfTor;`MZWrs~%lQaq*;Ѐ"ʿt-Nrm*h}uM'B^ZaYl kC:=5memk0 },LIVb_R: JCF+;\,ީ)P>Ӝ% jLtpq^?S#4i@Z=0 0{n-EDda*=g20f5ޣ  ;9RI?Sos/{wdXv5Lh k+k⺦Gs(uDv<ՁN]bF1!G)|=h&⥙_SlGX5HO?8[r$b_)Zze!7$/p}v}Zo e  Q$>NX^>åʜ`G&̍[~ !!ஐT^ @6"ܮ\xtPkv6StW-s i_ը_ \.#R<9]z}I'% 0'k_8e`Sҧ(>}ݿ҂A T^.vByHdU!h/g2ނɽd<%A5%14)=9`q4Em6&Ie7؍ю2< ^^%b=\oG0NStF|@ ?TCwpZF/}MCr|UpDr4.@uPA$@Dl?ޚ gTnFHĠ*ۧ`y5炷*ym%@սLx&XcQL3Y^Fh/BrV`7锌Ҡ׶7F28u8VimBD:3n J85/>wk;sʡ8g=UXao45ۄ{N~kS:kd@ou4)w"&UKV3<;jhF{E8qN"0E("] 0«>*^-7)S Tm:5Y5?-Gyx-Jb w ;\ jE^9pbCjb):~mJ2BK"4?wfQaY7Јd*blU\AebŜ\(AEFYzWZaJŖ2!JװzA-g*vǃSf:$΋I';:hN4wݒG e#(1ʠ/2D58=[@ SH1\7ƞ;yEV9NJFQT䴓Jc%rv8}5@hHqűA,5xVV])k#9 abd>{0dvҘ6wyk* t ռh1j2W?utnT=\uw{ǩ衋| gOcCk?f`T!%RXr/'0YTKWfvp?'R7Y7ٿU!Ė`)&9S'2G-3|XrVYj}AiJ Ba~\\mi ~._jejbQ[$˷SA endstream endobj 696 0 obj << /Length1 1644 /Length2 6246 /Length3 0 /Length 7086 /Filter /FlateDecode >> stream xڭVuXmQ$A:{ bf`F)ABAJi$vzw=~}>ϹE "!h~a!.2D"u ]C Dp *0B*P0@D ,--MPF }ah)7//߿,@>@0( P8Cv|ЎP= P7Upԡp;r:00r0. %RD aܠ`(7@B]a(C܁p4hx@~'#$tG`nb0 >FaH4U_E<ю@( 17!` ( @`( CtI;+>;qP NDF`h^HXvϊ&@i$ .>ԞHPƄpTo"E<{;.3f̞~/\|76BbڢwH/- &%$C}`n @]`p(F? 3r῅ !#ٟUմ+%3lcm䃄3c䟇߄JJo_DJ1I vy,1~`7U8=HO@83{4L8yP7Ly wJ@W XvuE +AKo."Gd|WkZ<.S{ lܝ_9[$yCmI2>۟Yij2Y_20y}I8"~k;ͳ  4VOwΤo'z>\͉! LfIFعՁ/<%QSٍI^=ُ(3vEnWM⵽"D _1*iԼ>+1S+/5+#ިVOg+_&7z3e0"007y8*)Vs_CU4Qu@YXtӭmXF5/= ox=;rz) R88_멕ʆ?}'THJ^好!zAEյYf.ǡaMcek[x(ɄfW[>u}mX%ڷtR,_Nz,cY-nVJj&,˘8^T0O$~L:[M5}l+ 䲥Uiv bCki_{L'4s92#S{[hzVJL 1 Y1xDӝ {W{B?\emO .{èŖ+ {[~ǠH&t<ٙ е҉:s4w6bR[t"#FJJ-+؂ϛ-ܞu_ r%Z]=R9qBQ.tRKo3r g*.I_&,q-;.u7N.wZ,@I1-8ozt=-067}JJv@N&.S'11c.I遟QH_+ #츕f Y',bt}pcDc0]}[Ͱ[{t6c֣;e.zF;-N4O^}5aui/N_XLuY Weu'=i(-W'T :Ê䜌@Y0l5=o{Ri_DuzJ=}jj ?[5E0a\(rZ!~B]ݮIb;6HHVeyʃs7{puF IMkwWz67@I9<մp?UR BWsw;qޕ娔m x0iMN[-'BE|T6aP&(L>~s(,UiԂ%/׫Do@'m eaB/kU颴3;ҐY_.w9ctyCo3M(X K̔{wGrem]jE~v;:*}=7/* ^1ļu=u00ud6 ѻ?gj4{t>Z6]wo]V], JlL-fkNT"q>}-Q71Ryuʱ= 6oe) .XznHcƝMܒȀ*N6m<쿙龜h4=\XchXZdo?l}v(O#C]@T~Ij]/JktJL3p\*njGJVe% 5svS^/^v*m(?".?u36T0* sHmo1iֳk:XL:mkOT:fe|&ی?+p^L D\ry2n7xx 4S|e 2GY &('YϗL'\EA:%JAe(^fƆjN=矿zҹ5L7Ln' \ {krT/Z)rPf ,vb{'G)W$yU ] ՖL&'k>p'&2pmP 7߷*7Tx+ev5d=-f.+)Y7&lԅv z43ܺrXGo7i/E$VfHX'O!-{B+͚-E9qz \88ܾSؘF,d&Ł#ZK'Zp%{e䇑e읡D4>֟?'v`H SzQ?.djyW < R26/wX%e & +˽1KBZ}`G^px*ō$.=^%jxo÷3RrvHfsvuž p#`׭Z8uA=|xAy.W^K'r52˷GypU@ly (D{f*k#:6*З~8qR[Y~tA;ǚwO3"1e wDf3Z9$ {v#! Gߓe,\4x%3}+';vFJQ cߊgƕR$;RJwg>Mtmdd^rJ##:J~#9,y{Lmli5l8ъ 2_ݚG2uIbk\: Ãa$؁-.7>V[F  RQYu^sMۖBa~Skke.Y\^p<6MtxfU'\Uq%hPS.Ek×Tg|S[x* Tv65Uq_mh=3+핶 -|Q5" zS3I $?~PĆ֊dvFF+KLT1g)\lT+v\`_%T{Dpp"'" ^bD%ђ:1=KUGk5/QKi8ZI2.h GkK'5?[o8~#:|S@P%NbR؈WZZqp)v9LG;wq&WhWYHfb1P񇡰ظQe S82<}7tMySQ l 8HНs \7VϙIkJDF^dlOK$rxgΆ ve<:tz)E 4x Q>iy\Y*۞qϡ&oZiQQF!_`Cqj)Oyހ{R%@NGڄD)r0#juЍnqxJ WܑK7O] cK[Ilb5^]xJHWQ% =h,{U šn l8pDēT+ۼeP#Gؽא&,Ǭ%߽SPF\+(Qmnu|m in3ˋ7ZRz^ wZ-+fO JVK܅Q^n-C47)v?PӫMcJj_u6ˍ_]짚l\P/ِz)JF \Ђȥot}V%/K{NK * ܓd.{ʝDY}!=Jk,$\eD{J`r xX ^tm:gyj2Ό'q -Sse)ÂM}1Jbx CzXnK 0ے %yɓN3gEq.rTt2ގA>Ͱ5jx#ls&š>7N4H GbQʕCٰˆ3Opc+#Ǣi $1^Ɩnv)-%Zt3URcgnstzW  NN4}WHn~֒8^c3D'x7V"PZm)mīDq?[O;'%.D:j o^dAm8=e+f. UbCg)Q?E]6SPGqk/s:⦆ffЛҠx G͚ȟѱAް^XZ0JⲔڐihI.[ffǞn'\xiks˚ҙ\?6+OW@r{fh5t?PKZHA>tF2fZ+Cn 9/Cq}J޶xWfQ7I(s*Jq~oo1.ib 16]Qb݃3 ^Z^SĶqI1窲mSzvǨF}>1lAo=Ɖ1ݷ"ΔU\,>I%BE= ~І까o(uƱ;3BZ%َeH,O᣽cZab1ЃŶ M︒kjV`)˞GnU>I%Fow3J 0 :5;~O!&1Pv6%`M q i a Y`hB0Un4 H̔=Qhߟrn`( ɭ Q$&d{x:l6 bEKiPXh4 6YZBWv@-줻F SƙW\AM 􂊎 %d x3!9u^I{l*h2_QSS }l=>,yL febզJ7u䪞{M6r ت > stream xڭwct$ܶm͊:mv*۶;ض{wwTk5k"'VT27۹13r-m]md锁R.F6O \ hbio'jhM@33  bdinTS֠+c"Ζv?܀6@;O p,mE-)y @ht,B kisR68LL-*͙K`pvX~=LAo3.K;Wӿ OLUQTyX؛}47qOOp+1`j`c4\-- hndjtv;_7rp[3ƌ3glsK;8E?17 kf>02]>C(g* +GZFsgk௅ciZxw~[3TfKgqKyLN6vO#a&vhg5|w RbJ4ͶTz:IC?Q {عt9r1~_g9#'K#=##F9Rq134:9}*64[Y7 JLwf v(ZTWmUiZL0p/M}0܍iCѕp0_ tܽ7R)ؙmB aG: i;n{(@#TK#'mD{a:,ыy^zʹ|P俘BmTY~ҌL VxgON- pFJ] QDV5Ԋty5bʑwsG=qq3Z^Y[CKmjdU2Ux5t`WL.~e & B"zZ4|՞qcd9\CQnnT O^A= %䋃äՑ*}#l)QdFۋDR{>=6\I5 '",QP ),y8q9q#0F7gT~raVarXF .2UW!v!_>lGivho sBR"2j'(8jw~fj Vϲ L=ƻj⛔`QB &ٔɀVsnK^+c l?Mg:]*DDk98NH{bEi u$~~N5Lub4rne"pl[vS6'=PUSٛ@RM":U""UjҰy ͻ'E [ϣTH&~dRY+>F}nr.?Z=1} Nf 7K缊Vgi=B5Fn 3ȵ, of4v0lU%iGHϕZeh9(&ƶ)3!/9Bm2Cg 6qwHقD'yxN6HrokHl wxՏqɔK1~k ( _q5ʧIܮM l?YrL[j`Șb4W=0NHTGlqv vjt>%m+Ryɢ`Tvi?3aI 5M|+RhkIyREW'ƳRԌe+XU#XXg:/+4o2 ]JS3gK͙o"?;R% |k1^ Evgjh?DD) Ƥ$P¯ait7;wȒ39?| -Yol 7;*CwNHɦ$vㇽ#yN X AhF8!)яÝ&Ί8Ƣ⇘t[ɉ\bRh 3ix~pсUp̆nԇH!NI}`Eޯ3ߢPIfh'VJh 04*;nb1 VApi#^}s74sJiGeqixu `\Y/QdА% ֖ B4"ӼqRٓ/0/= ;5.$lNG9(?fD0FВ[v&ƮH6hܱ]@7z_#p62ZQSkJshPeҮK3[j`q[tV 5W,:M`a n]o r c 84njvĚO3}wdA9Yfbt57`hoX+uQcel1p 9% XSc J '|Y:_N `R}ˍwH9cTp hǟ$]u}fHP 'b%vf%vPf$jK0_¶YU'`UiP2쯌#?@2԰1 )|?:ɝR&aM[Z0EejD:)R֯FYN- @&MAXy_ X8>wԻtݬ'ύAϦ=&>B3E#Bhc+(^UL:SwA~uifNK-̱:" LRz0I{hB:rSup[{kNgOl{ KEC1rq1գ,"=.(n=ƟH!R5 fq/s 9#~ w,_ftMs~˲Nޜ781M14 !eDH2 \:MUDEMcgN' K֩gqkʮZSU,OCHwM 0m/UأҠбZNӟ_0b7U{ l5U#w &Hj$l&#oAgV|^w<ЌKj𨏲ey=AprT]|Mi81YŅp.OD|;s!-;}ݒh2%-ʬ1 fj~g\2ji!V֦vWhomEͽ?'=7ɤ- Z 6;qa5+aV=ꡫ>q+IrZ=R%|pY>reK}5p6NY t%s qٽ_.IWռ;b_Pb2ʘ 6$ce e,^`l<*1Fcv'AS6HB^qLe]پftw}4@qmz5ng?G$+ix;,ńW~PPzQ}v\Pۗ1rXk~Bdcj܍u?)%+&m,f{*)UF!CnnY"now͈Rx46OPbΈ5}ͷA G&6%?bw8O|t**ks\HZ2 ?Et~(łZA.OVl%X^ FIrexx%&$Hx5D5s(qE{7\We`ш5z9,AtH'ID;a+86>Uxt|vo4mp4͸w%b[FiJ&[k _%8Md A$U*ЬV/=|hR)%;&XM|JѫT{pu~SRpƘ^z tEpU*fKZHhJ֙u#"`uj)6FN{'cIXd٩̏ݪ}fz(3%rCW]7/5=mpE 0p@箘xQ#~[HK#&"32x^f^:d*/dr(v8+Bbj ^1^rM22lk.5ީVi}Szirҍ/|z@5?ٝF(?nj c2.ф>^NKXl7c`/*wsc$#jɞ8LkvM?6 LCSLgN8%E'(]"֭H ,$x$G^J⇤Ɲub gm,7PKP{9\X@?ccN"`U!iޅm:7u sEļ3"mgsZKVkt߄J1E 5<mkc! NLz 7ޑֽ9_ҽnȤoՍjb$hqY I{f3">!O}Klݒ6vjaOtP%}7B*ۏ⦼* e᭭*C9g fjBKo%By08rCYمYͼ. .9uH ɋTWeX,5R֟`}g*Ä72Mw j(k++ _ɪ}$&8z7>d^ҫޱ]$RSd _j`v! uT pepVJgOտ"\ҹL`k60_u A5)J|yxDfM p }Swk904ls@y9V)旊'M30y_ JSgijqTY{5*GǙ(/ZyT XцX T&i-L'p^y,DYh 'oxX O<.k__'/F2ɾbyc=T|w?tuTd56*ǁx'oyW8kOǘUoM)f-,FeQw/Cm>./;E9Wt,]u#\ }Bem M6) rl (!:J_.0qHET}<(Ҋ#VZSbq7 eۡ`ҝ:]pdYhT abᏛ"Ko~0 %6jԓkdK΍{|,_jIωgp{z'@Hp%v ӂ{C wx8TA~ 3{4aysxMU?L(VhG=GԏfbD?0{(ڋKsܐdGÇ(R{!^OW44@ԎxFCxYdw$PIöջJ<.4֖dIftNj`X"WYJ`)v~o<~Ny>BR OfKO=:?QiВ첋#!܀/HØéqpxᱛM$|a!XbTJI6,fEYD(؏x청3Ў~w&P)˜  Gc-eri#&Ri% !VC;?* |Q_AiVn4Yi*mxbIw7OϾ@24+iZ3xhK=1Q:r1~E6$/$<Ί\~HVmcb +BLhv\c3qaUdqb brnλ(;/z4%)ϙ&#{c^hr#rOl /{-ݶ&1`&Ŋ1ox+c2-*aoGiᲯp~h0fy8<ק \q)rU/|P\SNΛr k y6H=6PW$] =0mNdօnc2vY4+8Qb̞5'cr:J΢io@'j䭘Oʁ?0҇^nRfҾMo]ueBS:͛9(Âe6w'X5"iQ'- 52zMVg*leN9Q`~4P6} )lk<&s4nnh,ңd;؋Eu^i˯6, &.H8嚸vL<~±ߓK<ͺ`4}?@K2;>No_| ".V'c#<|p|>&cN(G)+ Dwދ*#Ki[%b -VWx B 9r.%6\v0ЀbJB`5 n*޿p%*a5s<_$auiNS"j]0w7 *fЮx?7 uqlކgAeSL<!5n3ʁ "A/lQ>f\<fDعTwjRbʢfl׈{4i:Z_T\ErNzr6uF1u6Wee\ bKn,~_w x? $@1BR0nxA\zUɚzl؅I٧qXHbv %1Ae}7Mެ0|HUprė:butπ~67M/Z^m.>jL)IMm~ʖ+Q˱iR_>g/ԃqZ98'YEPHVՎ6Rv;?IRU1\Q} B[:G%R+ m4T[/h]?ٙǥ|8 )=U#NfxJ[tr>3_b^SX9z,}T<p:1j}ٺ;EN/2:4Trm`˪mgjD- A Y;R9mœ'o4ٻOm)4_djl>Y@#߃cqWjĥzV)xp_M61t\IYts*WaOML\,{8>߱ʸ[h&ͪu3n$ݐrX6`ĈE( GHsJE&IPN)t䷢/d P]b-NJ۳"gi֢1L}5Cw LgŦ@F3hF9v&B1dK@lj+vH#ΆAh-¯4\Ȱ@\΋t53-2up9K$s !u$д[ot1iT?zEfhL黱NEě3qҟ8_f4=sa+D_\ߘ̈edx.pqUu\+XJ.233sOxuU1DjzTj?6xVǾzDqOggp d#Jc i/E9?-C˜Upof98$}ۺVw|UP{L>WV!Gi J*0 ߚodO0o$5>g !hR߇z'.n38Bl.DYWVO{[Sx:6^aP~Ũ0b⮟b|lG*пGI"H~\P .s&cRԱ P>pksJ^F ]Hqm(@r Z7:M Vc*⁎7L׏%>?wSzPajT!(y[FbonQ;qaT] Uϫv[6桕Ï0E@0Ƕ{.C`hUFE^glؑ&ETJsU4=tܺ_A~lEnاZ.Hp[@0?uq7>! ՐKla mߟB&Rn@^n B&uѺ(//P6U%QٖD`ӏǥF&[3[D8EeOX{IA+Ua+$TW:ZBWKR0涀CFͅ[ Ȥ$aòQhd%|d./].侾A*%muΩu%"F\t8-B9pѴps@Fc!$sk!~)LD<~e_1̎y45ҮvY$X)~KVrdȄ9'Ar^ZZf6(n= >I#nN@_m e)cZ"W|9UtiXwc \FfJXkDrDLӉ^EER?+c'gFyC_ @}αjLn)Pt/ */ߡQz",x˶;Cˬѽ1ZpY;#V~&~8EFhTrU4w{(XA~b*'{n7 i",Fm!ݩ#jva#ܬD@΍\1A\ˆCOV= 4fBW-ƍyeu|3b("X&{Wb,l XaW_M'mvӤ2z:c=]ʸGJrZB!y7sƝ:`G)nB>Kߪbt* Tv7iMW]7maHpt}U!|+'q>#3ɿR<}!֫T,CB}?da .iPz b4Fr-X i u73Ct'P!!+Elk+}s¤{.C=i&mw5h|LZ `DJfYGIr ^.kin+&GU;S Bk~?oKf{dⴲή·~+4dK#y9~|vJaٽ.aژ :,E[׏*D((,y Cll bDyjtg9"a6 lAa&rC;:t^xr hAē~tmlRRVloEvCc%~/ɖ $[ș$%5 $j/͋̓k9#Z@lka or6V(Y)" vh 'T~c+_wf }<&-`P-a7Vk#qJVC>T`r00O `t= ң bSwz@anP;̇`قM h#9 xXL޻M)[\qy'9cR⟶C*Vh=b`vlR3k/µxWXk"‹'2^ɨM-3ėWw4z˔Tʏ=Rm*xyFe5LVce-HШ3<³c ;v }z {辫;iŔAhMQ7tH"=vk"{ҚqEjVCy)Z 4> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 701 0 obj << /Length 739 /Filter /FlateDecode >> stream xmUMo0WxvHUdCmU^!1H#x?gx]OTm$|͜s_Iss :L;<Sz==׾f`*_`ɫڟk3'iѴ}=M;7rfnj-eSӵOLg~8 )ok A8 $`I\3`Af<Z]! xNky"7 _㓧q H`nḱRONH=CpB:# =%888QA~!*zƜАT?!~> tw8y*sύ }nFE>7*QύR>7G];~<6OIyktg>O:yұϓN|I/|yIg>O:y҅ϓ.}2 L> stream xmUMo0WxvHB!qض*jn$HP#x?gxLT$|+$=wwY[L5Okˍ}M=ٝP7{=,yfܢ_ybsn yS6`z¦}TEA] $rwyś~0uoMd?tNC0}*f6` `bێh[W0ƂtmeӶ4ݶ0[*0M\B+vX*+T*Xb-L s[ #*X,caq\``2Iш P]QA2E;XXJKC k88pLB$qƩ/088?rxy!B=X y82VAנp"Zqx8t9MD/W)u8|}ۆ~)30|SRHCOt$"NN_h 1'>4$OOB:]*N:qJ(sB5Qύ}nTsύ(Q<6O͓yk'<ϓ|t'=y '|yҩϓ|t <)>Ozg~x^uEtϭ{ՍȧU" t endstream endobj 703 0 obj << /Length 740 /Filter /FlateDecode >> stream xmUMo0WxvHB!qض*jn$HP#x?gxLT$|+$=wwY[L5Okˍ}M=4$OOB:]*N:qJ(sB5Qύ}nTsύ(Q<6O͓yk'<ϓ|t'=y '|yҩϓ|t <)>Ozg~x^uEtϭ{ՍȧU"  endstream endobj 704 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 705 0 obj << /Length 851 /Filter /FlateDecode >> stream x}Un0+CW`$ MEDbɐCuA6ّD^}{l;~\N=Cu.7զOu½t}5sM7dz0;nMfMK-ٖ?xN[E_EzIVCH޾&w!X.ouc׿z|<:Q:XTߙOoGBZ ;ww ZԲWcv+>7+>S} ~!>_Sϔ+>cB|&LOr`B,&+jwRP{xᇣI^U E'b\!'}sG =C:wWq8"~t]Q|" endstream endobj 706 0 obj << /Length 851 /Filter /FlateDecode >> stream x}Un0+CW`$ MEDbɐCuA6ّD^}{l?YtգиY}w 9]7puewSClݤMӍ'oܺ sR^}5s8dz8'7&3Hy:LK-ٖ?0N[l "N/rDz=49z}'wt>X.oFzoкнz|::Q:XTߙOo'BZO KWjY׫u{FRsuB`ilB =@ )U 9yI(ѥ S*043``]߻A 𭑦 btX& #q,pg'~ι58|%Nb'QDa 8g"h~ ' ~Xkzǚ_81Bx.BzҬÀhƘ'g 2xk=6u2,bق6E0F,eL燆LY` YecODV3Μ蛳;zr֟P.O0{S3ux9(uF: }6,V|ƌV|gegV|F_+>O+>G|V|~+>C1 V|B|FB|/g)g1{!>_|&~'a9i0K!cB{XTK5;)NŽbPq<${y儢 19螡SsWѩ?!~t]QiT endstream endobj 707 0 obj << /Length 851 /Filter /FlateDecode >> stream x}Un0+CW`$ MEDbɐCUA6ّD^}{l?Ytգ;q\]U}s9n\i|ٺQ]jOtusR^}5s89Ηfi<WOlKQn8N[-#;skQ70j(+o!$oΣ;n},j7Fzoкнzr::Q:XTߙOo'BZ;vv݋ ZԲW<'suB`ilB =@ )U 9yI(ѥ S*043``MSin|kiCXc, pDˆzA:x0)ljsn l9u}SrI4"nXCA8%&ٵ6AIǚc:7^EHOupQF^odž1BЖEQ?[0^׆ƨАԗ0 9+ãbLi~jЙ}s~zrCOe fYJ|֟uМ8gΈrYφ}ŊϘъ1LҊkgigϘ݊og3f3|3ߊY[3 =L3f/gd ,' f)Rx jb&'W *~8d0UPt" ~7a3t> stream x}Un0+CW`$ MEDbɐCUA6ّD^}{l?Ytգ;q\]U}s9n\i|ٺQ]jOtusR^}5s8dz8;_Nnft_= [-E~|;en>ڲ?bs0qj>vzЌBRe]*q8cMC0c F F 14Ej~1F60aG+ıcW c rn q9Qܗ8% DMq.5Sh]`4$a]~9Vk?qc.\Y7ь1O*ezl,d mY50ymȋ,aYʘ8 xA} /Y1<*T71މf 97g19w(g1?\֟`g Yg 9LsQ.(ulgYˊx/V|V|&٭ V|N+>cv+>7+>S} ~!>_Sϔ+>cB|&LOr`B,&+jwRP{xᇣI^U E'b\!'}s =C:CޯSBQY endstream endobj 709 0 obj << /Length 851 /Filter /FlateDecode >> stream x}Un0+CW`$ MEDbɐCUA6ّD^}{l?Ytգ;q\]U}s9n\i|ٺQ]jOtusR^}5s8PYs/'7F3Hy:K-ٖ?p>ݝ2ZkXwm1985];B U{hFYs!yvq`TGy7{ E]&AjZu/?vG_L|z;9ڰƦokܰ^\zu \g$y?qמk(_KdR$| 4hd52HHNsL F.8XV`TR!fn"_LS5w[#McL#F X1+N978Nsk`q KpN8q )q4ϮEp O.?5Yş81Bx.BzҬÀhƘ'g 2xk=6u2,bق6E0F,eL燆LY` YecODV3Μ蛳;zr֟P.O0{S3ux9(uF: }6,V|ƌV|gegV|F_+>O+>G|V|~+>C1 V|B|FB|/g)g1{!>_|&~'a9i0K!cB{XTK5;)NŽbPq<${y儢 1 螡SsWѩ?!~tM(Vu endstream endobj 710 0 obj << /Length 851 /Filter /FlateDecode >> stream x}Un0+CW`$ MEDbɐCUA6ّD^}{l?Ytգ;q\]U}s9n\i|ٺQ]jOtusR^}5s8BϚ|9a6Fa|/Xo϶Zk\ĩ$wAg LC3ʊw۷莛n˥?8ޛ`~?n8t/3NbV+պ};:5bwɩֆ56}Χ]]₥+U=#)\]PG*X$D F @F@k} 89@FJuFF#`R0Jt 5 5553G|F/+>㽴3Z~Z83f3[:٭ ߬Lg3t33 ~!>CO!>S 33>IY ?BXIAup*Çq&#{U-'H8qe%@ 8{N Y;lF?h; endstream endobj 711 0 obj << /Length 851 /Filter /FlateDecode >> stream x}Un0CƆ"Rjn"BD73o`_|nxZNcg!w㍺O겺otȷ}z9/>vⅵv?;~Mf^ [-E~e!jcc4qj~( 3F&VݮdE>8ǷvK5i|#Wn_gt8zQ:ZT緡nfߙOobZ?67ZԲiV^:} ?L; N|N|oN|3;:K}KR|)W|L|Or`R,&+jwRR{xI^ E'b\!'}{p =C:]߯p@;_X5w| endstream endobj 712 0 obj << /Length 1022 /Filter /FlateDecode >> stream xmVMo8Wh҃kTHrضh^I IJ!ۇf|tǙqV}xܟ>ڿ7]Ocp{Vc> stream xmTMk0WhFG*! miʲVZCcYy#9톅ļ{3񼛤es^7箰 nn8l=hzI-._뫦~^JIu]f `tTsr*o8{&X,dew+mWos~X(2X.EiTz}ܟ^7uY~lVNMєo R.bY.֔O9؄b%9vsr(MXa#D$ar bqMDs!FKRLDP0.BEHQ#͸FuŎ577v}QȕanOd$g;A,əCR;6+ѧx**Ę$90q'oקfQ%n;5pX2]$^q~+s"F!CyhIh~CMnOf1$#h)r~hмj5F̹k#ni<7>Tsa>s\8s&wsaY1:+r1\ut[ZM,k4w6_%aJ endstream endobj 714 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTMk0WhFG*! miʲVZCcYy#9햅ļ{3񸟤e&Oo]&C]]Mq>zwt߉Ǯ)n.pCx?nڽVgx=itO"i [\l\WM}'ԭ̚t4pXeȉeU oq yM\-CnCW_Ey}wP dZz891euB)] W-\v\]~[S!8&+Zce"'2Ɍ5I@|"B2AQhSlLء28a}ɑFq5ҍnnbfǮCG= Wܢe$g;A,:sx l=NOTƘ$0_س/vЧQ%~Zx pX2]$^qnaK??q FqMyc0=) &l(mi,3|d &\c ]͹&ӈ9w{d-tx\ \cΜekqLJs?<@>qhx .׷8wl~1V<*m"mmDa endstream endobj 715 0 obj << /Length 990 /Filter /FlateDecode >> stream xmVnH+AMyثL,R~(r]]n7W~c7߽p}z\[{%8OeWϝ\'}oe<]8m|kq7,r[|UJ;P)ڮ:U8 *&~(Ia7~x;~z. OM~?/,x72 .OC+B89 :u m#)u:f 6FyY\g_BSfeMsbWe\@HhBcyI'_yPkf6SG8r5mmh-aEB)8d-89-9I_خZbو XXќaO ; v+[`SJ/Yr5N1C=5küFlXEs9䪘˂Zs2֕YQiˡZDebg\hG|U.v}@.-zFeeuMyuC5jM{ _)p5/b͚&8ЬySrߐH^-}P*`,}𝒞[m؉ lShreo-ȞURoZQl~~)ra ;4zj8QUG= > stream xmTMo0WxvB+8l[jWHL7RI;onDo3ތ?n~<&Y$ŝK_IsE77E[^N\5sߖ;7|[lzmS_*7F?h3΃;mc-bB`ew\_7oK׽;(2Z.ETz}ܟ~o9V^MVK7-\f\S}[S!pcSs|TXo1/ȡ aeuC> stream xmTMo0WxvB+8l[+ML7RI;onDo3ތ?n~<&YվI|/ŋ;t硋nn\3<:Wj\=?-wn6pGۦ|Tnʽgxté7~qzxKlqrnX7UޞMjuSAxHiQ,'wͱ 1}hW7q{UEݥ-rG*F>NNL7u]tNhWS;wE )b,#TTHy=)9>*QKr7P:MȡQ^s$LD6aȑ*s.$S56`>ƄmÁ#TL 5kd}WXssc*zRh/#? bE$L|ږ8^y>eSQc̯bV̯cNa'_OAJ195kd3EH@8ܰ%~As*=F 0`{RLPh33Y$LƹǬ oqMsȼ tx\ \cΜ-eksL ?"@>qhx ׷=l~1֍>*]!MBa endstream endobj 718 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=c_~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGM@c endstream endobj 719 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=cߚ~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGMc endstream endobj 637 0 obj << /Type /ObjStm /N 100 /First 943 /Length 4745 /Filter /FlateDecode >> stream x\[sH~ǝ~ڪH !0-'w;c;30~n-2EV/-ŚQBf0 g*h518>Q8˜=)ġ !60w3"Y M8!+lc plO ) BHBn$$hA8.T 2x7 =" e,Phi2)dH *""RgBjcRH! f)(fD%P B\dX pWVH>"`~R&gA;쓭 iUQZP.@%A;f]>& yD-@ܛ#;3+1B!Ө KVfJD3a)Db3D*1q9 rp+ܓ=& 6sc:0Ck2aE.2j}ViA.0c.sfU|LӺ Qa4´, 0̻CDFҮ&)Y J "Lpc$! 6d1 rVXzZ!]>s(+BH0琸ͪZЂȧ$GX@e Vzp~0}jʀm!pDW7F OsO>,py{[ x_H~O˜/ә!?O .e qeYP8+ |pƾpC=M%NKL~fqND(3)szzY,9 c@p2 Y gE)Ax=x2F8Qa1Pc\ڤЍ{<i|;>&79o~PхtXT+LjW1ʣLuΌ&YrEMxqM92z g AZxVy&?܀DyB:2}KIGzSgƁ(J Œp8ԹvHa%<t'0Zed9@r\J?Ұ~ƥeQzm"mK8 (n1#??<`ak 3*%_a~N ܡ[9QXxx)3xxB6CҶϥtuaҕ\ KNJFaľ5Pqr x3>ZjE23C>i-p֣G-qcI),G -)ȕǗns:LXD2}/Ο 1տXoJ/KK·56~좿{E\%%֔X\xӣĜg<<})%$K>0a*JgJنbkdEVA7 a۬QH N32;( L-IJ^^r RTLE] &mI%*,LT<#5|@)&oq/A0H0j+֢zԵma UQRU@ؿUP(d 5r*$E\:Tp`U«Z6 և@4ލKWu%ZdV:6DͣTţ\G)Fz a)\\v'YƉ&H"?%^1ixzpO_8=~{||(< nfDϞMoJ/fWx^;?(7s\r=ep> v7j?/΁^! )W~5t8g6Oa aDѼN y}wf5z*Sdajtp{1e3< F`ZC_Z;߄ݏ_}n"wgo_w;dS[_sT<BbJ_!!n2^^j6CקOg:\F_Zc5myU;ڄo:o FS]5_I~wGn:/̆s|OɸHd^\_i>ț5/un}> 0 X_GVmeH|7˟^H_o@o`@`v5"f<܅|8.*s=RM8QVhp<8y&oC;rwt6I$j&!%oK-Ǭgş0l̄(&5;NꖴQ98e.oT%a,i Z#G)TV ~_}]ApY᫣㣠kލD 5txtE4I(9< J+sBԮNQ|Ç\ZXr?oώ_yzxw0GOMF (0 euv31))Ipuw桋3W7iZE%auX3U c\C+؃3xwC] ϋ|0L_1gӦ˖qMG.Yb̊6&0]Y`b5S֘s%o|}:{=qGOacqGo`A.P8GS4K5 Ba^xSX!16Ҧ$FC偲!Ŵ g":ϏNYᐨnK/ף~pk#я(k8TeΥrTNg^s0jr5Ls|UDOKmadw ~ݰ+y֐{/;ދ{o-+a8 `q;ęF?OJ8@@0D !\(|ZK9m$5XeZ {a5%-KwUȑ$+v Nld6rԆ/``Vj! |8\ #GxvO7=Я bhG淊&=EMAQmz4_4 RMLb.(RMߜ˚&EEI)ķmS$6IkRDk &HnaD7 LێTMmjA Eڜ}ʖqqDrf*T7țT N~\JS6_To2CݜaJ[]s^.[J]6T8kɶ-&jm":VɶMli[67Ms)OTx6j)<ڴnU:2ܴE֞\f<Shm7v֚<%V D:&hj'׬C[;M*k]uH"_$ܴ-:/ Q'bw'=҃ix;ejx OP0\C`n;<$G8c~6!<Vs=`)\E)Pt9W~D_&^m>sȐ_5> endobj 724 0 obj << /Type /ObjStm /N 79 /First 675 /Length 3264 /Filter /FlateDecode >> stream xڕZݏ bIDRa` iA."=u!g4}YR$)ͮlLc5u7z4¶؀ҭk /w /_ЇmP }XCuI_!TtbNrqG:5/:6҈ԛV59qpd/Yb(w&j[0t1 )b@ h;;]J%,&N,i.'tR$ !il;6$}Ri0Wkq}I5Esܞ6I?`%gq4Է .lR廊smM0=琉%j v?} qRMɜUEscg:`h 7`~k Z?$\_TI=PBMWD}W2pN6(<,28^|)p\jYb+ l 2r5E +(c+ XGU^"f:5)#Z&c})Nᅒ;蜌q8 ε}$n^7 UUO׵r>w/*oaNy(ZHDY@B}ࢉ8Om7͋;-J_ti",$/i5UIiBٷ bhm rxQ$>u(2GA#d9@nZ*w.Ytxm-sTP}Uzx>}R/1n+Q2h73Q/H2W,v/TUb(^W,ܒ"wj ]W!JhVvz\P?O/'*uLXRw'YbXMu- \zUJߟwϧgX|rL? <$鶤Q6C|;z)4TLYoM0EW+t+N SPz 3zi,M78brJᒢn(zOsoiKXVUWeN@ц`ԁ%E/i=fzLuUhxt]o>yfU2|9uJݱVvwc|pΞ-V1Ўf&`df2Vþ(lW_C\`B- 7F%(qT^^N e*n?vJ'KV'֝#s,^<, l3쉲rW/_ʒ*<1?-ѦX3_m%μ`4Sxn-ނŇZ{奮"fZQv,muJ[a:Ben9g!pjT*KO?ˠޱc1b!{}0 <45922D68FCC87C00835492A052CD5F85>] /Length 1887 /Filter /FlateDecode >> stream x%Yh^;ߖǶ]ErK:Ym&˛H-MBHo M!!ZhawڋPYN(6ؔRL& y49ϙs=ɜ˜E?+ԟhA3mfZ*h618F BhփEhgњzzK*: m1ZrhMLWh[0]VmE[T Mht:h+ꁚѮe6陗3F;dq!M؊ 4V mR4mN MeAZtY:){^4Œhe](z7"}hd~06KA0}H9òQM{%@2{vhaejToҨL{h4k?heّQ-N2F/4FV=%Vy0!}gK|_^%7G%~?*%?'J|zĿ)^/Ql`} 7qg{_#///B};VtբЇtd>[>VzXL$bA"$bA"$bRlHB3$b/R XXXLZy܃s"K endstream endobj startxref 405214 %%EOF utils-0.86/doc/gaplog.css000644 000765 000024 00000002277 14621444241 020455 0ustar00christopherwensleystaff000000 000000 /* ####################################################################### */ /* ## ## */ /* ## gaplog.css GAP *.log - File Style Stefan Kohl ## */ /* ## ## */ /* ####################################################################### */ body { background: #FFFFFF; color: #000000; margin-top: 5mm; margin-bottom: 5mm; margin-left: 5mm; margin-right: 5mm; font-family: Helvetica,Verdana,Arial,sans-serif; } pre.logfile { font-family: "Courier New",Courier,monospace; font-size: 100%; } em.prompt { font-size: 100%; font-style: normal; color: #FF0000; } em.input { font-size: 100%; font-style: normal; color: #0000FF; } em.output { font-size: 100%; font-style: normal; color: #284D49; } a:link { color: #0000AE; text-decoration: none; } a:visited { color: #0000AE; text-decoration: none; } a:active { color: #000000; text-decoration: none; } /* ####################################################################### */ utils-0.86/doc/obsolete.xml000644 000765 000024 00000007627 14621444241 021034 0ustar00christopherwensleystaff000000 000000 Obsolete functions

Operations from AutoDoc The file functions FindMatchingFiles FindMatchingFiles and CreateDirIfMissing CreateDirIfMissing were copied from package AutoDoc where they are named AutoDoc_FindMatchingFiles and AutoDoc_CreateDirIfMissing.

The string function StringDotSuffix StringDotSuffix was also copied from package AutoDoc, where it is named AUTODOC_GetSuffix. GetSuffix

The function SetIfMissing SetIfMissing was also transferred from package AutoDoc, where it is called AUTODOC_SetIfMissing. It writes into a record provided the position is not yet bound.

As from version 0.61, all these functions became obsolete in Utils, but continue to be defined in AutoDoc.

Functions for printing The function PrintOneItemPerLine PrintOneItemPerLine was used to prints lists vertically, rather than horizontally. Since a very similar result may be achieved using the &GAP; library functions Perform and Display, this function became obsolete in version 0.61.

s3 := SymmetricGroup( 3 );; gap> L := KnownPropertiesOfObject( GeneratorsOfGroup( s3 ) );; gap> Perform( L, Display ); IsFinite IsSmallList IsGeneratorsOfMagmaWithInverses IsGeneratorsOfSemigroup IsSubsetLocallyFiniteGroup gap> Perform( s3, Display ); () (2,3) (1,3) (1,3,2) (1,2,3) (1,2) ]]>

Other obsolete functions Applicable Methods The function PrintApplicableMethod PrintApplicableMethod, which was included in versions from 0.41 to 0.58, has been removed since it was considered superfluous. The example shows how to print out a function.

ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 1, 1 ); #I Searching Method for IsCyclic with 1 arguments: #I Total: 7 entries #I Method 4: ``IsCyclic'' at /Applications/gap/gap4r9/lib/grp.gi:30 , value: 36 function( G ) ... end gap> Print( last ); function ( G ) if Length( GeneratorsOfGroup( G ) ) = 1 then return true; else TryNextMethod(); fi; return; end gap> ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 0, 3 ); function( <1 unnamed arguments> ) ... end gap> Print( last ); function ( <> ) <> end ]]> ExponentOfPrime The function ExponentOfPrime ExponentOfPrime was originally transferred from package &RCWA;. The command ExponentOfPrime(n,p) returned the exponent of the prime p in the prime factorization of n.

Since the &GAP; function PValuation produces the same results, and does so more quickly, this function has been made obsolete.

utils-0.86/doc/times.css000644 000765 000024 00000000261 14621610515 020313 0ustar00christopherwensleystaff000000 000000 /* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { font-family: Times,Times New Roman,serif; } utils-0.86/doc/utils.xml000644 000765 000024 00000001257 14621610512 020345 0ustar00christopherwensleystaff000000 000000 ] > <#Include SYSTEM "title.xml"> <#Include SYSTEM "intro.xml"> <#Include SYSTEM "print.xml"> <#Include SYSTEM "lists.xml"> <#Include SYSTEM "number.xml"> <#Include SYSTEM "groups.xml"> <#Include SYSTEM "matrix.xml"> <#Include SYSTEM "iterator.xml"> <#Include SYSTEM "record.xml"> <#Include SYSTEM "download.xml"> <#Include SYSTEM "others.xml"> <#Include SYSTEM "obsolete.xml"> <#Include SYSTEM "transfer.xml"> utils-0.86/doc/toggless.css000644 000765 000024 00000001672 14621610515 021030 0ustar00christopherwensleystaff000000 000000 /* toggless.css Frank Lübeck */ /* Using javascript we change all div.ContSect to div.ContSectOpen or div.ContSectClosed. This way the config for div.ContSect in manual.css is no longer relevant. Here we add the CSS for the new elements. */ /* This layout is based on an idea by Burkhard Höfling. */ div.ContSectClosed { text-align: left; margin-left: 1em; } div.ContSectOpen { text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock { display: block; text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock a { display: block; width: 100%; margin-left: 1em; } span.tocline a:hover { display: inline; background: #eeeeee; } span.ContSS a:hover { display: inline; background: #eeeeee; } span.toctoggle { font-size: 80%; display: inline-block; width: 1.2em; } span.toctoggle:hover { background-color: #aaaaaa; } utils-0.86/doc/chap2.txt000644 000765 000024 00000005356 14621610512 020225 0ustar00christopherwensleystaff000000 000000 2 Printing Lists and Iterators 2.1 Printing selected items The functions described here print lists or objects with an iterator with one item per line, either the whole list/iterator or certain subsets:  by giving a list of positions of items to be printed, or  by specifying a first item and then a regular step. 2.1-1 PrintSelection PrintSelection( obj, first, step[, last] )  function PrintSelection( obj, list )  function This function, given three (or four) parameters, calls operations PrintSelectionFromList or PrintSelectionFromIterator which prints the first item specified, and then the item at every step. The fourth parameter is essential when the object being printed is infinite. Alternatively, given two parameters, with the second parameter a list L of positive integers, only the items at positions in L are printed.  Example   gap> L := List( [1..20], n -> n^5 );; gap> PrintSelection( L, [18..20] ); 18 : 1889568 19 : 2476099 20 : 3200000 gap> PrintSelection( L, 2, 9 );  2 : 32 11 : 161051 20 : 3200000 gap> PrintSelection( L, 2, 3, 11 ); 2 : 32 5 : 3125 8 : 32768 11 : 161051 gap> s5 := SymmetricGroup( 5 );; gap> PrintSelection( s5, [30,31,100,101] ); 30 : (1,5)(3,4) 31 : (1,5,2) 100 : (1,4,3) 101 : (1,4)(3,5) gap> PrintSelection( s5, 1, 30 ); 1 : () 31 : (1,5,2) 61 : (1,2,3) 91 : (1,3,5,2,4) gap> PrintSelection( s5, 9, 11, 43 ); 9 : (2,5,3) 20 : (2,4) 31 : (1,5,2) 42 : (1,5,2,3,4)   utils-0.86/doc/chap3.txt000644 000765 000024 00000024016 14621610512 020220 0ustar00christopherwensleystaff000000 000000 3 Lists, Sets and Strings 3.1 Functions for lists 3.1-1 DifferencesList DifferencesList( L )  function This function has been transferred from package ResClasses. It takes a list L of length n and outputs the list of length n-1 containing all the differences L[i]-L[i-1].  Example   gap> List( [1..12], n->n^3 ); [ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000, 1331, 1728 ] gap> DifferencesList( last ); [ 7, 19, 37, 61, 91, 127, 169, 217, 271, 331, 397 ] gap> DifferencesList( last ); [ 12, 18, 24, 30, 36, 42, 48, 54, 60, 66 ] gap> DifferencesList( last ); [ 6, 6, 6, 6, 6, 6, 6, 6, 6 ]   3.1-2 QuotientsList QuotientsList( L )  function FloatQuotientsList( L )  function These functions have been transferred from package ResClasses. They take a list L of length n and output the quotients L[i]/L[i-1] of consecutive entries in L. An error is returned if an entry is zero.  Example   gap> List( [0..10], n -> Factorial(n) ); [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ] gap> QuotientsList( last ); [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] gap> L := [ 1, 3, 5, -1, -3, -5 ];; gap> QuotientsList( L ); [ 3, 5/3, -1/5, 3, 5/3 ] gap> FloatQuotientsList( L ); [ 3., 1.66667, -0.2, 3., 1.66667 ] gap> QuotientsList( [ 2, 1, 0, -1, -2 ] ); [ 1/2, 0, fail, 2 ] gap> FloatQuotientsList( [1..10] ); [ 2., 1.5, 1.33333, 1.25, 1.2, 1.16667, 1.14286, 1.125, 1.11111 ] gap> Product( last ); 10.    3.1-3 SearchCycle SearchCycle( L )  operation This function has been transferred from package RCWA. SearchCycle is a tool to find likely cycles in lists. What, precisely, a cycle is, is deliberately fuzzy here, and may possibly even change. The idea is that the beginning of the list may be anything, following that the same pattern needs to be repeated several times in order to be recognized as a cycle.  Example   gap> L := [1..20];; L[1]:=13;;  gap> for i in [1..19] do  >  if IsOddInt(L[i]) then L[i+1]:=3*L[i]+1; else L[i+1]:=L[i]/2; fi; >  od;  gap> L;  [ 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4 ] gap> SearchCycle( L );  [ 1, 4, 2 ] gap> n := 1;; L := [n];; gap> for i in [1..100] do n:=(n^2+1) mod 1093; Add(L,n); od; gap> L;  [ 1, 2, 5, 26, 677, 363, 610, 481, 739, 715, 795, 272, 754, 157, 604, 848,   1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271,   211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521,   378, 795, 272, 754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272,   754, 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604,   848, 1004, 271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004,   271, 211, 802, 521, 378, 795, 272, 754, 157, 604, 848, 1004 ] gap> C := SearchCycle( L ); [ 157, 604, 848, 1004, 271, 211, 802, 521, 378, 795, 272, 754 ] gap> P := Positions( L, 157 ); [ 14, 26, 38, 50, 62, 74, 86, 98 ] gap> Length( C ); DifferencesList( P ); 12 [ 12, 12, 12, 12, 12, 12, 12 ]   3.1-4 RandomCombination RandomCombination( S, k )  operation This function has been transferred from package ResClasses. It returns a random unordered k-tuple of distinct elements of a set S.  Example   gap> ## "6 aus 49" is a common lottery in Germany gap> RandomCombination( [1..49], 6 );  [ 2, 16, 24, 26, 37, 47 ]   3.2 Distinct and Common Representatives 3.2-1 DistinctRepresentatives DistinctRepresentatives( list )  operation CommonRepresentatives( list )  operation CommonTransversal( grp, subgrp )  operation IsCommonTransversal( grp, subgrp, list )  operation These operations have been transferred from package XMod. They deal with lists of subsets of [1 ... n] and construct systems of distinct and common representatives using simple, non-recursive, combinatorial algorithms. When L is a set of n subsets of [1 ... n] and the Hall condition is satisfied (the union of any k subsets has at least k elements), a set of DistinctRepresentatives exists. When J,K are both lists of n sets, the operation CommonRepresentatives returns two lists: the set of representatives, and a permutation of the subsets of the second list. The operation CommonTransversal may be used to provide a common transversal for the sets of left and right cosets of a subgroup H of a group G, although a greedy algorithm is usually quicker.  Example   gap> J := [ [1,2,3], [3,4], [3,4], [1,2,4] ];; gap> DistinctRepresentatives( J ); [ 1, 3, 4, 2 ] gap> K := [ [3,4], [1,2], [2,3], [2,3,4] ];; gap> CommonRepresentatives( J, K ); [ [ 3, 3, 3, 1 ], [ 1, 3, 4, 2 ] ] gap> d16 := DihedralGroup( IsPermGroup, 16 );  Group([ (1,2,3,4,5,6,7,8), (2,8)(3,7)(4,6) ]) gap> SetName( d16, "d16" ); gap> c4 := Subgroup( d16, [ d16.1^2 ] );  Group([ (1,3,5,7)(2,4,6,8) ]) gap> SetName( c4, "c4" ); gap> RightCosets( d16, c4 ); [ RightCoset(c4,()), RightCoset(c4,(2,8)(3,7)(4,6)), RightCoset(c4,(1,8,7,6,5,  4,3,2)), RightCoset(c4,(1,8)(2,7)(3,6)(4,5)) ] gap> trans := CommonTransversal( d16, c4 ); [ (), (2,8)(3,7)(4,6), (1,2,3,4,5,6,7,8), (1,2)(3,8)(4,7)(5,6) ] gap> IsCommonTransversal( d16, c4, trans ); true   3.3 Functions for strings 3.3-1 BlankFreeString BlankFreeString( obj )  function This function has been transferred from package ResClasses. The result of BlankFreeString( obj ); is a composite of the functions String( obj ) and RemoveCharacters( obj, " " );.  Example   gap> gens := GeneratorsOfGroup( DihedralGroup(12) ); [ f1, f2, f3 ] gap> String( gens );  "[ f1, f2, f3 ]" gap> BlankFreeString( gens );  "[f1,f2,f3]"   utils-0.86/doc/chapBib.html000644 000765 000024 00000013540 14621610515 020702 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - References
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

References

[BCP97] Bosma, W., Cannon, J. and Playoust, C., The Magma algebra system. {I}. The user language, J. Symbolic Comput., 24 (3-4) (1997), 235--265 pages
( Computational algebra and number theory (London, 1993)} https://doi.org/10.1006/jsco.1996.0125 ).

[GH16] Gutsche, S. and Horn, M., AutoDoc - Generate documentation from GAP source code (Version 2016.12.04) (2016)
( GAP package, https://github.com/gap-packages/AutoDoc ).

[Hor17] Horn, M., GitHubPagesForGAP - Template for easily using GitHub Pages within GAP packages (Version 0.2) (2017)
( GAP package, https://gap-system.github.io/GitHubPagesForGAP/ ).

[Koh17a] Kohl, S., RCWA - Residue-Class-Wise Affine Groups (Version 4.5.1) (2017)
( GAP package, https://stefan-kohl.github.io/rcwa.html ).

[Koh17b] Kohl, S., ResClasses - Set-Theoretic Computations with Residue Classes (Version 4.6.0) (2017)
( GAP package, https://stefan-kohl.github.io/resclasses.html ).

[LN17] Lübeck, F. and Neunhöffer, M., GAPDoc (Version 1.6), RWTH Aachen (2017)
( GAP package, https://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/index.html ).

[WAOU17] Wensley, C. D., Alp, M., Odabas, A. and Uslu, E. O., XMod - Crossed Modules and Cat1-groups in GAP (Version 2.64) (2017)
( GAP package, https://github.com/gap-packages/xmod ).

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap10_mj.html000644 000765 000024 00000025302 14621610515 021113 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 10: Various other functions
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

10 Various other functions

10.1 File operations

10.1-1 Log2HTML
‣ Log2HTML( filename )( function )

This function has been transferred from package RCWA.

This function converts the GAP logfile filename to HTML. It appears that the logfile should be in your current directory. The extension of the input file must be *.log. The name of the output file is the same as the one of the input file except that the extension *.log is replaced by *.html. There is a sample CSS file in utils/doc/gaplog.css, which you can adjust to your taste.


gap> LogTo( "triv.log" );
gap> a := 33^5;
39135393
gap> LogTo(); 
gap> Log2HTML( "triv.log" );     

10.2 LaTeX strings

10.2-1 IntOrOnfinityToLaTeX
‣ IntOrOnfinityToLaTeX( n )( function )

This function has been transferred from package ResClasses.

IntOrInfinityToLaTeX(n) returns the LaTeX string for n.


gap> IntOrInfinityToLaTeX( 10^3 );
"1000"
gap> IntOrInfinityToLaTeX( infinity );
"\\infty"

10.2-2 LaTeXStringFactorsInt
‣ LaTeXStringFactorsInt( n )( function )

This function has been transferred from package RCWA.

It returns the prime factorization of the integer \(n\) as a string in LaTeX format.


gap> LaTeXStringFactorsInt( Factorial(12) );
"2^{10} \\cdot 3^5 \\cdot 5^2 \\cdot 7 \\cdot 11"

10.3 Conversion to \({\sf Magma}\) string

10.3-1 ConvertToMagmaInputString
‣ ConvertToMagmaInputString( arg )( function )

The function ConvertToMagmaInputString( obj [, str] ) attempts to output a string s which can be read into \({\sf Magma}\) [BCP97] so as to produce the same group in that computer algebra system. In the second form the user specifies the name of the resulting object, so that the output string has the form "str := ...". When obj is a permutation group, the operation PermGroupToMagmaFormat(obj) is called. This function has been taken from other.gi in the main library where it was called MagmaInputString. When obj is a pc-group, the operation PcGroupToMagmaFormat(obj) is called. This function was private code of Max Horn. When obj is a matrix group over a finite field, the operation MatrixGroupToMagmaFormat(obj) is called. This function is a modification of private code of Frank Lübeck.

Hopefully code for other types of group will be added in due course.

These functions should be considered experimental, and more testing is desirable.


gap> ConvertToMagmaInputString( Group( (1,2,3,4,5), (3,4,5) ) );
"PermutationGroup<5|(1,2,3,4,5),\n(3,4,5)>;\n"
gap> ConvertToMagmaInputString( Group( (1,2,3,4,5) ), "c5" );        
"c5:=PermutationGroup<5|(1,2,3,4,5)>;\n"
gap> ConvertToMagmaInputString( DihedralGroup( IsPcGroup, 10 ) );
"PolycyclicGroup< f1,f2 |\nf1^2,\nf2^5,\nf2^f1 = f2^4\n>;\n"
gap> M := GL(2,5);;  Size(M); 
480
gap> s1 := ConvertToMagmaInputString( M );
"F := GF(5);\nP := GL(2,F);\ngens := [\nP![2,0,0,1],\nP![4,1,4,0]\n];\nsub<P |\
 gens>;\n"
gap> Print( s1 );
F := GF(5);
P := GL(2,F);
gens := [
P![2,0,0,1],
P![4,1,4,0]
];
sub<P | gens>;
gap> n1 := [ [ Z(9)^0, Z(9)^0 ], [ Z(9)^0, Z(9) ] ];;
gap> n2 := [ [ Z(9)^0, Z(9)^3 ], [ Z(9)^4, Z(9)^2 ] ];;
gap> N := Group( n1, n2 );;  Size( N );
5760
gap> s2 := ConvertToMagmaInputString( N, "gpN" );;
gap> Print( s2 );
F := GF(3^2);
P := GL(2,F);
w := PrimitiveElement(F);
gens := [
P![ 1, 1, 1,w^1],
P![ 1,w^3, 2,w^2]
];
gpN := sub<P | gens>;

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/template.xml000644 000765 000024 00000001744 14621444241 021025 0ustar00christopherwensleystaff000000 000000 Number-theoretic functions
Functions for integers These functions are in the process of being transferred from package &Home;.

They

utils-0.86/doc/chap0.html000644 000765 000024 00000045443 14621610515 020354 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Contents
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

utils

Utility functions in GAP

0.86

16 May 2024

Thomas Breuer
Email: sam@math.rwth-aachen.de
Homepage: https://www.math.rwth-aachen.de/~Thomas.Breuer

Sebastian Gutsche
Email: gutsche@mathematik.uni-siegen.de
Homepage: https://sebasguts.github.io/

Max Horn
Email: mhorn@rptu.de
Homepage: https://github.com/mhorn

Alexander Hulpke
Email: hulpke@math.colostate.edu
Homepage: https://www.math.colostate.edu/~hulpke

Pedro García-Sánchez
Email: pedro@ugr.es
Homepage: http://www.ugr.es/local/pedro

Christopher Jefferson
Email: caj21@st-andrews.ac.uk
Homepage: https://caj.host.cs.st-andrews.ac.uk/

Stefan Kohl
Email: stefan@mcs.st-and.ac.uk
Homepage: https://www.gap-system.org/DevelopersPages/StefanKohl/

Frank Lübeck
Email: Frank.Luebeck@Math.RWTH-Aachen.De
Homepage: https://www.math.rwth-aachen.de/~Frank.Luebeck

Chris Wensley
Email: cdwensley.maths@btinternet.com
Homepage: https://github.com/cdwensley

Abstract

The Utils package provides a space for utility functions in a variety of GAP packages to be collected together into a single package. In this way it is hoped that they will become more visible to package authors.

Any package author who transfers a function to Utils will become an author of Utils.

If deemed appropriate, functions may also be transferred from the main library.

Bug reports, suggestions and comments are, of course, welcome. Please contact the last author at cdwensley.maths@btinternet.com or submit an issue at the GitHub repository https://github.com/gap-packages/utils/issues/.

Copyright

© 2015-2024, The GAP Group.

The Utils package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Acknowledgements

This documentation was prepared using the GAPDoc [LN17] and AutoDoc [GH16] packages.

The procedure used to produce new releases uses the package GitHubPagesForGAP [Hor17] and the package ReleaseTools.

Contents


Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap1.txt000644 000765 000024 00000012723 14621610512 020220 0ustar00christopherwensleystaff000000 000000 1 Introduction The Utils package provides a space for utility functions from a variety of GAP packages to be collected together into a single package. In this way it is hoped that they will become more visible to other package authors. This package was first distributed as part of the GAP 4.8.2 distribution. The package is loaded with the command  Example   gap> LoadPackage( "utils" );    Functions have been transferred from the following packages:  Conversion of a GAP group to a Magma output string, taken from various sources including other.gi in the main library. Transfer is complete (for now) for functions from the following packages:  AutoDoc [GH16] (with function names changed);  ResClasses [Koh17b];  RCWA [Koh17a];  XMod [WAOU17]. The package may be obtained either as a compressed .tar file or as a .zip file, utils-version_number.tar.gz, by ftp from one of the following sites:  the Utils GitHub release site: https://gap-packages.github.io/utils/.  any GAP archive, e.g. https://www.gap-system.org/Packages/packages.html; The package also has a GitHub repository at: https://github.com/gap-packages/utils. Once the package is loaded, the manual doc/manual.pdf can be found in the documentation folder. The html versions, with or without MathJax, may be rebuilt as follows:  Example   gap> ReadPackage( "utils", "makedoc.g" );    It is possible to check that the package has been installed correctly by running the test files (which terminates the GAP session):  Example   gap> ReadPackage( "utils", "tst/testall.g" ); Architecture: . . . . .  testing: . . . . .  . . .  #I No errors detected while testing   Note that functions listed in this manual that are currently in the process of being transferred are only read from the source package Home (say), and so can only be used if Home has already been loaded. There are no such functions in transition at present. 1.1 Information for package authors A function (or collection of functions) is suitable for transfer from a package Home to Utils if the following conditions are satisfied.  The function is sufficiently non-specialised so that it might be of use to other authors.  The function does not depend on the remaining functions in Home  The function does not do what can already be done with a GAP library function.  Documentation of the function and test examples are available.  When there is more than one active author of Home, they should all be aware (and content) that the transfer is taking place. Authors of packages may be reluctant to let go of their utility functions. The following principles may help to reassure them. (Suggestions for more items here are welcome.)  A function that has been transferred to Utils will not be changed without the approval of the original author.  The current package maintainer has every intention of continuing to maintain Utils. In the event that this proves impossible, the GAP development team will surely find someone to take over.  Function names will not be changed unless specifically requested by Home's author(s) or unless they have the form HOME_FunctionName.  In order to speed up the transfer process, only functions from one package will be in transition at any given time. Hopefully a week or two will suffice for most packages.  Any package author who transfers a function to Utils will become an author of Utils. (In truth, Utils does not have authors, just a large number of contributors.) The process for transferring utility functions from Home to Utils is described in Chapter 12. utils-0.86/doc/chap0.txt000644 000765 000024 00000015106 14621610512 020215 0ustar00christopherwensleystaff000000 000000  utils   Utility functions in GAP  0.86 16 May 2024 Thomas Breuer Sebastian Gutsche Max Horn Alexander Hulpke Pedro García-Sánchez Christopher Jefferson Stefan Kohl Frank Lübeck Chris Wensley Thomas Breuer Email: mailto:sam@math.rwth-aachen.de Homepage: https://www.math.rwth-aachen.de/~Thomas.Breuer Sebastian Gutsche Email: mailto:gutsche@mathematik.uni-siegen.de Homepage: https://sebasguts.github.io/ Max Horn Email: mailto:mhorn@rptu.de Homepage: https://github.com/mhorn Alexander Hulpke Email: mailto:hulpke@math.colostate.edu Homepage: https://www.math.colostate.edu/~hulpke Pedro García-Sánchez Email: mailto:pedro@ugr.es Homepage: http://www.ugr.es/local/pedro Christopher Jefferson Email: mailto:caj21@st-andrews.ac.uk Homepage: https://caj.host.cs.st-andrews.ac.uk/ Stefan Kohl Email: mailto:stefan@mcs.st-and.ac.uk Homepage: https://www.gap-system.org/DevelopersPages/StefanKohl/ Frank Lübeck Email: mailto:Frank.Luebeck@Math.RWTH-Aachen.De Homepage: https://www.math.rwth-aachen.de/~Frank.Luebeck Chris Wensley Email: mailto:cdwensley.maths@btinternet.com Homepage: https://github.com/cdwensley ------------------------------------------------------- Abstract The Utils package provides a space for utility functions in a variety of GAP packages to be collected together into a single package. In this way it is hoped that they will become more visible to package authors. Any package author who transfers a function to Utils will become an author of Utils. If deemed appropriate, functions may also be transferred from the main library. Bug reports, suggestions and comments are, of course, welcome. Please contact the last author at mailto:cdwensley.maths@btinternet.com or submit an issue at the GitHub repository https://github.com/gap-packages/utils/issues/. ------------------------------------------------------- Copyright © 2015-2024, The GAP Group. The Utils package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ------------------------------------------------------- Acknowledgements This documentation was prepared using the GAPDoc [LN17] and AutoDoc [GH16] packages. The procedure used to produce new releases uses the package GitHubPagesForGAP [Hor17] and the package ReleaseTools. ------------------------------------------------------- Contents (Utils) 1 Introduction 1.1 Information for package authors 2 Printing Lists and Iterators 2.1 Printing selected items 2.1-1 PrintSelection 3 Lists, Sets and Strings 3.1 Functions for lists 3.1-1 DifferencesList 3.1-2 QuotientsList 3.1-3 SearchCycle 3.1-4 RandomCombination 3.2 Distinct and Common Representatives 3.2-1 DistinctRepresentatives 3.3 Functions for strings 3.3-1 BlankFreeString 4 Number-theoretic functions 4.1 Functions for integers 4.1-1 AllSmoothIntegers 4.1-2 AllProducts 4.1-3 RestrictedPartitionsWithoutRepetitions 4.1-4 NextProbablyPrimeInt 4.1-5 PrimeNumbersIterator 5 Groups and homomorphisms 5.1 Functions for groups 5.1-1 Comm 5.1-2 IsCommuting 5.1-3 ListOfPowers 5.1-4 GeneratorsAndInverses 5.1-5 UpperFittingSeries 5.2 Left Cosets for Groups 5.2-1 LeftCoset 5.2-2 Inverse 5.3 Functions for group homomorphisms 5.3-1 EpimorphismByGenerators 5.3-2 Pullback 5.3-3 CentralProduct 5.3-4 IdempotentEndomorphisms 5.3-5 DirectProductOfFunctions 5.3-6 DirectProductOfAutomorphismGroups 6 Matrices 6.1 Some operations for matrices 6.1-1 DirectSumDecompositionMatrices 7 Iterators 7.1 Some iterators for groups and their isomorphisms 7.1-1 AllIsomorphismsIterator 7.1-2 AllSubgroupsIterator 7.2 Operations on iterators 7.2-1 CartesianIterator 7.2-2 UnorderedPairsIterator 8 Records 8.1 Functions for records 8.1-1 AssignGlobals 8.2 Option records for functions 8.2-1 OptionRecordWithDefaults 9 Web Downloads 9.1 Functions for downloading files from the web 9.1-1 Download 9.1-2 User preference DownloadVerifyCertificate 10 Various other functions 10.1 File operations 10.1-1 Log2HTML 10.2 LaTeX strings 10.2-1 IntOrOnfinityToLaTeX 10.2-2 LaTeXStringFactorsInt 10.3 Conversion to Magma string 10.3-1 ConvertToMagmaInputString 11 Obsolete functions 11.1 Operations from AutoDoc 11.2 Functions for printing 11.3 Other obsolete functions 11.3-1 Applicable Methods 11.3-2 ExponentOfPrime 12 The transfer procedure  utils-0.86/doc/chap4_mj.html000644 000765 000024 00000030633 14621610515 021041 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 4: Number-theoretic functions
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

4 Number-theoretic functions

4.1 Functions for integers

4.1-1 AllSmoothIntegers
‣ AllSmoothIntegers( maxp, maxn )( function )
‣ AllSmoothIntegers( L, maxp )( function )

This function has been transferred from package RCWA.

The function AllSmoothIntegers(maxp,maxn) returns the list of all positive integers less than or equal to maxn whose prime factors are all in the list \(L = \{p ~|~ p \leqslant maxp, p~\mbox{prime} \}\).

In the alternative form, when \(L\) is a list of primes, the function returns the list of all positive integers whose prime factors lie in \(L\).


gap> AllSmoothIntegers( 3, 1000 );
[ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96, 
  108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576, 
  648, 729, 768, 864, 972 ]
gap> AllSmoothIntegers( [5,11,17], 1000 );
[ 1, 5, 11, 17, 25, 55, 85, 121, 125, 187, 275, 289, 425, 605, 625, 935 ]
gap> Length( last );
16
gap> List( [3..20], n -> Length( AllSmoothIntegers( [5,11,17], 10^n ) ) );
[ 16, 29, 50, 78, 114, 155, 212, 282, 359, 452, 565, 691, 831, 992, 1173, 
  1374, 1595, 1843 ]

4.1-2 AllProducts
‣ AllProducts( L, k )( function )

This function has been transferred from package RCWA.

The command AllProducts(L,k) returns the list of all products of k entries of the list L. Note that every ordering of the entries is used so that, in the commuting case, there are bound to be repetitions.


gap> AllProducts([1..4],3); 
[ 1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16, 2, 4, 6, 8, 4, 8, 12, 
  16, 6, 12, 18, 24, 8, 16, 24, 32, 3, 6, 9, 12, 6, 12, 18, 24, 9, 18, 27, 
  36, 12, 24, 36, 48, 4, 8, 12, 16, 8, 16, 24, 32, 12, 24, 36, 48, 16, 32, 
  48, 64 ]
gap> Set(last);            
[ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 64 ]
gap> AllProducts( [(1,2,3),(2,3,4)], 2 );
[ (2,4,3), (1,2)(3,4), (1,3)(2,4), (1,3,2) ]

4.1-3 RestrictedPartitionsWithoutRepetitions
‣ RestrictedPartitionsWithoutRepetitions( n, S )( function )

This function has been transferred from package RCWA.

For a positive integer n and a set of positive integers S, this function returns the list of partitions of n into distinct elements of S. Unlike RestrictedPartitions, no repetitions are allowed.


gap> RestrictedPartitions( 20, [4..10] );
[ [ 4, 4, 4, 4, 4 ], [ 5, 5, 5, 5 ], [ 6, 5, 5, 4 ], [ 6, 6, 4, 4 ], 
  [ 7, 5, 4, 4 ], [ 7, 7, 6 ], [ 8, 4, 4, 4 ], [ 8, 6, 6 ], [ 8, 7, 5 ], 
  [ 8, 8, 4 ], [ 9, 6, 5 ], [ 9, 7, 4 ], [ 10, 5, 5 ], [ 10, 6, 4 ], 
  [ 10, 10 ] ]
gap> RestrictedPartitionsWithoutRepetitions( 20, [4..10] );
[ [ 10, 6, 4 ], [ 9, 7, 4 ], [ 9, 6, 5 ], [ 8, 7, 5 ] ]
gap> RestrictedPartitionsWithoutRepetitions( 10^2, List([1..10], n->n^2 ) );
[ [ 100 ], [ 64, 36 ], [ 49, 25, 16, 9, 1 ] ]

4.1-4 NextProbablyPrimeInt
‣ NextProbablyPrimeInt( n )( function )

This function has been transferred from package RCWA.

The function NextProbablyPrimeInt(n) does the same as NextPrimeInt(n) except that for reasons of performance it tests numbers only for IsProbablyPrimeInt(n) instead of IsPrimeInt(n). For large n, this function is much faster than NextPrimeInt(n)


gap> n := 2^251;
3618502788666131106986593281521497120414687020801267626233049500247285301248
gap> NextProbablyPrimeInt( n );
3618502788666131106986593281521497120414687020801267626233049500247285301313
gap> time;                     
1
gap> NextPrimeInt( n );        
3618502788666131106986593281521497120414687020801267626233049500247285301313
gap> time;             
213

4.1-5 PrimeNumbersIterator
‣ PrimeNumbersIterator( [chunksize] )( function )

This function has been transferred from package RCWA.

This function returns an iterator which runs over the prime numbers n ascending order; it takes an optional argument chunksize which specifies the length of the interval which is sieved in one go (the default is \(10^7\)), and which can be used to balance runtime vs. memory consumption. It is assumed that chunksize is larger than any gap between two consecutive primes within the range one intends to run the iterator over.


gap> iter := PrimeNumbersIterator();;
gap> for i in [1..100] do  p := NextIterator(iter);  od;
gap> p;
541
gap> sum := 0;;
gap> ## "prime number race" 1 vs. 3 mod 4
gap> for p in PrimeNumbersIterator() do 
>       if p <> 2 then sum := sum + E(4)^(p-1); fi;
>       if sum > 0 then break; fi;
>    od;
gap> p;
26861

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/groups.xml000644 000765 000024 00000041071 14621444241 020526 0ustar00christopherwensleystaff000000 000000 Groups and homomorphisms
Functions for groups This method has been transferred from package &ResClasses;.

It provides a method for Comm when the argument is a list (enclosed in square brackets), and calls the function LeftNormedComm.

Comm( [ (1,2), (2,3) ] ); (1,2,3) gap> Comm( [(1,2),(2,3),(3,4),(4,5),(5,6)] ); (1,5,6) gap> Comm(Comm(Comm(Comm((1,2),(2,3)),(3,4)),(4,5)),(5,6)); ## the same (1,5,6) ]]> This function has been transferred from package &ResClasses;.

It tests whether two elements in a group commute.

D12 := DihedralGroup( 12 ); gap> SetName( D12, "D12" ); gap> a := D12.1;; b := D12.2;; gap> IsCommuting( a, b ); false ]]> This function has been transferred from package &RCWA;.

The operation ListOfPowers(g,exp) returns the list [g,g^2,...,g^{exp}] of powers of the element g.

ListOfPowers( 2, 20 ); [ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576 ] gap> ListOfPowers( (1,2,3)(4,5), 12 ); [ (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), (), (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), () ] gap> ListOfPowers( D12.2, 6 ); [ f2, f3, f2*f3, f3^2, f2*f3^2, of ... ] ]]> This function has been transferred from package &RCWA;.

This operation returns a list containing the generators of G followed by the inverses of these generators.

GeneratorsAndInverses( D12 ); [ f1, f2, f3, f1, f2*f3^2, f3^2 ] gap> GeneratorsAndInverses( SymmetricGroup(5) ); [ (1,2,3,4,5), (1,2), (1,5,4,3,2), (1,2) ] ]]> These three functions have been transferred from package &ResClasses;.

Fitting series The upper and lower Fitting series and the Fitting length of a solvable group are described here: https://en.wikipedia.org/wiki/Fitting_length.

UpperFittingSeries( D12 ); LowerFittingSeries( D12 ); [ Group([ ]), Group([ f3, f2*f3 ]), Group([ f1, f3, f2*f3 ]) ] [ D12, Group([ f3 ]), Group([ ]) ] gap> FittingLength( D12 ); 2 gap> S4 := SymmetricGroup( 4 );; gap> UpperFittingSeries( S4 ); [ Group(()), Group([ (1,2)(3,4), (1,4)(2,3) ]), Group([ (1,2)(3,4), (1,4) (2,3), (2,4,3) ]), Group([ (3,4), (2,3,4), (1,2)(3,4) ]) ] gap> List( last, StructureDescription ); [ "1", "C2 x C2", "A4", "S4" ] gap> LowerFittingSeries( S4 ); [ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,3) (2,4) ]), Group(()) ] gap> List( last, StructureDescription ); [ "S4", "A4", "C2 x C2", "1" ] gap> FittingLength( S4); 3 ]]>

Left Cosets for Groups Since &GAP; uses right actions by default, the library contains the operation RightCoset(U,g) for constructing the right coset Ug of a subgroup U \leq G and an element g \in G. It has been noted in the reference manual that, by inverting all the elements in Ug, the left coset g^{-1}U is obtained.

Just for the sake of completeness, from August 2022 this package provides the operation LeftCoset(g,U) for constructing the left coset gU. Users are strongly recommended to continue to use RightCoset for all serious calculations, since left cosets have a much simpler implementation and do not behave exactly like right cosets.

The methods for left cosets which are provided generally work by converting gU to Ug^{-1}; applying the equivalent method for right cosets; and, if necessary, converting back again to left cosets.

G acts on gU by OnLeftInverse: (gU)^{g_0} = g_0^{-1}*(gU) = (g_0^{-1}g)U.

lc1 := LeftCoset( (1,2,3), Group( [ (1,2), (3,4) ] ) ); LeftCoset((1,2,3),Group([ (1,2), (3,4) ])) gap> Representative( lc1 ); (1,2,3) gap> ActingDomain( lc1 ); Group([ (1,2), (3,4) ]) gap> AsSet( lc1 ); [ (2,3), (2,4,3), (1,2,3), (1,2,4,3) ] gap> (1,2,3) in lc1; true gap> lc2 := (2,4,3) * lc1; LeftCoset((1,2,4),Group([ (1,2), (3,4) ])) gap> lc3 := lc1^(2,3,4);; gap> lc2 = lc3; true ]]> Inverse The inverse of the left coset gU is the right coset Ug^{-1}, and conversely. This is an abuse of the attribute Inverse, since the standard requirement, that x*x^{-1} is an identity, does not hold.

rc1 := Inverse( lc1 ); RightCoset(Group([ (1,2), (3,4) ]),(1,3,2)) gap> rc4 := RightCoset( Group( (1,2), (2,3) ), (3,4) ); RightCoset(Group([ (1,2), (2,3) ]),(3,4)) gap> lc4 := Inverse( rc4 ); LeftCoset((3,4),Group([ (1,2), (2,3) ])) gap> Intersection( lc2, lc4 ); [ (2,3,4), (1,2,3,4) ] ]]>

Functions for group homomorphisms This function has been transferred from package &RCWA;.

It constructs a group homomorphism which maps the generators of G to those of H. Its intended use is when G is a free group, and a warning is printed when this is not the case. Note that anything may happen if the resulting map is not a homomorphism!

G := Group( (1,2,3), (3,4,5), (5,6,7), (7,8,9) );; gap> phi := EpimorphismByGenerators( FreeGroup("a","b","c","d"), G ); [ a, b, c, d ] -> [ (1,2,3), (3,4,5), (5,6,7), (7,8,9) ] gap> PreImagesRepresentativeNC( phi, (1,2,3,4,5,6,7,8,9) ); d*c*b*a gap> a := G.1;; b := G.2;; c := G.3;; d := G.4;; gap> d*c*b*a; (1,2,3,4,5,6,7,8,9) gap> ## note that it is easy to produce nonsense: gap> epi := EpimorphismByGenerators( Group((1,2,3)), Group((8,9)) ); Warning: calling GroupHomomorphismByImagesNC without checks [ (1,2,3) ] -> [ (8,9) ] gap> IsGroupHomomorphism( epi ); true gap> Image( epi, (1,2,3) ); () gap> Image( epi, (1,3,2) ); (8,9) ]]> If \phi_1 : G_1 \to H and \phi_2 : G_2 \to H are two group homomorphisms with the same range, then their pullback is the subgroup of G_1 \times G_2 consisting of those elements (g_1,g_2) such that \phi_1 g_1 = \phi_2 g_2.

The attribute PullbackInfo of a pullback group P is similar to DirectProductInfo for a direct product of groups. Its value is a record with the following components:

directProduct the direct product G_1 \times G_2, and projections a list with the two projections onto G_1 and G_2. There are no embeddings in this record, but it is possible to use the embeddings into the direct product, see .

s4 := Group( (1,2),(2,3),(3,4) );; gap> s3 := Group( (5,6),(6,7) );; gap> c3 := Subgroup( s3, [ (5,6,7) ] );; gap> f := GroupHomomorphismByImages( s4, s3, > [(1,2),(2,3),(3,4)], [(5,6),(6,7),(5,6)] );; gap> i := GroupHomomorphismByImages( c3, s3, [(5,6,7)], [(5,6,7)] );; gap> Pfi := Pullback( f, i ); Group([ (2,3,4)(5,7,6), (1,2)(3,4) ]) gap> StructureDescription( Pfi ); "A4" gap> info := PullbackInfo( Pfi ); rec( directProduct := Group([ (1,2), (2,3), (3,4), (5,6,7) ]), projections := [ [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (2,3,4), (1,2)(3,4) ], [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (5,7,6), () ] ] ) gap> g := (1,2,3)(5,6,7);; gap> ImageElm( info!.projections[1], g ); (1,2,3) gap> ImageElm( info!.projections[2], g ); (5,6,7) gap> dp := info!.directProduct;; gap> a := ImageElm( Embedding( dp, 1 ), (1,4,3) );; gap> b := ImageElm( Embedding( dp, 2 ), (5,7,6) );; gap> a*b in Pfi; true ]]> This function was added by Thomas Breuer, following discussions with Hongyi Zhao (see https://github.com/gap-packages/hap/issues/73).

Let G1 and G2 be two groups, Z1 be a central subgroup of G1, and Phi be an isomorphism from Z1 to a central subgroup of G2. The central product defined by these arguments is the factor group of the direct product of G1 and G2 by the central subgroup \{ (z, (Phi(z))^{-1}) : z \in Z1 \}.

The attribute of a group G that has been created by is similar to for pullback groups. Its value is a record with the following components.

projection the epimorphism from the direct product of G1 and G2 to G, and phi the map Phi. Note that one can access the direct product as the value of the projection map, and one can access G1 and G2 as the two embeddings of this direct product, see . g1 := DihedralGroup( 8 ); gap> c1 := Centre( g1 ); Group([ f3 ]) gap> cp1 := CentralProduct( g1, g1, c1, IdentityMapping( c1 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp1 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> g2 := QuaternionGroup( 8 ); gap> c2 := Centre( g2 ); Group([ y2 ]) gap> cp2 := CentralProduct( g2, g2, c2, IdentityMapping( c2 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp2 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> info2 := CentralProductInfo( cp2 ); rec( phi := IdentityMapping( Group([ y2 ]) ), projection := [ f1, f2, f3, f4, f5, f6 ] -> [ f1, f2, f5, f3, f4, f5 ] ) gap> Source( Embedding( Source( info2.projection ), 1 ) ) = g2; true ]]> An endomorphism f : G \to G is idempotent if f^2=f. It has an image R \leqslant G; is the identity map when restricted to R; and has a kernel N which has trivial intersection with R and has size |G|/|R|.

The operation IdempotentEndomorphismsWithImage(genG,R) returns a list of the images of the generating set genG of a group G under the idempotent endomorphisms with image R.

The attribute IdempotentEndomorphismsData(G) returns a record data with fields data.gens, a fixed generating set for G, and data.images a list of the non-empty outputs of IdempotentEndomorphismsWithImage(genG,R) obtained by iterating over all subgroups of G.

The operation IdempotentEndomorphisms(G) returns the list of these mappings obtained using IdempotentEndomorphismsData(G). The first of these is the zero map, the second is the identity.

gens := [ (1,2,3,4), (1,2)(3,4) ];; gap> d8 := Group( gens );; gap> SetName( d8, "d8" ); gap> c2 := Subgroup( d8, [ (2,4) ] );; gap> IdempotentEndomorphismsWithImage( gens, c2 ); [ [ (), (2,4) ], [ (2,4), () ] ] gap> IdempotentEndomorphismsData( d8 ); rec( gens := [ (1,2,3,4), (1,2)(3,4) ], images := [ [ [ (), () ] ], [ [ (), (2,4) ], [ (2,4), () ] ], [ [ (), (1,3) ], [ (1,3), () ] ], [ [ (), (1,2)(3,4) ], [ (1,2)(3,4), (1,2)(3,4) ] ], [ [ (), (1,4)(2,3) ], [ (1,4)(2,3), (1,4)(2,3) ] ], [ [ (1,2,3,4), (1,2)(3,4) ] ] ] ) gap> List( last.images, L -> Length(L) ); [ 1, 2, 2, 2, 2, 1 ] gap> IdempotentEndomorphisms( d8 ); [ [ (1,2,3,4), (1,2)(3,4) ] -> [ (), () ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (2,4) ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (2,4), () ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,3) ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,3), () ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,2)(3,4) ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2)(3,4), (1,2)(3,4) ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,4)(2,3) ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,4)(2,3), (1,4)(2,3) ], [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2,3,4), (1,2)(3,4) ] ] ]]> The quaternion group q8 is an example of a group with a tail: there is only one subgroup in the lattice which covers the identity subgroup. The only idempotent isomorphisms of such groups are the identity mapping and the zero mapping because the only pairs N,R are the whole group and the identity subgroup. q8 := QuaternionGroup( 8 );; gap> IdempotentEndomorphisms( q8 ); [ [ x, y ] -> [ of ..., of ... ], [ x, y ] -> [ x, y ] ] ]]> Given group homomorphisms f_1 : G_1 \to G_2 and f_2 : H_1 \to H_2, this operation return the product homomorphism f_1 \times f_2 : G_1 \times G_2 \to H_1 \times H_2.

c4 := Group( (1,2,3,4) );; gap> c2 := Group( (5,6) );; gap> f1 := GroupHomomorphismByImages( c4, c2, [(1,2,3,4)], [(5,6)] );; gap> c3 := Group( (1,2,3) );; gap> c6 := Group( (1,2,3,4,5,6) );; gap> f2 := GroupHomomorphismByImages( c3, c6, [(1,2,3)], [(1,3,5)(2,4,6)] );; gap> c4c3 := DirectProduct( c4, c3 ); Group([ (1,2,3,4), (5,6,7) ]) gap> c2c6 := DirectProduct( c2, c6 ); Group([ (1,2), (3,4,5,6,7,8) ]) gap> f := DirectProductOfFunctions( c4c3, c2c6, f1, f2 ); [ (1,2,3,4), (5,6,7) ] -> [ (1,2), (3,5,7)(4,6,8) ] gap> ImageElm( f, (1,4,3,2)(5,7,6) ); (1,2)(3,7,5)(4,8,6) ]]> Let A_1,A_2 be groups of automorphism of groups G_1,G_2 respectively. The output of this function is a group A_1 \times A_2 of automorphisms of G_1 \times G_2.

c9 := Group( (1,2,3,4,5,6,7,8,9) );; gap> ac9 := AutomorphismGroup( c9 );; gap> q8 := QuaternionGroup( IsPermGroup, 8 );; gap> aq8 := AutomorphismGroup( q8 );; gap> A := DirectProductOfAutomorphismGroups( ac9, aq8 ); gap> genA := GeneratorsOfGroup( A );; gap> G := Source( genA[1] ); Group([ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13) (14,15,16,17) ]) gap> a := genA[1]*genA[5]; [ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)(14,15,16,17) ] -> [ (1,3,5,7,9,2,4,6,8), (10,16,12,14)(11,15,13,17), (10,11,12,13)(14,15,16,17) ] gap> ImageElm( a, (1,9,8,7,6,5,4,3,2)(10,14,12,16)(11,17,13,15) ); (1,8,6,4,2,9,7,5,3)(10,16,12,14)(11,15,13,17) ]]>

utils-0.86/doc/manual.css000644 000765 000024 00000015754 14621610515 020464 0ustar00christopherwensleystaff000000 000000 /* manual.css Frank Lübeck */ /* This is the default CSS style sheet for GAPDoc HTML manuals. */ /* basic settings, fonts, sizes, colors, ... */ body { position: relative; background: #ffffff; color: #000000; width: 70%; margin: 0pt; padding: 15pt; font-family: Helvetica,Verdana,Arial,sans-serif; text-align: justify; } /* no side toc on title page, bib and index */ body.chap0 { width: 95%; } body.chapBib { width: 95%; } body.chapInd { width: 95%; } h1 { font-size: 200%; } h2 { font-size: 160%; } h3 { font-size: 160%; } h4 { font-size: 130%; } h5 { font-size: 100%; } p.foot { font-size: 60%; font-style: normal; } a:link { color: #00008e; text-decoration: none; } a:visited { color: #00008e; text-decoration: none; } a:active { color: #000000; text-decoration: none; } a:hover { background: #eeeeee; } pre { font-family: "Courier New",Courier,monospace; font-size: 100%; color:#111111; } tt,code { font-family: "Courier New",Courier,monospace; font-size: 110%; color: #000000; } var { } /* general alignment classes */ .pcenter { text-align: center; } .pleft { text-align: left; } .pright { text-align: right; } /* layout for the definitions of functions, variables, ... */ div.func { background: #e0e0e0; margin: 0pt 0pt; } /* general and special table settings */ table { border-collapse: collapse; margin-left: auto; margin-right: auto; } td, th { border-style: none; } table.func { padding: 0pt 1ex; margin-left: 1ex; margin-right: 1ex; background: transparent; /* line-height: 1.1; */ width: 100%; } table.func td.tdright { padding-right: 2ex; } /* Example elements (for old converted manuals, now in div+pre */ table.example { background: #efefef; border-style: none; border-width: 0pt; padding: 0px; width: 100% } table.example td { border-style: none; border-width: 0pt; padding: 0ex 1ex; } /* becomes ... */ div.example { background: #efefef; padding: 0ex 1ex; /* overflow-x: auto; */ overflow: auto; } /* Links to chapters in all files at top and bottom. */ /* If there are too many chapters then use 'display: none' here. */ div.chlinktop { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; } div.chlinktop a { margin: 3px; } div.chlinktop a:hover { background: #ffffff; } div.chlinkbot { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; /* width: 100%; */ } div.chlinkbot a { margin: 3px; } span.chlink1 { } /* and this is for the "Top", "Prev", "Next" links */ div.chlinkprevnexttop { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnexttop a:hover { background: #ffffff; } div.chlinkprevnextbot { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnextbot a:hover { background: #ffffff; } /* table of contents, initially don't display subsections */ div.ContSSBlock { display: none; } div.ContSSBlock br { display: none; } /* format in separate lines */ span.tocline { display: block; width: 100%; } div.ContSSBlock a { display: block; } /* this is for the main table of contents */ div.ContChap { } div.ContChap div.ContSect:hover div.ContSSBlock { display: block; position: absolute; background: #eeeeee; border-style: solid; border-width: 1px 4px 4px 1px; border-color: #666666; padding-left: 0.5ex; color: #000000; left: 20%; width: 40%; z-index: 10000; } div.ContSSBlock a:hover { background: #ffffff; } /* and here for the side menu of contents in the chapter files */ div.ChapSects { } div.ChapSects a:hover { background: #eeeeee; } div.ChapSects a:hover { display: block; width: 100%; background: #eeeeee; color: #000000; } div.ChapSects div.ContSect:hover div.ContSSBlock { display: block; position: fixed; background: #eeeeee; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #666666; padding-left: 0ex; padding-right: 0.5ex; color: #000000; left: 54%; width: 25%; z-index: 10000; } div.ChapSects div.ContSect:hover div.ContSSBlock a { display: block; margin-left: 3px; } div.ChapSects div.ContSect:hover div.ContSSBlock a:hover { display: block; background: #ffffff; } div.ContSect { text-align: left; margin-left: 1em; } div.ChapSects { position: fixed; left: 75%; font-size: 90%; overflow: auto; top: 10px; bottom: 0px; } /* Table elements */ table.GAPDocTable { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTable td, table.GAPDocTable th { padding: 3pt; border-width: thin; border-style: solid; border-color: #555555; } caption.GAPDocTable { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } table.GAPDocTablenoborder { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTablenoborder td, table.GAPDocTable th { padding: 3pt; border-width: 0pt; border-style: solid; border-color: #555555; } caption.GAPDocTablenoborder { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } td.tdright { text-align: right; } td.tdcenter { text-align: center; } /* Colors and fonts can be overwritten for some types of elements. */ /* Verb elements */ pre.normal { color: #000000; } /* Func-like elements and Ref to Func-like */ code.func { color: #000000; } /* K elements */ code.keyw { color: #770000; } /* F elements */ code.file { color: #8e4510; } /* C elements */ code.code { } /* Item elements */ code.i { } /* Button elements */ strong.button { } /* Headings */ span.Heading { } /* Arg elements */ var.Arg { color: #006600; } /* Example elements, is in tables, see above */ div.Example { } /* Package elements */ strong.pkg { } /* URL-like elements */ span.URL { } /* Mark elements */ strong.Mark { } /* Ref elements */ b.Ref { } span.Ref { } /* this contains the contents page */ div.contents { } /* this contains the index page */ div.index { } /* ignore some text for non-css layout */ span.nocss { display: none; } /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000097; font-weight: normal; } span.GAPbrkprompt { color: #970000; font-weight: normal; } span.GAPinput { color: #970000; } /* Bib entries */ p.BibEntry { } span.BibKey { color: #005522; } span.BibKeyLink { } b.BibAuthor { } i.BibTitle { } i.BibBookTitle { } span.BibEditor { } span.BibJournal { } span.BibType { } span.BibPublisher { } span.BibSchool { } span.BibEdition { } span.BibVolume { } span.BibSeries { } span.BibNumber { } span.BibPages { } span.BibOrganization { } span.BibAddress { } span.BibYear { } span.BibPublisher { } span.BibNote { } span.BibHowpublished { } utils-0.86/doc/chap11_mj.html000644 000765 000024 00000017742 14621610515 021125 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 11: Obsolete functions
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

11 Obsolete functions

11.1 Operations from AutoDoc

The file functions FindMatchingFiles and CreateDirIfMissing were copied from package AutoDoc where they are named AutoDoc_FindMatchingFiles and AutoDoc_CreateDirIfMissing.

The string function StringDotSuffix was also copied from package AutoDoc, where it is named AUTODOC_GetSuffix.

The function SetIfMissing was also transferred from package AutoDoc, where it is called AUTODOC_SetIfMissing. It writes into a record provided the position is not yet bound.

As from version 0.61, all these functions became obsolete in Utils, but continue to be defined in AutoDoc.

11.2 Functions for printing

The function PrintOneItemPerLine was used to prints lists vertically, rather than horizontally. Since a very similar result may be achieved using the GAP library functions Perform and Display, this function became obsolete in version 0.61.


gap> s3 := SymmetricGroup( 3 );; 
gap> L := KnownPropertiesOfObject( GeneratorsOfGroup( s3 ) );;
gap> Perform( L, Display );
IsFinite
IsSmallList
IsGeneratorsOfMagmaWithInverses
IsGeneratorsOfSemigroup
IsSubsetLocallyFiniteGroup
gap> Perform( s3, Display ); 
()
(2,3)
(1,3)
(1,3,2)
(1,2,3)
(1,2)

11.3 Other obsolete functions

11.3-1 Applicable Methods

The function PrintApplicableMethod, which was included in versions from 0.41 to 0.58, has been removed since it was considered superfluous. The example shows how to print out a function.


gap> ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 1, 1 );
#I  Searching Method for IsCyclic with 1 arguments:
#I  Total: 7 entries
#I  Method 4: ``IsCyclic'' at /Applications/gap/gap4r9/lib/grp.gi:30 , value: 
36
function( G ) ... end
gap> Print( last );
function ( G )
    if Length( GeneratorsOfGroup( G ) ) = 1 then
        return true;
    else
        TryNextMethod();
    fi;
    return;
end
gap> ApplicableMethod( IsCyclic, [ Group((1,2,3),(4,5)) ], 0, 3 );
function( <1 unnamed arguments> ) ... end
gap> Print( last );                                               
function ( <<arg-1>> )
    <<compiled GAP code from GAPROOT/lib/oper1.g:578>>
end

11.3-2 ExponentOfPrime

The function ExponentOfPrime was originally transferred from package RCWA. The command ExponentOfPrime(n,p) returned the exponent of the prime p in the prime factorization of n.

Since the GAP function PValuation produces the same results, and does so more quickly, this function has been made obsolete.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap4.txt000644 000765 000024 00000016704 14621610512 020226 0ustar00christopherwensleystaff000000 000000 4 Number-theoretic functions 4.1 Functions for integers 4.1-1 AllSmoothIntegers AllSmoothIntegers( maxp, maxn )  function AllSmoothIntegers( L, maxp )  function This function has been transferred from package RCWA. The function AllSmoothIntegers(maxp,maxn) returns the list of all positive integers less than or equal to maxn whose prime factors are all in the list L = {p ~|~ p leqslant maxp, p~mboxprime }. In the alternative form, when L is a list of primes, the function returns the list of all positive integers whose prime factors lie in L.  Example   gap> AllSmoothIntegers( 3, 1000 ); [ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96,   108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576,   648, 729, 768, 864, 972 ] gap> AllSmoothIntegers( [5,11,17], 1000 ); [ 1, 5, 11, 17, 25, 55, 85, 121, 125, 187, 275, 289, 425, 605, 625, 935 ] gap> Length( last ); 16 gap> List( [3..20], n -> Length( AllSmoothIntegers( [5,11,17], 10^n ) ) ); [ 16, 29, 50, 78, 114, 155, 212, 282, 359, 452, 565, 691, 831, 992, 1173,   1374, 1595, 1843 ]   4.1-2 AllProducts AllProducts( L, k )  function This function has been transferred from package RCWA. The command AllProducts(L,k) returns the list of all products of k entries of the list L. Note that every ordering of the entries is used so that, in the commuting case, there are bound to be repetitions.  Example   gap> AllProducts([1..4],3);  [ 1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16, 2, 4, 6, 8, 4, 8, 12,   16, 6, 12, 18, 24, 8, 16, 24, 32, 3, 6, 9, 12, 6, 12, 18, 24, 9, 18, 27,   36, 12, 24, 36, 48, 4, 8, 12, 16, 8, 16, 24, 32, 12, 24, 36, 48, 16, 32,   48, 64 ] gap> Set(last);  [ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 64 ] gap> AllProducts( [(1,2,3),(2,3,4)], 2 ); [ (2,4,3), (1,2)(3,4), (1,3)(2,4), (1,3,2) ]   4.1-3 RestrictedPartitionsWithoutRepetitions RestrictedPartitionsWithoutRepetitions( n, S )  function This function has been transferred from package RCWA. For a positive integer n and a set of positive integers S, this function returns the list of partitions of n into distinct elements of S. Unlike RestrictedPartitions, no repetitions are allowed.  Example   gap> RestrictedPartitions( 20, [4..10] ); [ [ 4, 4, 4, 4, 4 ], [ 5, 5, 5, 5 ], [ 6, 5, 5, 4 ], [ 6, 6, 4, 4 ],   [ 7, 5, 4, 4 ], [ 7, 7, 6 ], [ 8, 4, 4, 4 ], [ 8, 6, 6 ], [ 8, 7, 5 ],   [ 8, 8, 4 ], [ 9, 6, 5 ], [ 9, 7, 4 ], [ 10, 5, 5 ], [ 10, 6, 4 ],   [ 10, 10 ] ] gap> RestrictedPartitionsWithoutRepetitions( 20, [4..10] ); [ [ 10, 6, 4 ], [ 9, 7, 4 ], [ 9, 6, 5 ], [ 8, 7, 5 ] ] gap> RestrictedPartitionsWithoutRepetitions( 10^2, List([1..10], n->n^2 ) ); [ [ 100 ], [ 64, 36 ], [ 49, 25, 16, 9, 1 ] ]   4.1-4 NextProbablyPrimeInt NextProbablyPrimeInt( n )  function This function has been transferred from package RCWA. The function NextProbablyPrimeInt(n) does the same as NextPrimeInt(n) except that for reasons of performance it tests numbers only for IsProbablyPrimeInt(n) instead of IsPrimeInt(n). For large n, this function is much faster than NextPrimeInt(n)  Example   gap> n := 2^251; 3618502788666131106986593281521497120414687020801267626233049500247285301248 gap> NextProbablyPrimeInt( n ); 3618502788666131106986593281521497120414687020801267626233049500247285301313 gap> time;  1 gap> NextPrimeInt( n );  3618502788666131106986593281521497120414687020801267626233049500247285301313 gap> time;  213   4.1-5 PrimeNumbersIterator PrimeNumbersIterator( [chunksize] )  function This function has been transferred from package RCWA. This function returns an iterator which runs over the prime numbers n ascending order; it takes an optional argument chunksize which specifies the length of the interval which is sieved in one go (the default is 10^7), and which can be used to balance runtime vs. memory consumption. It is assumed that chunksize is larger than any gap between two consecutive primes within the range one intends to run the iterator over.  Example   gap> iter := PrimeNumbersIterator();; gap> for i in [1..100] do p := NextIterator(iter); od; gap> p; 541 gap> sum := 0;; gap> ## "prime number race" 1 vs. 3 mod 4 gap> for p in PrimeNumbersIterator() do  >  if p <> 2 then sum := sum + E(4)^(p-1); fi; >  if sum > 0 then break; fi; >  od; gap> p; 26861   utils-0.86/doc/chap5.txt000644 000765 000024 00000057727 14621610512 020241 0ustar00christopherwensleystaff000000 000000 5 Groups and homomorphisms 5.1 Functions for groups 5.1-1 Comm Comm( L )  operation This method has been transferred from package ResClasses. It provides a method for Comm when the argument is a list (enclosed in square brackets), and calls the function LeftNormedComm.  Example   gap> Comm( [ (1,2), (2,3) ] ); (1,2,3) gap> Comm( [(1,2),(2,3),(3,4),(4,5),(5,6)] ); (1,5,6) gap> Comm(Comm(Comm(Comm((1,2),(2,3)),(3,4)),(4,5)),(5,6)); ## the same (1,5,6)   5.1-2 IsCommuting IsCommuting( a, b )  operation This function has been transferred from package ResClasses. It tests whether two elements in a group commute.  Example   gap> D12 := DihedralGroup( 12 );  gap> SetName( D12, "D12" );  gap> a := D12.1;; b := D12.2;;  gap> IsCommuting( a, b ); false   5.1-3 ListOfPowers ListOfPowers( g, exp )  operation This function has been transferred from package RCWA. The operation ListOfPowers(g,exp) returns the list [g,g^2,...,g^exp] of powers of the element g.  Example   gap> ListOfPowers( 2, 20 ); [ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,  32768, 65536, 131072, 262144, 524288, 1048576 ] gap> ListOfPowers( (1,2,3)(4,5), 12 ); [ (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), (),  (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), () ] gap> ListOfPowers( D12.2, 6 ); [ f2, f3, f2*f3, f3^2, f2*f3^2, of ... ]   5.1-4 GeneratorsAndInverses GeneratorsAndInverses( G )  operation This function has been transferred from package RCWA. This operation returns a list containing the generators of G followed by the inverses of these generators.  Example   gap> GeneratorsAndInverses( D12 ); [ f1, f2, f3, f1, f2*f3^2, f3^2 ] gap> GeneratorsAndInverses( SymmetricGroup(5) );  [ (1,2,3,4,5), (1,2), (1,5,4,3,2), (1,2) ]   5.1-5 UpperFittingSeries UpperFittingSeries( G )  attribute LowerFittingSeries( G )  attribute FittingLength( G )  attribute These three functions have been transferred from package ResClasses. The upper and lower Fitting series and the Fitting length of a solvable group are described here: https://en.wikipedia.org/wiki/Fitting_length.  Example   gap> UpperFittingSeries( D12 ); LowerFittingSeries( D12 ); [ Group([ ]), Group([ f3, f2*f3 ]), Group([ f1, f3, f2*f3 ]) ] [ D12, Group([ f3 ]), Group([ ]) ] gap> FittingLength( D12 ); 2 gap> S4 := SymmetricGroup( 4 );; gap> UpperFittingSeries( S4 ); [ Group(()), Group([ (1,2)(3,4), (1,4)(2,3) ]), Group([ (1,2)(3,4), (1,4)  (2,3), (2,4,3) ]), Group([ (3,4), (2,3,4), (1,2)(3,4) ]) ] gap> List( last, StructureDescription ); [ "1", "C2 x C2", "A4", "S4" ] gap> LowerFittingSeries( S4 ); [ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,3)  (2,4) ]), Group(()) ] gap> List( last, StructureDescription ); [ "S4", "A4", "C2 x C2", "1" ] gap> FittingLength( S4); 3   5.2 Left Cosets for Groups 5.2-1 LeftCoset LeftCoset( g, U )  operation Since GAP uses right actions by default, the library contains the operation RightCoset(U,g) for constructing the right coset Ug of a subgroup U ≤ G and an element g ∈ G. It has been noted in the reference manual that, by inverting all the elements in Ug, the left coset g^-1U is obtained. Just for the sake of completeness, from August 2022 this package provides the operation LeftCoset(g,U) for constructing the left coset gU. Users are strongly recommended to continue to use RightCoset for all serious calculations, since left cosets have a much simpler implementation and do not behave exactly like right cosets. The methods for left cosets which are provided generally work by converting gU to Ug^-1; applying the equivalent method for right cosets; and, if necessary, converting back again to left cosets. G acts on gU by OnLeftInverse: (gU)^g_0 = g_0^-1*(gU) = (g_0^-1g)U.  Example   gap> lc1 := LeftCoset( (1,2,3), Group( [ (1,2), (3,4) ] ) );  LeftCoset((1,2,3),Group([ (1,2), (3,4) ])) gap> Representative( lc1 ); (1,2,3) gap> ActingDomain( lc1 ); Group([ (1,2), (3,4) ]) gap> AsSet( lc1 ); [ (2,3), (2,4,3), (1,2,3), (1,2,4,3) ] gap> (1,2,3) in lc1; true gap> lc2 := (2,4,3) * lc1;  LeftCoset((1,2,4),Group([ (1,2), (3,4) ])) gap> lc3 := lc1^(2,3,4);; gap> lc2 = lc3;  true   5.2-2 Inverse The inverse of the left coset gU is the right coset Ug^-1, and conversely. This is an abuse of the attribute Inverse, since the standard requirement, that x*x^-1 is an identity, does not hold.  Example   gap> rc1 := Inverse( lc1 );  RightCoset(Group([ (1,2), (3,4) ]),(1,3,2)) gap> rc4 := RightCoset( Group( (1,2), (2,3) ), (3,4) );  RightCoset(Group([ (1,2), (2,3) ]),(3,4)) gap> lc4 := Inverse( rc4 ); LeftCoset((3,4),Group([ (1,2), (2,3) ])) gap> Intersection( lc2, lc4 ); [ (2,3,4), (1,2,3,4) ]   5.3 Functions for group homomorphisms 5.3-1 EpimorphismByGenerators EpimorphismByGenerators( G, H )  operation This function has been transferred from package RCWA. It constructs a group homomorphism which maps the generators of G to those of H. Its intended use is when G is a free group, and a warning is printed when this is not the case. Note that anything may happen if the resulting map is not a homomorphism!  Example   gap> G := Group( (1,2,3), (3,4,5), (5,6,7), (7,8,9) );; gap> phi := EpimorphismByGenerators( FreeGroup("a","b","c","d"), G ); [ a, b, c, d ] -> [ (1,2,3), (3,4,5), (5,6,7), (7,8,9) ] gap> PreImagesRepresentativeNC( phi, (1,2,3,4,5,6,7,8,9) ); d*c*b*a gap> a := G.1;; b := G.2;; c := G.3;; d := G.4;; gap> d*c*b*a; (1,2,3,4,5,6,7,8,9) gap> ## note that it is easy to produce nonsense:  gap> epi := EpimorphismByGenerators( Group((1,2,3)), Group((8,9)) ); Warning: calling GroupHomomorphismByImagesNC without checks [ (1,2,3) ] -> [ (8,9) ] gap> IsGroupHomomorphism( epi ); true gap> Image( epi, (1,2,3) );  () gap> Image( epi, (1,3,2) ); (8,9)   5.3-2 Pullback Pullback( hom1, hom2 )  operation PullbackInfo( G )  attribute If ϕ_1 : G_1 -> H and ϕ_2 : G_2 -> H are two group homomorphisms with the same range, then their pullback is the subgroup of G_1 × G_2 consisting of those elements (g_1,g_2) such that ϕ_1 g_1 = ϕ_2 g_2. The attribute PullbackInfo of a pullback group P is similar to DirectProductInfo for a direct product of groups. Its value is a record with the following components: directProduct the direct product G_1 × G_2, and projections a list with the two projections onto G_1 and G_2. There are no embeddings in this record, but it is possible to use the embeddings into the direct product, see Embedding (Reference: Embedding).  Example   gap> s4 := Group( (1,2),(2,3),(3,4) );; gap> s3 := Group( (5,6),(6,7) );; gap> c3 := Subgroup( s3, [ (5,6,7) ] );; gap> f := GroupHomomorphismByImages( s4, s3,  >  [(1,2),(2,3),(3,4)], [(5,6),(6,7),(5,6)] );;  gap> i := GroupHomomorphismByImages( c3, s3, [(5,6,7)], [(5,6,7)] );;  gap> Pfi := Pullback( f, i ); Group([ (2,3,4)(5,7,6), (1,2)(3,4) ]) gap> StructureDescription( Pfi ); "A4" gap> info := PullbackInfo( Pfi ); rec( directProduct := Group([ (1,2), (2,3), (3,4), (5,6,7) ]),   projections := [ [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (2,3,4), (1,2)(3,4) ],   [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (5,7,6), () ] ] ) gap> g := (1,2,3)(5,6,7);;  gap> ImageElm( info!.projections[1], g ); (1,2,3) gap> ImageElm( info!.projections[2], g ); (5,6,7)  gap> dp := info!.directProduct;;  gap> a := ImageElm( Embedding( dp, 1 ), (1,4,3) );;  gap> b := ImageElm( Embedding( dp, 2 ), (5,7,6) );;  gap> a*b in Pfi; true   5.3-3 CentralProduct CentralProduct( G1, G2, Z1, Phi )  operation CentralProductInfo( G )  attribute This function was added by Thomas Breuer, following discussions with Hongyi Zhao (see https://github.com/gap-packages/hap/issues/73). Let G1 and G2 be two groups, Z1 be a central subgroup of G1, and Phi be an isomorphism from Z1 to a central subgroup of G2. The central product defined by these arguments is the factor group of the direct product of G1 and G2 by the central subgroup { (z, (Phi(z))^-1) : z ∈ Z1 }. The attribute CentralProductInfo of a group G that has been created by CentralProduct is similar to PullbackInfo (5.3-2) for pullback groups. Its value is a record with the following components. projection the epimorphism from the direct product of G1 and G2 to G, and phi the map Phi. Note that one can access the direct product as the Source (Reference: Source) value of the projection map, and one can access G1 and G2 as the two embeddings of this direct product, see Embedding (Reference: Embedding).  Example  gap> g1 := DihedralGroup( 8 );  gap> c1 := Centre( g1 ); Group([ f3 ]) gap> cp1 := CentralProduct( g1, g1, c1, IdentityMapping( c1 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp1 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> g2 := QuaternionGroup( 8 );  gap> c2 := Centre( g2 ); Group([ y2 ]) gap> cp2 := CentralProduct( g2, g2, c2, IdentityMapping( c2 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp2 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> info2 := CentralProductInfo( cp2 ); rec( phi := IdentityMapping( Group([ y2 ]) ),   projection := [ f1, f2, f3, f4, f5, f6 ] -> [ f1, f2, f5, f3, f4, f5 ] ) gap> Source( Embedding( Source( info2.projection ), 1 ) ) = g2; true  5.3-4 IdempotentEndomorphisms IdempotentEndomorphisms( G )  operation IdempotentEndomorphismsData( G )  attribute IdempotentEndomorphismsWithImage( genG, R )  operation An endomorphism f : G -> G is idempotent if f^2=f. It has an image R leqslant G; is the identity map when restricted to R; and has a kernel N which has trivial intersection with R and has size |G|/|R|. The operation IdempotentEndomorphismsWithImage(genG,R) returns a list of the images of the generating set genG of a group G under the idempotent endomorphisms with image R. The attribute IdempotentEndomorphismsData(G) returns a record data with fields data.gens, a fixed generating set for G, and data.images a list of the non-empty outputs of IdempotentEndomorphismsWithImage(genG,R) obtained by iterating over all subgroups of G. The operation IdempotentEndomorphisms(G) returns the list of these mappings obtained using IdempotentEndomorphismsData(G). The first of these is the zero map, the second is the identity.  Example   gap> gens := [ (1,2,3,4), (1,2)(3,4) ];;  gap> d8 := Group( gens );; gap> SetName( d8, "d8" ); gap> c2 := Subgroup( d8, [ (2,4) ] );; gap> IdempotentEndomorphismsWithImage( gens, c2 ); [ [ (), (2,4) ], [ (2,4), () ] ] gap> IdempotentEndomorphismsData( d8 ); rec( gens := [ (1,2,3,4), (1,2)(3,4) ],   images := [ [ [ (), () ] ], [ [ (), (2,4) ], [ (2,4), () ] ],   [ [ (), (1,3) ], [ (1,3), () ] ],   [ [ (), (1,2)(3,4) ], [ (1,2)(3,4), (1,2)(3,4) ] ],   [ [ (), (1,4)(2,3) ], [ (1,4)(2,3), (1,4)(2,3) ] ],   [ [ (1,2,3,4), (1,2)(3,4) ] ] ] ) gap> List( last.images, L -> Length(L) ); [ 1, 2, 2, 2, 2, 1 ] gap> IdempotentEndomorphisms( d8 );  [ [ (1,2,3,4), (1,2)(3,4) ] -> [ (), () ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (2,4) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (2,4), () ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,3) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,3), () ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,2)(3,4) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2)(3,4), (1,2)(3,4) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,4)(2,3) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,4)(2,3), (1,4)(2,3) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2,3,4), (1,2)(3,4) ] ]   The quaternion group q8 is an example of a group with a tail: there is only one subgroup in the lattice which covers the identity subgroup. The only idempotent isomorphisms of such groups are the identity mapping and the zero mapping because the only pairs N,R are the whole group and the identity subgroup.  Example   gap> q8 := QuaternionGroup( 8 );; gap> IdempotentEndomorphisms( q8 ); [ [ x, y ] -> [ of ..., of ... ], [ x, y ] -> [ x, y ] ]   5.3-5 DirectProductOfFunctions DirectProductOfFunctions( G, H, f1, f2 )  operation Given group homomorphisms f_1 : G_1 -> G_2 and f_2 : H_1 -> H_2, this operation return the product homomorphism f_1 × f_2 : G_1 × G_2 -> H_1 × H_2.  Example   gap> c4 := Group( (1,2,3,4) );;  gap> c2 := Group( (5,6) );;  gap> f1 := GroupHomomorphismByImages( c4, c2, [(1,2,3,4)], [(5,6)] );; gap> c3 := Group( (1,2,3) );;  gap> c6 := Group( (1,2,3,4,5,6) );;  gap> f2 := GroupHomomorphismByImages( c3, c6, [(1,2,3)], [(1,3,5)(2,4,6)] );;  gap> c4c3 := DirectProduct( c4, c3 );  Group([ (1,2,3,4), (5,6,7) ]) gap> c2c6 := DirectProduct( c2, c6 );  Group([ (1,2), (3,4,5,6,7,8) ]) gap> f := DirectProductOfFunctions( c4c3, c2c6, f1, f2 );  [ (1,2,3,4), (5,6,7) ] -> [ (1,2), (3,5,7)(4,6,8) ] gap> ImageElm( f, (1,4,3,2)(5,7,6) );  (1,2)(3,7,5)(4,8,6)   5.3-6 DirectProductOfAutomorphismGroups DirectProductOfAutomorphismGroups( A1, A2 )  operation Let A_1,A_2 be groups of automorphism of groups G_1,G_2 respectively. The output of this function is a group A_1 × A_2 of automorphisms of G_1 × G_2.  Example   gap> c9 := Group( (1,2,3,4,5,6,7,8,9) );;  gap> ac9 := AutomorphismGroup( c9 );;  gap> q8 := QuaternionGroup( IsPermGroup, 8 );; gap> aq8 := AutomorphismGroup( q8 );; gap> A := DirectProductOfAutomorphismGroups( ac9, aq8 );  gap> genA := GeneratorsOfGroup( A );; gap> G := Source( genA[1] ); Group([ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13) (14,15,16,17) ]) gap> a := genA[1]*genA[5];  [ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)(14,15,16,17)   ] -> [ (1,3,5,7,9,2,4,6,8), (10,16,12,14)(11,15,13,17),   (10,11,12,13)(14,15,16,17) ] gap> ImageElm( a, (1,9,8,7,6,5,4,3,2)(10,14,12,16)(11,17,13,15) ); (1,8,6,4,2,9,7,5,3)(10,16,12,14)(11,15,13,17)   utils-0.86/doc/ragged.css000644 000765 000024 00000000231 14621610515 020420 0ustar00christopherwensleystaff000000 000000 /* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { text-align: left; } utils-0.86/doc/chap1.html000644 000765 000024 00000020726 14621610515 020352 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 1: Introduction
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

1 Introduction

The Utils package provides a space for utility functions from a variety of GAP packages to be collected together into a single package. In this way it is hoped that they will become more visible to other package authors. This package was first distributed as part of the GAP 4.8.2 distribution.

The package is loaded with the command


gap> LoadPackage( "utils" ); 

Functions have been transferred from the following packages:

  • Conversion of a GAP group to a Magma output string, taken from various sources including other.gi in the main library.

Transfer is complete (for now) for functions from the following packages:

The package may be obtained either as a compressed .tar file or as a .zip file, utils-version_number.tar.gz, by ftp from one of the following sites:

The package also has a GitHub repository at: https://github.com/gap-packages/utils.

Once the package is loaded, the manual doc/manual.pdf can be found in the documentation folder. The html versions, with or without MathJax, may be rebuilt as follows:


gap> ReadPackage( "utils", "makedoc.g" ); 

It is possible to check that the package has been installed correctly by running the test files (which terminates the GAP session):


gap> ReadPackage( "utils", "tst/testall.g" );
Architecture: . . . . . 
testing: . . . . . 
. . . 
#I  No errors detected while testing

Note that functions listed in this manual that are currently in the process of being transferred are only read from the source package Home (say), and so can only be used if Home has already been loaded. There are no such functions in transition at present.

1.1 Information for package authors

A function (or collection of functions) is suitable for transfer from a package Home to Utils if the following conditions are satisfied.

  • The function is sufficiently non-specialised so that it might be of use to other authors.

  • The function does not depend on the remaining functions in Home

  • The function does not do what can already be done with a GAP library function.

  • Documentation of the function and test examples are available.

  • When there is more than one active author of Home, they should all be aware (and content) that the transfer is taking place.

Authors of packages may be reluctant to let go of their utility functions. The following principles may help to reassure them. (Suggestions for more items here are welcome.)

  • A function that has been transferred to Utils will not be changed without the approval of the original author.

  • The current package maintainer has every intention of continuing to maintain Utils. In the event that this proves impossible, the GAP development team will surely find someone to take over.

  • Function names will not be changed unless specifically requested by Home's author(s) or unless they have the form HOME_FunctionName.

  • In order to speed up the transfer process, only functions from one package will be in transition at any given time. Hopefully a week or two will suffice for most packages.

  • Any package author who transfers a function to Utils will become an author of Utils. (In truth, Utils does not have authors, just a large number of contributors.)

The process for transferring utility functions from Home to Utils is described in Chapter 12.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chap5_mj.html000644 000765 000024 00000104727 14621610515 021050 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 5: Groups and homomorphisms
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

5 Groups and homomorphisms

5.1 Functions for groups

5.1-1 Comm
‣ Comm( L )( operation )

This method has been transferred from package ResClasses.

It provides a method for Comm when the argument is a list (enclosed in square brackets), and calls the function LeftNormedComm.


gap> Comm( [ (1,2), (2,3) ] );
(1,2,3)
gap> Comm( [(1,2),(2,3),(3,4),(4,5),(5,6)] );
(1,5,6)
gap> Comm(Comm(Comm(Comm((1,2),(2,3)),(3,4)),(4,5)),(5,6));  ## the same
(1,5,6)

5.1-2 IsCommuting
‣ IsCommuting( a, b )( operation )

This function has been transferred from package ResClasses.

It tests whether two elements in a group commute.


gap> D12 := DihedralGroup( 12 );
<pc group of size 12 with 3 generators>
gap> SetName( D12, "D12" ); 
gap> a := D12.1;;  b := D12.2;;  
gap> IsCommuting( a, b );
false

5.1-3 ListOfPowers
‣ ListOfPowers( g, exp )( operation )

This function has been transferred from package RCWA.

The operation ListOfPowers(g,exp) returns the list \([g,g^2,...,g^{exp}]\) of powers of the element \(g\).


gap> ListOfPowers( 2, 20 );
[ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
 32768, 65536, 131072, 262144, 524288, 1048576 ]
gap> ListOfPowers( (1,2,3)(4,5), 12 );
[ (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), (),
 (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), () ]
gap> ListOfPowers( D12.2, 6 );
[ f2, f3, f2*f3, f3^2, f2*f3^2, <identity> of ... ]

5.1-4 GeneratorsAndInverses
‣ GeneratorsAndInverses( G )( operation )

This function has been transferred from package RCWA.

This operation returns a list containing the generators of \(G\) followed by the inverses of these generators.


gap> GeneratorsAndInverses( D12 );
[ f1, f2, f3, f1, f2*f3^2, f3^2 ]
gap> GeneratorsAndInverses( SymmetricGroup(5) );     
[ (1,2,3,4,5), (1,2), (1,5,4,3,2), (1,2) ]

5.1-5 UpperFittingSeries
‣ UpperFittingSeries( G )( attribute )
‣ LowerFittingSeries( G )( attribute )
‣ FittingLength( G )( attribute )

These three functions have been transferred from package ResClasses.

The upper and lower Fitting series and the Fitting length of a solvable group are described here: https://en.wikipedia.org/wiki/Fitting_length.


gap> UpperFittingSeries( D12 );  LowerFittingSeries( D12 );
[ Group([  ]), Group([ f3, f2*f3 ]), Group([ f1, f3, f2*f3 ]) ]
[ D12, Group([ f3 ]), Group([  ]) ]
gap> FittingLength( D12 );
2
gap> S4 := SymmetricGroup( 4 );;
gap> UpperFittingSeries( S4 );
[ Group(()), Group([ (1,2)(3,4), (1,4)(2,3) ]), Group([ (1,2)(3,4), (1,4)
  (2,3), (2,4,3) ]), Group([ (3,4), (2,3,4), (1,2)(3,4) ]) ]
gap> List( last, StructureDescription );
[ "1", "C2 x C2", "A4", "S4" ]
gap> LowerFittingSeries( S4 );
[ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,3)
 (2,4) ]), Group(()) ]
gap> List( last, StructureDescription );
[ "S4", "A4", "C2 x C2", "1" ]
gap> FittingLength( S4);
3

5.2 Left Cosets for Groups

5.2-1 LeftCoset
‣ LeftCoset( g, U )( operation )

Since GAP uses right actions by default, the library contains the operation RightCoset(U,g) for constructing the right coset \(Ug\) of a subgroup \(U \leq G\) and an element \(g \in G\). It has been noted in the reference manual that, by inverting all the elements in \(Ug\), the left coset \(g^{-1}U\) is obtained.

Just for the sake of completeness, from August 2022 this package provides the operation LeftCoset(g,U) for constructing the left coset \(gU\). Users are strongly recommended to continue to use RightCoset for all serious calculations, since left cosets have a much simpler implementation and do not behave exactly like right cosets.

The methods for left cosets which are provided generally work by converting \(gU\) to \(Ug^{-1}\); applying the equivalent method for right cosets; and, if necessary, converting back again to left cosets.

\(G\) acts on \(gU\) by OnLeftInverse: \((gU)^{g_0} = g_0^{-1}*(gU) = (g_0^{-1}g)U\).


gap> lc1 := LeftCoset( (1,2,3), Group( [ (1,2), (3,4) ] ) ); 
LeftCoset((1,2,3),Group([ (1,2), (3,4) ]))
gap> Representative( lc1 );
(1,2,3)
gap> ActingDomain( lc1 );
Group([ (1,2), (3,4) ])
gap> AsSet( lc1 );
[ (2,3), (2,4,3), (1,2,3), (1,2,4,3) ]
gap> (1,2,3) in lc1;
true
gap> lc2 := (2,4,3) * lc1;   
LeftCoset((1,2,4),Group([ (1,2), (3,4) ]))
gap> lc3 := lc1^(2,3,4);;
gap> lc2 = lc3;            
true

5.2-2 Inverse

The inverse of the left coset \(gU\) is the right coset \(Ug^{-1}\), and conversely. This is an abuse of the attribute Inverse, since the standard requirement, that \(x*x^{-1}\) is an identity, does not hold.


gap> rc1 := Inverse( lc1 ); 
RightCoset(Group([ (1,2), (3,4) ]),(1,3,2))
gap> rc4 := RightCoset( Group( (1,2), (2,3) ), (3,4) ); 
RightCoset(Group([ (1,2), (2,3) ]),(3,4))
gap> lc4 := Inverse( rc4 );
LeftCoset((3,4),Group([ (1,2), (2,3) ]))
gap> Intersection( lc2, lc4 );
[ (2,3,4), (1,2,3,4) ]

5.3 Functions for group homomorphisms

5.3-1 EpimorphismByGenerators
‣ EpimorphismByGenerators( G, H )( operation )

This function has been transferred from package RCWA.

It constructs a group homomorphism which maps the generators of \(G\) to those of \(H\). Its intended use is when \(G\) is a free group, and a warning is printed when this is not the case. Note that anything may happen if the resulting map is not a homomorphism!


gap> G := Group( (1,2,3), (3,4,5), (5,6,7), (7,8,9) );;
gap> phi := EpimorphismByGenerators( FreeGroup("a","b","c","d"), G );
[ a, b, c, d ] -> [ (1,2,3), (3,4,5), (5,6,7), (7,8,9) ]
gap> PreImagesRepresentativeNC( phi, (1,2,3,4,5,6,7,8,9) );
d*c*b*a
gap> a := G.1;; b := G.2;; c := G.3;; d := G.4;;
gap> d*c*b*a;
(1,2,3,4,5,6,7,8,9)
gap> ## note that it is easy to produce nonsense: 
gap> epi := EpimorphismByGenerators( Group((1,2,3)), Group((8,9)) );
Warning: calling GroupHomomorphismByImagesNC without checks
[ (1,2,3) ] -> [ (8,9) ]
gap> IsGroupHomomorphism( epi );
true
gap> Image( epi, (1,2,3) );                                            
()
gap> Image( epi, (1,3,2) );
(8,9)

5.3-2 Pullback
‣ Pullback( hom1, hom2 )( operation )
‣ PullbackInfo( G )( attribute )

If \(\phi_1 : G_1 \to H\) and \(\phi_2 : G_2 \to H\) are two group homomorphisms with the same range, then their pullback is the subgroup of \(G_1 \times G_2\) consisting of those elements \((g_1,g_2)\) such that \(\phi_1 g_1 = \phi_2 g_2\).

The attribute PullbackInfo of a pullback group P is similar to DirectProductInfo for a direct product of groups. Its value is a record with the following components:

directProduct

the direct product \(G_1 \times G_2\), and

projections

a list with the two projections onto \(G_1\) and \(G_2\).

There are no embeddings in this record, but it is possible to use the embeddings into the direct product, see Embedding (Reference: Embedding).


gap> s4 := Group( (1,2),(2,3),(3,4) );;
gap> s3 := Group( (5,6),(6,7) );;
gap> c3 := Subgroup( s3, [ (5,6,7) ] );;
gap> f := GroupHomomorphismByImages( s4, s3, 
>             [(1,2),(2,3),(3,4)], [(5,6),(6,7),(5,6)] );; 
gap> i := GroupHomomorphismByImages( c3, s3, [(5,6,7)], [(5,6,7)] );; 
gap> Pfi := Pullback( f, i );
Group([ (2,3,4)(5,7,6), (1,2)(3,4) ])
gap> StructureDescription( Pfi );
"A4"
gap> info := PullbackInfo( Pfi );
rec( directProduct := Group([ (1,2), (2,3), (3,4), (5,6,7) ]), 
  projections := [ [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (2,3,4), (1,2)(3,4) ], 
      [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (5,7,6), () ] ] )
gap> g := (1,2,3)(5,6,7);; 
gap> ImageElm( info!.projections[1], g );
(1,2,3)
gap> ImageElm( info!.projections[2], g );
(5,6,7) 
gap> dp := info!.directProduct;; 
gap> a := ImageElm( Embedding( dp, 1 ), (1,4,3) );; 
gap> b := ImageElm( Embedding( dp, 2 ), (5,7,6) );; 
gap> a*b in Pfi;
true

5.3-3 CentralProduct
‣ CentralProduct( G1, G2, Z1, Phi )( operation )
‣ CentralProductInfo( G )( attribute )

This function was added by Thomas Breuer, following discussions with Hongyi Zhao (see https://github.com/gap-packages/hap/issues/73).

Let G1 and G2 be two groups, Z1 be a central subgroup of G1, and Phi be an isomorphism from Z1 to a central subgroup of G2. The central product defined by these arguments is the factor group of the direct product of G1 and G2 by the central subgroup \(\{ (z, (\textit{Phi}(z))^{-1}) : z \in \textit{Z1} \}\).

The attribute CentralProductInfo of a group \(G\) that has been created by CentralProduct is similar to PullbackInfo (5.3-2) for pullback groups. Its value is a record with the following components.

projection

the epimorphism from the direct product of G1 and G2 to \(G\), and

phi

the map Phi.

Note that one can access the direct product as the Source (Reference: Source) value of the projection map, and one can access G1 and G2 as the two embeddings of this direct product, see Embedding (Reference: Embedding).

gap> g1 := DihedralGroup( 8 );
<pc group of size 8 with 3 generators>
gap> c1 := Centre( g1 );
Group([ f3 ])
gap> cp1 := CentralProduct( g1, g1, c1, IdentityMapping( c1 ) );
Group([ f1, f2, f5, f3, f4, f5 ])
gap> IdGroup( cp1 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) );
true
gap> g2 := QuaternionGroup( 8 );
<pc group of size 8 with 3 generators>
gap> c2 := Centre( g2 );
Group([ y2 ])
gap> cp2 := CentralProduct( g2, g2, c2, IdentityMapping( c2 ) );
Group([ f1, f2, f5, f3, f4, f5 ])
gap> IdGroup( cp2 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) );
true
gap> info2 := CentralProductInfo( cp2 );
rec( phi := IdentityMapping( Group([ y2 ]) ), 
  projection := [ f1, f2, f3, f4, f5, f6 ] -> [ f1, f2, f5, f3, f4, f5 ] )
gap> Source( Embedding( Source( info2.projection ), 1 ) ) = g2;
true

5.3-4 IdempotentEndomorphisms
‣ IdempotentEndomorphisms( G )( operation )
‣ IdempotentEndomorphismsData( G )( attribute )
‣ IdempotentEndomorphismsWithImage( genG, R )( operation )

An endomorphism \(f : G \to G\) is idempotent if \(f^2=f\). It has an image \(R \leqslant G\); is the identity map when restricted to \(R\); and has a kernel \(N\) which has trivial intersection with \(R\) and has size \(|G|/|R|\).

The operation IdempotentEndomorphismsWithImage(genG,R) returns a list of the images of the generating set genG of a group \(G\) under the idempotent endomorphisms with image \(R\).

The attribute IdempotentEndomorphismsData(G) returns a record data with fields data.gens, a fixed generating set for \(G\), and data.images a list of the non-empty outputs of IdempotentEndomorphismsWithImage(genG,R) obtained by iterating over all subgroups of \(G\).

The operation IdempotentEndomorphisms(G) returns the list of these mappings obtained using IdempotentEndomorphismsData(G). The first of these is the zero map, the second is the identity.


gap> gens := [ (1,2,3,4), (1,2)(3,4) ];; 
gap> d8 := Group( gens );;
gap> SetName( d8, "d8" );
gap> c2 := Subgroup( d8, [ (2,4) ] );;
gap> IdempotentEndomorphismsWithImage( gens, c2 );
[ [ (), (2,4) ], [ (2,4), () ] ]
gap> IdempotentEndomorphismsData( d8 );
rec( gens := [ (1,2,3,4), (1,2)(3,4) ], 
  images := [ [ [ (), () ] ], [ [ (), (2,4) ], [ (2,4), () ] ], 
      [ [ (), (1,3) ], [ (1,3), () ] ], 
      [ [ (), (1,2)(3,4) ], [ (1,2)(3,4), (1,2)(3,4) ] ], 
      [ [ (), (1,4)(2,3) ], [ (1,4)(2,3), (1,4)(2,3) ] ], 
      [ [ (1,2,3,4), (1,2)(3,4) ] ] ] )
gap> List( last.images, L -> Length(L) );
[ 1, 2, 2, 2, 2, 1 ]
gap> IdempotentEndomorphisms( d8 );               
[ [ (1,2,3,4), (1,2)(3,4) ] -> [ (), () ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (2,4) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (2,4), () ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,3) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,3), () ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,2)(3,4) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2)(3,4), (1,2)(3,4) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,4)(2,3) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,4)(2,3), (1,4)(2,3) ], 
  [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2,3,4), (1,2)(3,4) ] ]

The quaternion group q8 is an example of a group with a tail: there is only one subgroup in the lattice which covers the identity subgroup. The only idempotent isomorphisms of such groups are the identity mapping and the zero mapping because the only pairs \(N,R\) are the whole group and the identity subgroup.


gap> q8 := QuaternionGroup( 8 );;
gap> IdempotentEndomorphisms( q8 );
[ [ x, y ] -> [ <identity> of ..., <identity> of ... ], [ x, y ] -> [ x, y ] ]

5.3-5 DirectProductOfFunctions
‣ DirectProductOfFunctions( G, H, f1, f2 )( operation )

Given group homomorphisms \(f_1 : G_1 \to G_2\) and \(f_2 : H_1 \to H_2\), this operation return the product homomorphism \(f_1 \times f_2 : G_1 \times G_2 \to H_1 \times H_2\).


gap> c4 := Group( (1,2,3,4) );; 
gap> c2 := Group( (5,6) );; 
gap> f1 := GroupHomomorphismByImages( c4, c2, [(1,2,3,4)], [(5,6)] );;
gap> c3 := Group( (1,2,3) );; 
gap> c6 := Group( (1,2,3,4,5,6) );; 
gap> f2 := GroupHomomorphismByImages( c3, c6, [(1,2,3)], [(1,3,5)(2,4,6)] );; 
gap> c4c3 := DirectProduct( c4, c3 ); 
Group([ (1,2,3,4), (5,6,7) ])
gap> c2c6 := DirectProduct( c2, c6 ); 
Group([ (1,2), (3,4,5,6,7,8) ])
gap> f := DirectProductOfFunctions( c4c3, c2c6, f1, f2 ); 
[ (1,2,3,4), (5,6,7) ] -> [ (1,2), (3,5,7)(4,6,8) ]
gap> ImageElm( f, (1,4,3,2)(5,7,6) ); 
(1,2)(3,7,5)(4,8,6)

5.3-6 DirectProductOfAutomorphismGroups
‣ DirectProductOfAutomorphismGroups( A1, A2 )( operation )

Let \(A_1,A_2\) be groups of automorphism of groups \(G_1,G_2\) respectively. The output of this function is a group \(A_1 \times A_2\) of automorphisms of \(G_1 \times G_2\).


gap> c9 := Group( (1,2,3,4,5,6,7,8,9) );; 
gap> ac9 := AutomorphismGroup( c9 );; 
gap> q8 := QuaternionGroup( IsPermGroup, 8 );;
gap> aq8 := AutomorphismGroup( q8 );;
gap> A := DirectProductOfAutomorphismGroups( ac9, aq8 );
<group with 5 generators>
gap> genA := GeneratorsOfGroup( A );;
gap> G := Source( genA[1] );
Group([ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)
(14,15,16,17) ])
gap> a := genA[1]*genA[5];  
[ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)(14,15,16,17) 
 ] -> [ (1,3,5,7,9,2,4,6,8), (10,16,12,14)(11,15,13,17), 
  (10,11,12,13)(14,15,16,17) ]
gap> ImageElm( a, (1,9,8,7,6,5,4,3,2)(10,14,12,16)(11,17,13,15) );
(1,8,6,4,2,9,7,5,3)(10,16,12,14)(11,15,13,17)

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/toggless.js000644 000765 000024 00000004205 14621610515 020647 0ustar00christopherwensleystaff000000 000000 /* toggless.js Frank Lübeck */ /* this file contains two functions: mergeSideTOCHooks: this changes div.ContSect elements to the class ContSectClosed and includes a hook to toggle between ContSectClosed and ContSectOpen. openclosetoc: this function does the toggling, the rest is done by CSS */ closedTOCMarker = "▶ "; openTOCMarker = "▼ "; noTOCMarker = " "; /* merge hooks into side toc for opening/closing subsections with openclosetoc */ function mergeSideTOCHooks() { var hlist = document.getElementsByTagName("div"); for (var i = 0; i < hlist.length; i++) { if (hlist[i].className == "ContSect") { var chlds = hlist[i].childNodes; var el = document.createElement("span"); var oncl = document.createAttribute("class"); oncl.nodeValue = "toctoggle"; el.setAttributeNode(oncl); var cont; if (chlds.length > 2) { var oncl = document.createAttribute("onclick"); oncl.nodeValue = "openclosetoc(event)"; el.setAttributeNode(oncl); cont = document.createTextNode(closedTOCMarker); } else { cont = document.createTextNode(noTOCMarker); } el.appendChild(cont); hlist[i].firstChild.insertBefore(el, hlist[i].firstChild.firstChild); hlist[i].className = "ContSectClosed"; } } } function openclosetoc (event) { /* first two steps to make it work in most browsers */ var evt=window.event || event; if (!evt.target) evt.target=evt.srcElement; var markClosed = document.createTextNode(closedTOCMarker); var markOpen = document.createTextNode(openTOCMarker); var par = evt.target.parentNode.parentNode; if (par.className == "ContSectOpen") { par.className = "ContSectClosed"; evt.target.replaceChild(markClosed, evt.target.firstChild); } else if (par.className == "ContSectClosed") { par.className = "ContSectOpen"; evt.target.replaceChild(markOpen, evt.target.firstChild); } } /* adjust jscontent which is called onload */ jscontentfuncs.push(mergeSideTOCHooks); utils-0.86/doc/iterator.xml000644 000765 000024 00000012325 14621444241 021040 0ustar00christopherwensleystaff000000 000000 Iterators
Some iterators for groups and their isomorphisms Iterators The motivation for adding these operations is partly to give a simple example of an iterator for a list that does not yet exist, and need not be created.

The main &GAP; library contains functions producing complete lists of group homomorphisms such as AllHomomorphisms; AllEndomorphisms and AllAutomorphisms. Here we add the missing AllIsomorphisms(G,H) for a list of isomorphisms from G to H. The method is simple -- find one isomorphism G \to H and compose this with all the automorphisms of G. In all these cases it may not be desirable to construct a list of homomorphisms, but just implement an iterator, and that is what is done here. The operation AllIsomorphismsNumber returns the number of isomorphisms iterated over (this is, of course, just the order of the automorphisms group). The operation AllIsomorphisms produces the list or isomorphisms.

G := SmallGroup( 6,1);; gap> iter := AllIsomorphismsIterator( G, s3 );; gap> NextIterator( iter ); [ f1, f2 ] -> [ (6,7), (5,6,7) ] gap> n := AllIsomorphismsNumber( G, s3 ); 6 gap> AllIsomorphisms( G, s3 ); [ [ f1, f2 ] -> [ (6,7), (5,6,7) ], [ f1, f2 ] -> [ (5,7), (5,6,7) ], [ f1, f2 ] -> [ (5,6), (5,7,6) ], [ f1, f2 ] -> [ (6,7), (5,7,6) ], [ f1, f2 ] -> [ (5,7), (5,7,6) ], [ f1, f2 ] -> [ (5,6), (5,6,7) ] ] gap> iter := AllIsomorphismsIterator( G, s3 );; gap> for h in iter do Print( ImageElm( h, G.1 ) = (6,7), ", " ); od; true, false, false, true, false, false, ]]> The manual entry for the operation AllSubgroups states that it is only intended to be used on small examples in a classroom situation. Access to all subgroups was required by the XMod package, so this iterator was introduced here. It used the operations LatticeSubgroups(G) and ConjugacyClassesSubgroups(lat), and then iterates over the entries in these classes.

c3c3 := Group( (1,2,3), (4,5,6) );; gap> iter := AllSubgroupsIterator( c3c3 ); gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od; Group( () ) Group( [ (4,5,6) ] ) Group( [ (1,2,3) ] ) Group( [ (1,2,3)(4,5,6) ] ) Group( [ (1,3,2)(4,5,6) ] ) Group( [ (4,5,6), (1,2,3) ] ) ]]>

Operations on iterators This section considers ways of producing an iterator from one or more iterators. It may be that operations equivalent to these are available elsewhere in the library -- if so, the ones here can be removed in due course. This iterator returns all pairs [x,y] where x is the output of a first iterator and y is the output of a second iterator.

it1 := Iterator( [ 1, 2, 3 ] );; gap> it2 := Iterator( [ 4, 5, 6 ] );; gap> iter := CartesianIterator( it1, it2 );; gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od; [ 1, 4 ] [ 1, 5 ] [ 1, 6 ] [ 2, 4 ] [ 2, 5 ] [ 2, 6 ] [ 3, 4 ] [ 3, 5 ] [ 3, 6 ] ]]> This operation returns pairs [x,y] where x,y are output from a given iterator iter. Unlike the output from CartesianIterator(iter,iter), unordered pairs are returned. In the case L = [1,2,3,\ldots] the pairs are ordered as [1,1],[1,2],[2,2],[1,3],[2,3],[3,3],\ldots.

L := [6,7,8,9];; gap> iterL := IteratorList( L );; gap> pairsL := UnorderedPairsIterator( iterL );; gap> while not IsDoneIterator(pairsL) do Print(NextIterator(pairsL),"\n"); od; [ 6, 6 ] [ 6, 7 ] [ 7, 7 ] [ 6, 8 ] [ 7, 8 ] [ 8, 8 ] [ 6, 9 ] [ 7, 9 ] [ 8, 9 ] [ 9, 9 ] gap> iter4 := IteratorList( [ 4 ] ); gap> pairs4 := UnorderedPairsIterator(iter4); gap> NextIterator( pairs4 ); [ 4, 4 ] gap> IsDoneIterator( pairs4 ); true ]]>

utils-0.86/doc/chap7.txt000644 000765 000024 00000015723 14621610512 020231 0ustar00christopherwensleystaff000000 000000 7 Iterators 7.1 Some iterators for groups and their isomorphisms The motivation for adding these operations is partly to give a simple example of an iterator for a list that does not yet exist, and need not be created. 7.1-1 AllIsomorphismsIterator AllIsomorphismsIterator( G, H )  operation AllIsomorphismsNumber( G, H )  operation AllIsomorphisms( G, H )  operation The main GAP library contains functions producing complete lists of group homomorphisms such as AllHomomorphisms; AllEndomorphisms and AllAutomorphisms. Here we add the missing AllIsomorphisms(G,H) for a list of isomorphisms from G to H. The method is simple -- find one isomorphism G -> H and compose this with all the automorphisms of G. In all these cases it may not be desirable to construct a list of homomorphisms, but just implement an iterator, and that is what is done here. The operation AllIsomorphismsNumber returns the number of isomorphisms iterated over (this is, of course, just the order of the automorphisms group). The operation AllIsomorphisms produces the list or isomorphisms.  Example   gap> G := SmallGroup( 6,1);;  gap> iter := AllIsomorphismsIterator( G, s3 );; gap> NextIterator( iter ); [ f1, f2 ] -> [ (6,7), (5,6,7) ] gap> n := AllIsomorphismsNumber( G, s3 ); 6 gap> AllIsomorphisms( G, s3 ); [ [ f1, f2 ] -> [ (6,7), (5,6,7) ], [ f1, f2 ] -> [ (5,7), (5,6,7) ],   [ f1, f2 ] -> [ (5,6), (5,7,6) ], [ f1, f2 ] -> [ (6,7), (5,7,6) ],   [ f1, f2 ] -> [ (5,7), (5,7,6) ], [ f1, f2 ] -> [ (5,6), (5,6,7) ] ] gap> iter := AllIsomorphismsIterator( G, s3 );; gap> for h in iter do Print( ImageElm( h, G.1 ) = (6,7), ", " ); od; true, false, false, true, false, false,   7.1-2 AllSubgroupsIterator AllSubgroupsIterator( G )  operation The manual entry for the operation AllSubgroups states that it is only intended to be used on small examples in a classroom situation. Access to all subgroups was required by the XMod package, so this iterator was introduced here. It used the operations LatticeSubgroups(G) and ConjugacyClassesSubgroups(lat), and then iterates over the entries in these classes.  Example   gap> c3c3 := Group( (1,2,3), (4,5,6) );;  gap> iter := AllSubgroupsIterator( c3c3 );  gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od; Group( () ) Group( [ (4,5,6) ] ) Group( [ (1,2,3) ] ) Group( [ (1,2,3)(4,5,6) ] ) Group( [ (1,3,2)(4,5,6) ] ) Group( [ (4,5,6), (1,2,3) ] )   7.2 Operations on iterators This section considers ways of producing an iterator from one or more iterators. It may be that operations equivalent to these are available elsewhere in the library -- if so, the ones here can be removed in due course. 7.2-1 CartesianIterator CartesianIterator( iter1, iter2 )  operation This iterator returns all pairs [x,y] where x is the output of a first iterator and y is the output of a second iterator.  Example   gap> it1 := Iterator( [ 1, 2, 3 ] );; gap> it2 := Iterator( [ 4, 5, 6 ] );; gap> iter := CartesianIterator( it1, it2 );; gap> while not IsDoneIterator(iter) do Print(NextIterator(iter),"\n"); od; [ 1, 4 ] [ 1, 5 ] [ 1, 6 ] [ 2, 4 ] [ 2, 5 ] [ 2, 6 ] [ 3, 4 ] [ 3, 5 ] [ 3, 6 ]   7.2-2 UnorderedPairsIterator UnorderedPairsIterator( iter )  operation This operation returns pairs [x,y] where x,y are output from a given iterator iter. Unlike the output from CartesianIterator(iter,iter), unordered pairs are returned. In the case L = [1,2,3,...] the pairs are ordered as [1,1],[1,2],[2,2],[1,3],[2,3],[3,3],....  Example   gap> L := [6,7,8,9];; gap> iterL := IteratorList( L );;  gap> pairsL := UnorderedPairsIterator( iterL );;  gap> while not IsDoneIterator(pairsL) do Print(NextIterator(pairsL),"\n"); od; [ 6, 6 ] [ 6, 7 ] [ 7, 7 ] [ 6, 8 ] [ 7, 8 ] [ 8, 8 ] [ 6, 9 ] [ 7, 9 ] [ 8, 9 ] [ 9, 9 ] gap> iter4 := IteratorList( [ 4 ] );  gap> pairs4 := UnorderedPairsIterator(iter4);  gap> NextIterator( pairs4 ); [ 4, 4 ] gap> IsDoneIterator( pairs4 ); true   utils-0.86/doc/chap6.txt000644 000765 000024 00000012276 14621610512 020230 0ustar00christopherwensleystaff000000 000000 6 Matrices 6.1 Some operations for matrices 6.1-1 DirectSumDecompositionMatrices DirectSumDecompositionMatrices( M )  operation In June 2023 Hongyi Zhao asked in the Forum for a function to implement matrix decomposition into blocks. Such a function was then provided by Pedro García-Sánchez. Hongyi Zhao then requested that the function be added to Utils. What is provided here is a revised version of the original solution, returning a list of decompositions. This function is a partial inverse to the undocumented library operation DirectSumMat. So if L is the list of diagonal decompositions of a matrix M then each entry in L is a list of matrices, and the direct sum of each of these lists is equal to the original M. In the following examples, M_6 is an obvious direct sum with 3 blocks. M_4 is an example with three decompositions, while M_8 = M_4 ⊕ M_4 has 16 decompositions (not listed).  Example   gap> M6 := [ [1,2,0,0,0,0], [3,4,0,0,0,0], [5,6,0,0,0,0],  >  [0,0,9,0,0,0], [0,0,0,1,2,3], [0,0,0,4,5,6] ];; gap> Display( M6 ); [ [ 1, 2, 0, 0, 0, 0 ],  [ 3, 4, 0, 0, 0, 0 ],  [ 5, 6, 0, 0, 0, 0 ],  [ 0, 0, 9, 0, 0, 0 ],  [ 0, 0, 0, 1, 2, 3 ],  [ 0, 0, 0, 4, 5, 6 ] ] gap> L6 := DirectSumDecompositionMatrices( M6 ); [ [ [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ], [ [ 9 ] ], [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]   ] ]  gap> M4 := [ [0,3,0,0], [0,0,0,0], [0,0,0,0], [0,0,4,0] ];; gap> Display( M4 ); [ [ 0, 3, 0, 0 ],  [ 0, 0, 0, 0 ],  [ 0, 0, 0, 0 ],  [ 0, 0, 4, 0 ] ] gap> L4 := DirectSumDecompositionMatrices( M4 ); [ [ [ [ 0, 3 ] ], [ [ 0, 0 ], [ 0, 0 ], [ 4, 0 ] ] ],   [ [ [ 0, 3 ], [ 0, 0 ] ], [ [ 0, 0 ], [ 4, 0 ] ] ],   [ [ [ 0, 3 ], [ 0, 0 ], [ 0, 0 ] ], [ [ 4, 0 ] ] ] ] gap> for L in L4 do  >  A := DirectSumMat( L );;  >  if ( A = M4 ) then Print( "yes, A = M4\n" ); fi;  >  od; yes, A = M4 yes, A = M4 yes, A = M4  gap> M8 := DirectSumMat( M4, M4 );;  gap> Display( M8 ); [ [ 0, 3, 0, 0, 0, 0, 0, 0 ],  [ 0, 0, 0, 0, 0, 0, 0, 0 ],  [ 0, 0, 0, 0, 0, 0, 0, 0 ],  [ 0, 0, 4, 0, 0, 0, 0, 0 ],  [ 0, 0, 0, 0, 0, 3, 0, 0 ],  [ 0, 0, 0, 0, 0, 0, 0, 0 ],  [ 0, 0, 0, 0, 0, 0, 0, 0 ],  [ 0, 0, 0, 0, 0, 0, 4, 0 ] ] gap> L8 := DirectSumDecompositionMatrices( M8 );; gap> Length( L8 );  16   The current method does not, however, catch all possible decompositions. In the following example the matrix M_5 has its third row and third column extirely zero, and the only decomposition found has a [0] factor. There are clearly two 2-factor decompositions with a 2-by-3 and a 3-by-2 factor, but these are not found at present.  Example   gap> M5 := [ [1,2,0,0,0], [3,4,0,0,0], [0,0,0,0,0], >  [0,0,0,6,7], [0,0,0,8,9] ];; gap> Display(M5); [ [ 1, 2, 0, 0, 0 ],  [ 3, 4, 0, 0, 0 ],  [ 0, 0, 0, 0, 0 ],  [ 0, 0, 0, 6, 7 ],  [ 0, 0, 0, 8, 9 ] ] gap> L5 := DirectSumDecompositionMatrices( M5 );  [ [ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 0 ] ], [ [ 6, 7 ], [ 8, 9 ] ] ] ]   utils-0.86/doc/chapInd_mj.html000644 000765 000024 00000022111 14621610515 021400 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Index
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

Index

AllIsomorphisms 7.1-1
AllIsomorphismsIterator 7.1-1
AllIsomorphismsNumber 7.1-1
AllProducts 4.1-2
AllSmoothIntegers 4.1-1 4.1-1
AllSubgroupsIterator 7.1-2
AssignGlobals 8.1-1
BlankFreeString 3.3-1
CartesianIterator 7.2-1
CentralProduct 5.3-3
CentralProductInfo 5.3-3
Comm 5.1-1
CommonRepresentatives 3.2-1
CommonTransversal 3.2-1
ConvertToMagmaInputString 10.3-1
CreateDirIfMissing 11.1
DifferencesList 3.1-1
DirectProductOfAutomorphismGroups 5.3-6
DirectProductOfFunctions 5.3-5
DirectSumDecompositionMatrices 6.1-1
distinct and common representatives 3.2
DistinctRepresentatives 3.2-1
Download 9.1-1
DownloadVerifyCertificate 9.1-2
EpimorphismByGenerators 5.3-1
ExponentOfPrime 11.3-2
FindMatchingFiles 11.1
Fitting series 5.1-5
FittingLength 5.1-5
FloatQuotientsList 3.1-2
GeneratorsAndInverses 5.1-4
GetSuffix 11.1
GitHub repository 1.
IdempotentEndomorphisms 5.3-4
IdempotentEndomorphismsData 5.3-4
IdempotentEndomorphismsWithImage 5.3-4
IntOrOnfinityToLaTeX 10.2-1
IsCommonTransversal 3.2-1
IsCommuting 5.1-2
Iterators 7.1
LaTeXStringFactorsInt 10.2-2
LeftCoset 5.2-1
ListOfPowers 5.1-3
Log2HTML 10.1-1
LowerFittingSeries 5.1-5
MatrixGroupToMagmaFormat 10.3-1
NextProbablyPrimeInt 4.1-4
OKtoReadFromUtils 12.
OptionRecordWithDefaults 8.2-1
PcGroupToMagmaFormat 10.3-1
PermGroupToMagmaFormat 10.3-1
PrimeNumbersIterator 4.1-5
PrintApplicableMethod 11.3-1
PrintOneItemPerLine 11.2
PrintSelection 2.1-1 2.1-1
Pullback 5.3-2
PullbackInfo 5.3-2
QuotientsList 3.1-2
RandomCombination 3.1-4
RestrictedPartitionsWithoutRepetitions 4.1-3
SearchCycle 3.1-3
SetIfMissing 11.1
smooth integer 4.1-1
StringDotSuffix 11.1
UnorderedPairsIterator 7.2-2
UpperFittingSeries 5.1-5

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/doc/chooser.html000644 000765 000024 00000007456 14621610515 021025 0ustar00christopherwensleystaff000000 000000 GAPDoc Style Chooser

Setting preferences for GAPDoc manuals

Unfold subsections in menus only by mouse clicks: no (default)     yes

Show GAP examples as in sessions with ColorPrompt(true): yes (default)     no

Display side of table of contents within chapters: right (default)     left

Main document font: Helvetica/sans serif (default)     Times/serif

Paragraph formatting: left-right justified (default)     ragged right

Apply settings to last page.

utils-0.86/doc/chap12.html000644 000765 000024 00000017710 14621610515 020433 0ustar00christopherwensleystaff000000 000000 GAP (Utils) - Chapter 12: The transfer procedure
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

12 The transfer procedure

We consider here the process for transferring utility functions from a package Home to Utils which has to avoid the potential problem of duplicate declarations of a function causing loading problems in GAP.

If the functions in Home all have names of the form HOME_FunctionName then, in Utils, these functions are likely to be renamed as FunctionName or something similar. In this case the problem of duplicate declarations does not arise. This is what has happened with transfers from the AutoDoc package.

The case where the function names are unchanged is more complicated. Initially we tried out a process which allowed repeated declarations and installations of the functions being transferred. This involved additions to the main library files global.g and oper.g. Since there were misgivings about interfering in this way with basic operations such as BIND_GLOBAL, a simpler (but slightly less convenient) process has been adopted.

Using this alternative procedure, the following steps will be followed when making transfers from Home to Utils.

  1. (Home:) Offer functions for inclusion. This may be simply done by emailing a list of functions. More usefully, email the declaration, implementation, test and documentation files, e.g.: home.gd, home.gi, home.tst and home.xml. (All active authors should be involved.)

  2. (Home:) Declare that m.n is the last version of Home to contain these functions, so that m.n+1 (or similar) will be the first version of Home to have all these functions removed, and to specify Utils as a required package.

  3. (Utils:) Add strings "home" and "m.n" to the list UtilsPackageVersions in the file utils/lib/start.gd.

    
    UtilsPackageVersions := 
      [ "autodoc",     "2016.01.31", 
        "resclasses",  "4.2.5", 
        "home",        "m.n",
        ...,           ... 
      ];
    
    

    While the transfers are being made, it is essential that any new versions of Home should be tested with the latest version of Utils before they are released, so as to avoid loading failures.

  4. (Utils:) Include the function declaration and implementation sections in suitable files, enclosed within a conditional clause of the form:

    
    if OKtoReadFromUtils( "Home" ) then
    . . . . . . 
     <the code> 
    . . . . . . 
    fi;
    
    

    The function OKtoReadFromUtils returns true only if there is an installed version of Home and if this version is greater than m.n. So, at this stage, the copied code will not be read, and the transferred functions can only be called if Home has been installed.

  5. (Utils:) Add the test and documentation material to the appropriate files. The copied code can be tested by temporarily moving Home away from GAP's package directory.

  6. (Utils:) Release a new version of Utils containing all the transferred material.

  7. (Home:) Edit out the declarations and implementations of all the transferred functions, and remove references to them in the manual and tests. Possibly add a note to the manual that these functions have been transferred. Add Utils to the list of Home's required packages in PackageInfo.g. Release a new version of Home.

  8. (Utils:) In due course, when the new version(s) of Home are well established, it may be safe to remove the conditional clauses mentioned in item 4 above. The entry for Home in UtilsPackageLists may then be removed.

Finally, a note on the procedure for testing these functions. As long as a function being transferred still exists in the Home package, the code will not be read from Utils. So, when the tests are run, it is necessary to LoadPackage("home") before the function is called. The file utils/tst/testall.g makes sure that all the necessary packages are loaded before the individual tests are called.

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 Bib Ind

generated by GAPDoc2HTML

utils-0.86/lib/print.gd000644 000765 000024 00000001644 14621444241 020140 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W print.gd GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2018, The GAP Group ############################################################################## ## added global function and methods to print subsets of lists/iterators ## DeclareGlobalFunction( "PrintSelection" ); DeclareOperation( "PrintSelectionFromList", [ IsList, IsPosInt, IsPosInt, IsPosInt ] ); DeclareOperation( "PrintSelectionFromIterator", [ IsIterator, IsPosInt, IsPosInt, IsAdditiveElement ] ); DeclareOperation( "PrintSelectionFromListByList", [ IsList, IsList ] ); DeclareOperation( "PrintSelectionFromIteratorByList", [ IsIterator, IsList ] ); ############################################################################# ## #E print.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/lcset.gi000644 000765 000024 00000011271 14621444241 020120 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W lcset.gi GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2022, The GAP Group ############################################################################# ## #O LeftCoset( , ) . . . . . . . . forms a left coset of U by g \in G ## InstallMethod( LeftCoset, "generic method for left cosets", true, [ IsObject, IsGroup ], 0, function( g, U ) local lc, fam; fam := FamilyObj( U ); if not IsBound( fam!.leftCosetsDefaultType ) then fam!.leftCosetsDefaultType := NewType( fam, IsLeftCosetDefaultRep and HasActingDomain and HasFunctionAction and HasRepresentative ); fi; lc := rec(); ObjectifyWithAttributes( lc, fam!.leftCosetsDefaultType, Representative, g, ActingDomain, U, FunctionAction, OnLeftInverse, IsLeftCoset, true ); if HasSize( U ) then SetSize( lc, Size( U ) ); fi; return lc; end); ############################################################################# ## #A Inverse( ) . . . . . forms the right coset Ug^-1 corresponding to gU #A Inverse( ) . . . . . forms the left coset g^-1U corresponding to Ug ## InstallOtherMethod( Inverse, "generic method for left cosets", true, [ IsLeftCoset ], 0, function( lc ) local g, U, rc; g := Representative( lc ); U := ActingDomain( lc ); rc := RightCoset( U, g^-1 ); SetInverse( rc, lc ); return rc; end); InstallOtherMethod( Inverse, "generic method for right cosets", true, [ IsRightCoset ], 0, function( rc ) local g, U, lc; g := Representative( rc ); U := ActingDomain( rc ); lc := LeftCoset( g^-1, U ); SetInverse( lc, rc ); return lc; end); InstallMethod( PrintString, "for a left coset", true, [ IsLeftCoset ], 0, function( d ) return STRINGIFY( "LeftCoset(\<", PrintString( Representative(d) ), ",\>", PrintString( ActingDomain(d) ), ")" ); end); InstallMethod( PrintObj, "for a left coset", true, [ IsLeftCoset ], 0, function( d ) Print( PrintString( d ) ); end); InstallMethod( ViewString, "for a left coset", true, [ IsLeftCoset ], 0, function( d ) return STRINGIFY( "LeftCoset(\<", ViewString( Representative(d) ), ",\>", ViewString( ActingDomain(d) ), ")" ); end); InstallMethod( ViewObj, "for a left coset", true, [ IsLeftCoset ], 0, function( d ) Print( ViewString( d ) ); end); InstallMethod( \=, "for two left cosets", IsIdenticalObj, [ IsLeftCoset, IsLeftCoset ], 0, function( lc1, lc2 ) return ( ActingDomain( lc1 ) = ActingDomain( lc2 ) ) and ( Representative(lc1)/Representative(lc2) in ActingDomain( lc1 ) ); end); InstallMethod( \in, "element and LeftCoset", true, [ IsMultiplicativeElementWithInverse, IsLeftCoset ], 100, function( g, lc ) return ( Representative(lc)^-1 * g ) in ActingDomain( lc ); end); InstallOtherMethod( \*, "element and LeftCoset", true, [ IsMultiplicativeElementWithInverse, IsLeftCoset ], 0, function( g, lc ) return LeftCoset( g * Representative( lc ), ActingDomain( lc ) ); end); InstallOtherMethod( \^, "LeftCoset and element", true, [ IsLeftCoset, IsMultiplicativeElementWithInverse ], 0, function( lc, g ) return g^-1 * lc; end); InstallMethod( Size, "for a left coset", true, [ IsLeftCoset ], 0, function( lc ) return Size( ActingDomain( lc ) ); end); InstallOtherMethod( IsBiCoset, "for a left coset", true, [ IsLeftCoset ], 0, function( lc ) return IsBiCoset( Inverse( lc ) ); end); InstallOtherMethod( AsSet, "for a left coset", true, [ IsLeftCoset ], 0, function( lc ) local L; L := AsSet( Inverse( lc ) ); return Set( L, g -> g^-1 ); end); InstallOtherMethod( Intersection2, "for two left cosets", true, [ IsLeftCoset, IsLeftCoset ], 0, function( lc1, lc2 ) local L; L := Intersection2( Inverse( lc1 ), Inverse( lc2 ) ); return Set( L, g -> g^-1 ); ## return Inverse( L ); to be used once 4r12 is out end); ############################################################################# ## #F LeftCosets( ) . . . . . . . . . . . . left cosets of U by g \in G #O LeftCosetsNC( ) . . . . . . . . . . . left cosets of U by g \in G ## InstallGlobalFunction( LeftCosets, function( G, U ) if not IsSubset( G, U ) then Error("not contained"); fi; return LeftCosetsNC( G, U ); end ); InstallMethod( LeftCosetsNC, "generic", IsIdenticalObj, [ IsGroup, IsGroup ], 0, function( G, U ) local L; L := RightCosetsNC( G, U ); return List( L, Inverse ); end); utils-0.86/lib/lists.gi000644 000765 000024 00000023217 14621444241 020147 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W lists.gi GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2018, The GAP Group ############################################################################# ## these functions have been transferred from ResClasses ## #F DifferencesList( ) . . . . differences of consecutive list entries #F QuotientsList( ) . . . . . . quotients of consecutive list entries #F FloatQuotientsList( ) . . . . . . . . . . . . dito, but as floats ## InstallGlobalFunction( DifferencesList, list -> List( [ 2..Length(list) ], pos -> list[ pos ] - list[ pos-1 ] ) ); InstallGlobalFunction( QuotientsList, function( list ) local len, pos, quot; len := Length( list ); quot := ListWithIdenticalEntries( len-1, 0 ); for pos in [1..len-1] do if IsZero( list[pos] ) then quot[pos] := fail; else quot[pos] := list[pos+1]/list[pos]; fi; od; return quot; end ); InstallGlobalFunction( FloatQuotientsList, list -> List( QuotientsList( list ), Float ) ); ############################################################################# ## this function has been transferred from ResClasses ## #M RandomCombination( S, k ) . . . . . . . . . . . . . . . . default method ## InstallMethod( RandomCombination, "default method", ReturnTrue, [ IsListOrCollection, IsPosInt ], function ( S, k ) local c, elm, i; if k > Size(S) then return fail; fi; c := []; for i in [1..k] do repeat elm := Random(S); until not elm in c; Add(c,elm); od; return Set(c); end ); ############################################################################# ## this function has been transferred from RCWA ## #F SearchCycle( ) . a utility function for detecting cycles in lists ## InstallGlobalFunction( SearchCycle, function ( list ) local preperiod, cycle, startpos, mainpart, mainpartdiffs, elms, inds, min, n, d, i, j; n := Length(list); mainpart := list{[Int(n/3)..n]}; elms := Set(mainpart); cycle := [elms[1]]; startpos := Filtered(Positions(list,elms[1]),i->i>n/3); if Length(elms) = 1 then if ValueOption("alsopreperiod") <> true then return cycle; else i := Length(list); repeat i := i - 1; until i = 0 or list[i] <> elms[1]; preperiod := list{[1..i]}; return [preperiod,cycle]; fi; fi; i := 0; repeat i := i + 1; inds := Intersection(startpos+i,[1..n]); if inds = [] then return fail; fi; min := Minimum(list{inds}); Add(cycle,min); startpos := Filtered(startpos,j->j+i<=n and list[j+i]=min); if Length(startpos) <= 1 then return fail; fi; mainpartdiffs := DifferencesList(Intersection(startpos,[Int(n/3)..n])); if mainpartdiffs = [] then return fail; fi; d := Maximum(mainpartdiffs); until Length(cycle) = d; if Minimum(startpos) > n/2 or n-Maximum(startpos)-d+1 > d or list{[Maximum(startpos)+d..n]}<>cycle{[1..n-Maximum(startpos)-d+1]} then return fail; fi; if ValueOption("alsopreperiod") <> true then return cycle; else i := Minimum(startpos) + Length(cycle); repeat i := i - Length(cycle); until i <= 0 or list{[i..i+Length(cycle)-1]} <> cycle; preperiod := list{[1..i+Length(cycle)-1]}; return [preperiod,cycle]; fi; end ); ############################################################################## ## this function has been transferred from XMod ## #M DistinctRepresentatives( ) ## InstallMethod( DistinctRepresentatives, "for a list of sets", true, [ IsList ], 0, function( L ) local n, rep, U, len, i, j, k, used, found, S, T, M, P, x, y, z; if not ( IsList( L ) and ( ForAll( L, IsList ) or ForAll( L, IsSet ) ) ) then Error( "argument should be a list of sets" ); fi; n := Length( L ); U := [1..n]; len := 0 * U; for i in U do S := L[i]; if IsList( S ) then S := Set( S ); fi; len[i] := Length( S ); if ( len[i] = 0 ) then Error( "subsets must be non-empty" ); fi; if not ForAll( S, j -> ( j in U ) ) then Error( "each set must be a subset of [1..n]" ); fi; od; rep := 0 * U; used := 0 * U; rep[1] := L[1][1]; used[ rep[1] ] := 1; for i in [2..n] do found := false; S := L[i]; j := 0; while ( ( j < len[i] ) and not found ) do j := j+1; x := S[j]; if ( used[x] = 0 ) then rep[i] := x; used[x] := i; found := true; fi; od; # construct the graph component T := ShallowCopy( S ); M := List( T ); P := 0 * U; for x in M do P[x] := i; od; j := 0; while not found do j := j+1; x := M[j]; k := used[x]; if ( k = 0 ) then # reassign representatives y := P[x]; while ( y <> i ) do z := rep[y]; rep[y] := x; used[x] := y; x := z; y := P[x]; od; rep[i] := x; used[x] := i; found := true; else for y in L[k] do if not ( y in T ) then Add( M, y ); P[y] := k; T := Union( T, [y] ); fi; od; fi; if ( ( not found ) and ( j = Length( M ) ) ) then Print( "Hall condition not satisfied!\n" ); return false; fi; od; od; return rep; end ); ############################################################################## ## this function has been transferred from XMod ## #M CommonRepresentatives( , ) ## InstallMethod( CommonRepresentatives, "for a pair of lists/sets", true, [ IsList, IsList ], 0, function( J, K ) local U, i, j, k, m, n, lenJ, lenK, S, L, I, rep, perm, common; if not ( ForAll( J, IsList ) or ForAll( J, IsSet ) ) then Error( "first argument should be a list of sets" ); fi; m := Length( J ); if not ( ForAll( K, IsList ) or ForAll( K, IsSet ) ) then Error( "second argument should be a list of sets" ); fi; n := Length( K ); if not ( m = n ) then Error( "lists and have unequal length" ); fi; U := [1..n]; lenJ := 0 * U; lenK := 0 * U; for i in U do S := J[i]; if IsList( S ) then S := Set( S ); fi; lenJ[i] := Length( S ); if ( lenJ[i] = 0 ) then Error( "sets must be non-empty" ); fi; S := K[i]; if IsList( S ) then S := Set( S ); fi; lenK[i] := Length( S ); if ( lenK[i] = 0 ) then Error( "sets must be non-empty" ); fi; od; L := List( U, x -> [ ] ); for i in U do S := J[i]; for j in U do I := Intersection( S, K[j] ); if ( Length( I ) > 0 ) then Add( L[i], j ); fi; od; od; rep := DistinctRepresentatives( L ); perm := PermList( rep ); K := Permuted( K, perm^-1 ); common := 0 * U; for i in U do I := Intersection( J[i], K[i] ); common[i] := I[1]; od; return [ common, rep ]; end ); ############################################################################## ## this function has been transferred from XMod ## #M CommonTransversal ## InstallMethod( CommonTransversal, "for left and right cosets of a subgroup", true, [ IsGroup, IsGroup ], 0, function( G, H ) local R, ER, EL, T; if not IsSubgroup( G, H ) then Error( " must be a subgroup of " ); fi; R := RightCosets( G, H ); ER := List( R, Elements ); EL := List( ER, C -> List( C, Inverse ) ); Info( InfoUtils, 3, "right cosets: ", ER ); Info( InfoUtils, 3, " left cosets: ", EL ); T := CommonRepresentatives( EL, ER ); return T[1]; end ); ############################################################################## ## this function has been transferred from XMod ## #M IsCommonTransversal ## InstallMethod( IsCommonTransversal, "for group, subgroup, list", true, [ IsGroup, IsGroup, IsList ], 0, function( G, H, T ) local eG, eH, oG, oH, g, h, t, pos, ind, found; if not IsSubgroup( G, H ) then Print( "second group must be subgroup of first\n" ); return fail; fi; oG := Size( G ); oH := Size( H ); eG := Elements( G ); eH := Elements( H ); ind := oG/oH; found := 0 * [1..oG]; for t in T do if not ( t in eG ) then Print( "element of T not in G\n" ); return false; fi; for h in eH do g := t*h; pos := Position( eG, g ); found[pos] := found[pos] +1; g := h*t; pos := Position( eG, g ); found[pos] := found[pos] + 1; od; od; for t in [1..oG] do if not ( found[t] = 2 ) then Print( eG[t], " found ", found[t], " times\n" ); return false; fi; od; return true; end ); ############################################################################# ## #E lists.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/record.gd000644 000765 000024 00000002276 14621444241 020264 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W record.gd GAP4 package `Utils' Sebastian Gutsche ## Max Horn ## Stefan Kohl #Y Copyright (C) 2015-2022, The GAP Group ############################################################################# ## this function has been transferred from RCWA ## #F AssignGlobals( ) ## ## This auxiliary function assigns the record components of to ## global variables with the same names. ## DeclareGlobalFunction( "AssignGlobals" ); ############################################################################# ## this function has been contributed by Christopher Jefferson ## #F OptionRecordWithDefaults( arg1, arg2, ..., ) ## ## This auxiliary function assigns the record components of to ## global variables with the same names. ## DeclareGlobalFunction( "OptionRecordWithDefaults" ); ############################################################################# ## #E record.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/matrix.gi000644 000765 000024 00000017051 14621444241 020314 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W matrix.gi GAP4 package `Utils' Pedro A. Garcia-Sanchez ## #Y Copyright (C) 2023, The GAP Group InstallMethod( DirectSumBlock, "for a matrix", [ IsMatrixOrMatrixObj, IsInt, IsList, IsList ], 0, function( M, level, blocks, answer ) local nrM, ncM, nM, nr0, nc0, found, nlzr, nlzc, ntzr, ntzc, nlz, ntz, B, nrB, ncB, nB, nr, nc, i, j, k, i0, j0, nzr, nzc, rest, sub, bls, nrbls, ncbls, pr1, diag0, up0, low0, imax, jmax, len1, ok, ans; nrM := NumberRows( M ); ncM := NumberColumns( M ); nM := Minimum( [ nrM, ncM ] ); ## deal with the diagonal case first if IsDiagonalMatrix( M ) then bls := List( [1..nM], i -> [ [ M[i,i] ] ] ); if ( ncM > nM ) then sub := ExtractSubMatrix( M, [nM], [nM..ncM] )[1]; bls[nM] := [ sub ]; fi; if ( nrM > nM ) then sub := ExtractSubMatrix( M, [nM..nrM], [nM] )[1]; bls[ nM] := [ sub ]; fi; blocks[1] := Concatenation( blocks[1], bls ); ans := Concatenation( blocks[1], blocks[2] ); if not ( ans in answer ) then Add( answer, ans ); fi; return 0; fi; ## check for leading or trailing rows or columns of zeros nlzr := 0; found := false; i := 0; while not found do i := i+1; if ForAll( [1..ncM], j -> M[i,j] = 0 ) then nlzr := nlzr + 1; else found := true; fi; od; nlzc := 0; found := false; j := 0; while not found do j := j+1; if ForAll( [1..nrM], i -> M[i,j] = 0 ) then nlzc := nlzc + 1; else found := true; fi; od; ntzr := 0; found := false; i := nrM + 1; while not found do i := i-1; if ForAll( [1..ncM], j -> M[i,j] = 0 ) then ntzr := ntzr + 1; else found := true; fi; od; ntzc := 0; found := false; j := ncM + 1; while not found do j := j-1; if ForAll( [1..nrM], i -> M[i,j] = 0 ) then ntzc := ntzc + 1; else found := true; fi; od; ## add any leading or trailing blocks [ [0] ] nlz := Minimum( [ nlzr, nlzc ] ); if ( nlz > 0 ) then blocks[1] := Concatenation( blocks[1], ListWithIdenticalEntries( nlz, [ [0] ] ) ); fi; ntz := Minimum( [ ntzr, ntzc ] ); if ( ntz > 0 ) then blocks[2] := Concatenation( ListWithIdenticalEntries( ntz, [ [0] ] ), blocks[2] ); fi; B := ExtractSubMatrix( M, [nlz+1..nrM-ntz], [nlz+1..ncM-ntz] ); nrB := NumberRows( B ); ncB := NumberColumns( B ); nB := Minimum( [nrB, ncB] ); bls := [ ]; if ( nrB = 1 ) or ( ncB = 1 ) then Add( blocks[1], B ); ans := Concatenation( blocks[1], blocks[2] ); if not ( ans in answer ) then Add( answer, ans ); fi; return 0; fi; ## find first non-zero entry in column 1 found := false; pr1 := 0; while ( not found ) and ( pr1 < nrB-1 ) do pr1 := pr1 + 1; found := B[pr1,1] <> 0; od; ## determine ranges for i0 and j0 diag0 := nB+1; i := nB+1; while ( i > 1 ) do i := i-1; if ( B[i,i] <> 0 ) then diag0 := i; fi; od; up0 := [diag0,diag0]; j := 1; found := false; while ( not found ) and ( j < ncB ) do j := j+1; k := Minimum( [ j-1, nrB ] ); for i in [1..k] do if ( B[i,j] <> 0 ) then up0 := [i,j]; found := true; fi; od; od; low0 := [diag0,diag0]; i := 1; found := false; while ( not found ) and ( i < nrB ) do i := i+1; k := Minimum( [ i-1, ncB ] ); for j in [1..k] do if ( B[i,j] <> 0 ) then low0 := [i,j]; found := true; fi; od; od; imax := diag0; jmax := diag0; if ( up0[2] < low0[2] ) then jmax := low0[2] - 1; fi; if ( low0[1] < up0[1] ) then imax := up0[1] - 1; fi; if ( up0[1] < low0[1] ) then imax := Minimum( imax, low0[1] - 1 ); fi; if ( low0[2] < up0[2] ) then jmax := Minimum( jmax, up0[2] - 1 ); fi; if ( low0[1] > nrB ) then imax := up0[1]; fi; if ( up0[1] > ncM ) then jmax := low0[2]; fi; i0 := 0; while ( i0 < imax ) do i0 := i0 + 1; i := i0; j0 := 0; while ( j0 < jmax ) do found := false; j0 := j0 + 1; if ( j0 <= pr1 ) then j := j0; rest := MutableCopyMatrix( B ); nr := NumberRows( rest ); nc := NumberColumns( rest ); i := i0; j := j0; nzr := true; nzc := true; while nzr or nzc do nzr := ForAny( [1..i], i1 -> ForAny( [j+1..nc], j1->rest[i1][j1]<>0 ) ); nzc := ForAny( [i+1..nr], i1 -> ForAny( [1..j], j1->rest[i1][j1]<>0 ) ); if nzr then j := j+1; fi; if nzc then i := i+1; fi; od; bls := List( [1..i], i1 -> rest[i1]{[1..j]} ); ## check if we have filled all columns and rows nzc := ntzc - ntz; nrbls := NumberRows( bls ); ncbls := NumberColumns( bls ); if ( nzc > 0 ) and ( ncbls + nzc = ncB ) then ## add zero columns at the end of the block j := j + nzc; bls := List( [1..i], i1 -> rest[i1]{[1..j]} ); fi; nzr := ntzr - ntz; if ( nzr > 0 ) and ( nrbls + nzr = nrB ) then ## add zero rows at the end of the block i := i + nzr; bls := List( [1..i], i1 -> rest[i1]{[1..j]} ); fi; Add( blocks[1], bls ); len1 := Length( blocks[1] ); rest := List( [i+1..nr], i1 -> rest[i1]{[j+1..nc]} ); if ( rest <> [ ] ) then ok := DirectSumBlock( rest,level+1,blocks,answer ); else ans := Concatenation( blocks[1], blocks[2] ); if not ( ans in answer ) then Add( answer, ans ); fi; fi; blocks := [ blocks[1]{[1..len1-1]}, blocks[2] ]; fi; od; od; return Length( answer ); end ); InstallMethod( DirectSumDecompositionMatrices, "for a matrix", [ IsMatrixOrMatrixObj ], 0, function( M ) local L, blocks, answer, a, ma; blocks := [ [], [] ]; answer := [ ]; L := DirectSumBlock( M, 1, blocks, answer ); ## check that the answers are correct for a in answer do ma := DirectSumMat( a ); if not ( ma = M ) then Display( ma ); Error( "direct sum of decomposition <> original matrix" ); fi; od; return answer; end ); utils-0.86/lib/maps.gi000644 000765 000024 00000021132 14621444241 017743 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W maps.gi GAP4 package `Utils' Stefan Kohl ## Chris Wensley #Y Copyright (C) 2015-2019, The GAP Group ############################################################################# ## #F EpimorphismByGenerators( , ) . epi: gen's of ->gen's of ## InstallMethod( EpimorphismByGenerators, "for groups", ReturnTrue, [ IsGroup, IsGroup ], 0, function( G, H ) if not ( IsFreeGroup( G ) ) then Print( "Warning: calling GroupHomomorphismByImagesNC without checks\n" ); fi; return GroupHomomorphismByImagesNC( G, H, GeneratorsOfGroup(G), GeneratorsOfGroup(H) ); end ); ############################################################################## ## #M Pullback . . . . . . . . . for two group homomorphisms with a common range ## InstallMethod( Pullback, "for two group homomorphisms", true, [ IsGroupHomomorphism, IsGroupHomomorphism ], 0, function( nu, mu ) local M, N, P, NxM, projM, pmu, projN, pnu, genNxM, e, genL, L, imphi, phi, impsi, psi, info; M := Source( mu ); P := Range( mu ); N := Source( nu ); if not ( Range(nu) = P ) then Error( "homs nu,mu should have a common range" ); fi; NxM := DirectProduct( N, M ); genNxM := GeneratorsOfGroup( NxM ); projN := Projection( NxM, 1 ); pnu := projN * nu; projM := Projection( NxM, 2 ); pmu := projM * mu; if IsFinite( NxM ) then genL := [ ]; L := Subgroup( NxM, [ One(NxM) ] ); for e in NxM do if ImageElm( pnu, e ) = ImageElm( pmu, e ) then if not ( e in L ) then Add( genL, e ); L := Group( genL ); fi; fi; od; else return fail; fi; imphi := List( genL, g -> ImageElm( projN, g ) ); phi := GroupHomomorphismByImages( L, N, genL, imphi ); impsi := List( genL, g -> ImageElm( projM, g ) ); psi := GroupHomomorphismByImages( L, M, genL, impsi ); info := rec( directProduct := NxM, projections := [phi,psi] ); SetPullbackInfo( L, info ); return L; end ); ############################################################################# ## #M CentralProduct( , , , ) ## InstallMethod( CentralProduct, [ "IsGroup", "IsGroup", "IsGroup", "IsGroupHomomorphism" ], function( G1, G2, Z1, Phi ) local gens, imgs, dp, emb1, emb2, N, proj, G; if not ( IsSubset( G1, Z1 ) and IsCentral( G1, Z1 ) ) then Error( " must be a central subgroup of " ); fi; gens:= GeneratorsOfGroup( Z1 ); imgs:= List( gens, x -> (x^-1)^Phi ); if not ( IsSubset( G2, imgs ) and ForAll( imgs, x -> IsCentral( G2, x ) ) ) then Error( " must map to a central subgroup of " ); fi; dp:= DirectProduct( G1, G2 ); emb1:= Embedding( dp, 1 ); emb2:= Embedding( dp, 2 ); N:= SubgroupNC( dp, List( [ 1 .. Length( gens ) ], i -> gens[i]^emb1 * imgs[i]^emb2 ) ); proj:= NaturalHomomorphismByNormalSubgroup( dp, N ); G:= Image( proj ); SetCentralProductInfo( G, rec( projection:= proj, phi:= Phi ) ); return G; end ); ############################################################################## ## #M IdempotentEndomorphisms . . . . . . . . . . . . . . . . . . . for a group #M IdempotentEndomorphismsData . . . . . . . . . . . . . . . . . for a group #M IdempotentEndomorphismsWithImage . . . . . for a group and a chosen image ## InstallMethod( IdempotentEndomorphismsWithImage, "for a list of group generators and a chosen image", [ IsList, IsGroup ], 0, function( genG, R ) local G, numG, r, q, norm, n, reps, i, j, rc; G := Group( genG ); if not IsSubgroup( G, R ) then Error( "R should be a subgroup of G" ); fi; numG := Length( genG ); r := Size( R ); q := Size( G )/r; norm := Filtered( NormalSubgroups( G ), N -> ( Size( N ) = q ) and IsTrivial( Intersection( N, R ) ) ); n := Length( norm ); reps := [ ]; for i in [1..n] do Add( reps, [ ] ); for j in [1..numG] do rc := norm[i]*genG[j]; Add( reps[i], First( rc, g -> g in R ) ); od; od; return reps; end ); InstallMethod( IdempotentEndomorphismsData, "for a group", [ IsGroup ], 0, function( G ) local genG, R, data, images; genG := SmallGeneratingSet( G ); images := [ ]; for R in AllSubgroups( G ) do data := IdempotentEndomorphismsWithImage( genG, R ); if ( data <> [ ] ) then Add( images, data ); fi; od; return rec( gens := genG, images := images ); end ); InstallMethod( IdempotentEndomorphisms, "for a group", [ IsGroup ], 0, function( G ) local data, genG, images, len, L, i, im; data := IdempotentEndomorphismsData( G ); genG := data!.gens; G := Group( genG ); images := data!.images; len := Length( images ); L := [ ]; for i in [1..len] do for im in images[i] do Add( L, GroupHomomorphismByImages( G, G, genG, im ) ); od; od; return L; end ); ############################################################################## ## #M DirectProductOfFunctions . . . . . . for two groups and two homomorphisms ## InstallMethod( DirectProductOfFunctions, "for two groups and two homs", [ IsGroup, IsGroup, IsGroupHomomorphism, IsGroupHomomorphism ], 0, function( G, H, f1, f2 ) local infoG, gpsG, G1, G2, infoH, gpsH, H1, H2, eG1, eG2, eH1, eH2, mgi1, mgi2, genG, imH1, imH2, imH; if not HasDirectProductInfo( G ) and HasDirectProductInfo( H ) then Error( "first two parameters should be direct products" ); fi; infoG := DirectProductInfo( G ); gpsG := infoG!.groups; G1 := gpsG[1]; G2 := gpsG[2]; if not ( ( G1 = Source( f1 ) ) and ( G2 = Source( f2 ) ) ) then Error( "f1,f2 should have source G1,G2" ); fi; eG1 := Embedding( G, 1 ); eG2 := Embedding( G, 2 ); mgi1 := MappingGeneratorsImages( f1 ); mgi2 := MappingGeneratorsImages( f2 ); infoH := DirectProductInfo( H ); gpsH := infoH!.groups; H1 := gpsH[1]; H2 := gpsH[2]; if not ( ( H1 = Range( f1 ) ) and ( H2 = Range( f2 ) ) ) then Error( "f1,f2 should have range H1,H2" ); fi; eH1 := Embedding( H, 1 ); eH2 := Embedding( H, 2 ); genG := Concatenation( List( mgi1[1], g -> ImageElm( eG1, g ) ), List( mgi2[1], g -> ImageElm( eG2, g ) ) ); imH1 := List( mgi1[2], h -> ImageElm( eH1, h ) ); imH2 := List( mgi2[2], h -> ImageElm( eH2, h ) ); imH := Concatenation( imH1, imH2 ); return GroupHomomorphismByImagesNC( G, H, genG, imH ); end ); ############################################################################## ## #M DirectProductOfAutomorphismGroups . . . . . . for two automorphism groups ## InstallMethod( DirectProductOfAutomorphismGroups, "for two groups", [ IsGroup, IsGroup ], 0, function( A1, A2 ) local gen1, gen2, G1, G2, id1, id2, dp, dp1, dp2, gen12, A12, em1, em2, pr1, pr2, info; if not ( IsGroupOfAutomorphisms(A1) and IsGroupOfAutomorphisms(A2) ) then Error( "A1,A2 should be automorphism groups" ); fi; gen1 := GeneratorsOfGroup( A1 ); gen2 := GeneratorsOfGroup( A2 ); G1 := Source( gen1[1] ); G2 := Source( gen2[1] ); if not ( IsGroup( G1 ) and IsGroup( G2 ) ) then Error( "A1,A2 should be automorphism groups of groups G1,G2" ); fi; id1 := IdentityMapping( G1 ); id2 := IdentityMapping( G2 ); dp := DirectProduct( G1, G2 ); dp1 := List( gen1, g -> DirectProductOfFunctions( dp, dp, g, id2 ) ); dp2 := List( gen2, g -> DirectProductOfFunctions( dp, dp, id1, g ) ); gen12 := Concatenation( dp1, dp2 ); A12 := Group( gen12 ); em1 := GroupHomomorphismByImages( A1, A12, gen1, dp1 ); em2 := GroupHomomorphismByImages( A2, A12, gen2, dp2 ); pr1 := GroupHomomorphismByImages( A12, A1, gen12, Concatenation( gen1, List( gen2, g -> id1 ) ) ); pr2 := GroupHomomorphismByImages( A12, A2, gen12, Concatenation( List( gen1, g -> id2 ), gen2 ) ); info := rec( embeddings := [ em1, em2 ], groups := [ A1, A2 ], projections := [ pr1, pr2 ] ); SetDirectProductInfo( A12, info ); return A12; end ); utils-0.86/lib/iterator.gd000644 000765 000024 00000003300 14621444241 020624 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W iterator.gd GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2019, The GAP Group ############################################################################# ## These functions complement AllHomomorphisms, AllEndomorphisms, and ## AllAutomorphisms in the main library. ## The code gives an example of an iterator preferrred to a list. ## #O AllIsomorphismsIterator( , ) #F DoAllIsomorphismsIterator #O AllIsomorphismsNumber( , ) #O AllIsomorphisms( , ) ## DeclareOperation( "AllIsomorphismsIterator", [ IsGroup, IsGroup ] ); DeclareGlobalFunction( "DoAllIsomorphismsIterator" ); DeclareOperation( "AllIsomorphismsNumber", [ IsGroup, IsGroup ] ); DeclareOperation( "AllIsomorphisms", [ IsGroup, IsGroup ] ); ############################################################################# ## These functions provide an iterator for all subgroups of a group. ## #O AllSubgroupsIterator( ) #F DoAllSubgroupsIterator ## DeclareOperation( "AllSubgroupsIterator", [ IsGroup ] ); DeclareGlobalFunction( "DoAllSubgroupsIterator" ); ############################################################################# ## These functions provide ways of combining two iterators into one ## #O CartesianIterator( ) #F DoCartesianIterator #O UnorderedPairsIterator( ) #F DoUnorderedPairsIterator ## DeclareOperation( "CartesianIterator", [ IsIterator, IsIterator ] ); DeclareGlobalFunction( "DoCartesianIterator" ); DeclareOperation( "UnorderedPairsIterator", [ IsIterator ] ); DeclareGlobalFunction( "DoUnorderedPairsIterator" ); utils-0.86/lib/files.gi000644 000765 000024 00000007026 14621444241 020113 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W files.gi GAP4 package `Utils' Sebastian Gutsche ## Max Horn ## Stefan Kohl #Y Copyright (C) 2015-2018, The GAP Group, ############################################################################# ## this function has been transferred from RCWA ## #F Log2HTML ( logfilename ) . . . . convert GAP logfile to XHTML 1.0 Strict ## InstallGlobalFunction( Log2HTML, function ( logfilename ) local outputname, s1, s2, header, footer, pos, lastlf, nextlf, crlf, prompt; if ARCH_IS_UNIX() then crlf := 1; else crlf := 2; fi; header := Concatenation( "\n\n", "\n\n\n\n ", logfilename, " \n \n", "\n\n\n\n
\n");
    footer := "
"; s1 := StringFile( logfilename ); pos := PositionSublist( s1, "gap>" ); prompt := "gap> "; s2 := ReplacedString( s1{[1..pos-1]}, "<", "<" ); while pos <> fail do s2 := Concatenation(s2,"",prompt,""); s2 := Concatenation(s2,""); nextlf := Position(s1,'\n',pos); prompt := "gap>"; if nextlf = fail then nextlf := Length(s1); fi; s2 := Concatenation(s2,ReplacedString(s1{[pos+5..nextlf-crlf]}, "<","<"),""); while nextlf < Length(s1) and s1[nextlf+1] = '>' do s2 := Concatenation(s2,"\n>", ""); lastlf := nextlf; nextlf := Position(s1,'\n',lastlf); if nextlf = fail then nextlf := Length(s1); fi; s2 := Concatenation(s2,ReplacedString(s1{[lastlf+2..nextlf-crlf]}, "<","<"),""); od; s2 := Concatenation( s2, "\n" ); pos := PositionSublist( s1, "\ngap>", nextlf-1 ); if pos = fail then pos := Length(s1); fi; if pos > nextlf then s2 := Concatenation(s2,"", ReplacedString( s1{[nextlf+1..pos-crlf]}, "<", "<"), "\n" ); fi; if pos > Length(s1) - 3 then break; fi; od; s2 := Concatenation( header, s2, footer ); logfilename := LowercaseString( logfilename ); if ( PositionSublist(logfilename,".log") <> fail ) then outputname := ReplacedString( logfilename, ".log", ".html" ); elif ( PositionSublist( logfilename, ".txt" ) <> fail ) then outputname := ReplacedString( logfilename, ".txt", ".html" ); else outputname := Concatenation( logfilename, ".html" ); fi; FileString( outputname, s2 ); end ); ############################################################################# ## #E files.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/magma.gd000644 000765 000024 00000003213 14621444241 020060 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W magma.gd GAP4 package `Utils' Max Horn ## Alexander Hulpke ## #Y Copyright (C) 2015-2017, The GAP Group ############################################################################# ## this function is new in Utils but calls functions which have been ## transferred from the main library or from private code ## #F ConvertToMagmaInputString( ) . . output a string readable by Magma ## DeclareGlobalFunction( "ConvertToMagmaInputString" ); ############################################################################# ## this function was originally authored by Alexander Hulpke; ## it has been transferred from other.gd in the main library; ## and was originally named MagmaInputString ## #O PermGroupToMagmaFormat( ) ## DeclareOperation( "PermGroupToMagmaFormat", [ IsPermGroup ] ); ############################################################################# ## this function was private code of Max Horn ## #O PcGroupToMagmaFormat( ) ## DeclareOperation( "PcGroupToMagmaFormat", [ IsPcGroup ] ); ############################################################################# ## this function was private code of Frank Lübeck ## #O MatrixGroupToMagmaFormat( ) ## DeclareOperation( "MatrixGroupToMagmaFormat", [ IsMatrixGroup ] ); ############################################################################# ## #E magma.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/groups.gi000644 000765 000024 00000035275 14621444241 020337 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W groups.gi GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2022, The GAP Group ############################################################################# ## this function has been transferred from ResClasses ## #M Comm( [ , ] ) . . . for arguments enclosed in list brackets ## InstallOtherMethod( Comm, "for arguments enclosed in list brackets (ResClasses)", true, [ IsList ], 0, LeftNormedComm ); ############################################################################# ## this function has been transferred from ResClasses ## #M IsCommuting( , ) . . . . . . . . . . . . . . . . . fallback method ## InstallMethod( IsCommuting, "fallback method (ResClasses)", IsIdenticalObj, [ IsMultiplicativeElement, IsMultiplicativeElement ], 0, function ( a, b ) return a*b = b*a; end ); ############################################################################# ## this function has been transferred from ResClasses ## #M UpperFittingSeries( ) . . . . . . . . . . . . . . . . default method ## InstallMethod( UpperFittingSeries, "default method", true, [ IsGroup ], 0, function ( G ) local series, F, phi; if IsTrivial(FittingSubgroup(G)) then return [ TrivialSubgroup(G) ]; fi; F := FittingSubgroup(G); series := [ TrivialSubgroup(G), F ]; while F <> G do phi := NaturalHomomorphismByNormalSubgroup(G,F); F := PreImage(phi,FittingSubgroup(Image(phi))); if series[Length(series)] = F then break; fi; Add(series,F); od; return series; end ); ############################################################################# ## this function has been transferred from ResClasses ## #M LowerFittingSeries( ) . . . . . . . . . . . . . . . . default method ## InstallMethod( LowerFittingSeries, "default method", true, [ IsGroup ], 0, function ( G ) local series, F; series := [ G ]; F := G; while not IsTrivial(F) do F := Reversed(LowerCentralSeries(F))[1]; if series[Length(series)] = F then break; fi; Add(series,F); od; return series; end ); ############################################################################# ## this function has been transferred from ResClasses ## #M FittingLength( ) . . . . . . . . . . . . . . . . . . . default method ## InstallMethod( FittingLength, "default method", true, [ IsGroup ], 0, function ( G ) if not IsSolvableGroup(G) then return infinity; fi; if HasUpperFittingSeries(G) then return Length(UpperFittingSeries(G)) - 1; else return Length(LowerFittingSeries(G)) - 1; fi; end ); ############################################################################# ## this function has been transferred from RCWA ## #F ListOfPowers( , ) . . . . . . list of powers ^1 .. ^ ## InstallGlobalFunction( ListOfPowers, function ( g, exp ) local powers, n; powers := [g]; for n in [2..exp] do Add(powers,powers[n-1]*g); od; return powers; end ); ############################################################################# ## this function has been transferred from RCWA ## #M GeneratorsAndInverses( ) list of generators of and their inverses #M GeneratorsAndInverses( ) . . . . . . . . . . . . . . . . . for groups ## InstallMethod( GeneratorsAndInverses, "for groups", true, [ IsGroup ], 0, G -> Concatenation( GeneratorsOfGroup(G), List( GeneratorsOfGroup(G), g->g^-1 ) ) ); ############################################################################# ## temporary methods for SubdirectProductWithEmbeddings ## InstallGlobalFunction(SubdirectProductWithEmbeddings,function(G,H,ghom,hhom) local iso; if ( Range( ghom, G ) <> Range( hhom, H ) ) or ( Image( ghom, G ) <> Image( hhom, H ) ) then Error("the image groups are not the same"); fi; if not ( IsPermGroup(G) and IsPermGroup(H) ) or ( IsPcGroup(G) and IsPcGroup(H) ) then Error("methods only supplied forperm groups or pc groups"); fi; return SubdirectProductWithEmbeddingsOp( G, H, ghom, hhom ); end); ############################################################################# ## #M SubdirectProductWithEmbeddingsOp( , , , ) ## InstallMethod( SubdirectProductWithEmbeddingsOp,"groups", true, [ IsGroup, IsGroup, IsGroupHomomorphism, IsGroupHomomorphism ], 0, function( G, H, ghom, hhom ) local gc,hc,S,info; # try to enforce a common representation if not (IsFinite(G) and IsFinite(H)) then TryNextMethod(); fi; if IsSolvableGroup(G) and IsSolvableGroup(H) and not (IsPcGroup(G) and IsPcGroup(H)) then # enforce pc groups gc:=IsomorphismPcGroup(G); hc:=IsomorphismPcGroup(H); elif not (IsPermGroup(G) and IsPermGroup(H)) then # enforce perm groups gc:=IsomorphismPermGroup(G); hc:=IsomorphismPermGroup(H); else TryNextMethod(); fi; ghom := InverseGeneralMapping(gc)*ghom; hhom := InverseGeneralMapping(hc)*hhom; # the ...Op is installed for `IsGroupHomomorphism'. So we have to enforce # the filter to be set. if not IsGroupHomomorphism(ghom) or not IsGroupHomomorphism(hhom) then Error("mappings are not homomorphisms"); fi; S:=SubdirectProductWithEmbeddingsOp(Image(gc,G),Image(hc,H),ghom,hhom); info:=rec(groups:=[G,H], homomorphisms:=[ghom,hhom], projections:=[Projection(S,1)*InverseGeneralMapping(gc), Projection(S,2)*InverseGeneralMapping(hc)]); S:=Group(GeneratorsOfGroup(S)); SetSubdirectProductWithEmbeddingsInfo(S,info); return S; end); ############################################################################# ## #M Projection( , ) . . . . . . . . . . . . . . . . . make projection ## InstallMethod( Projection,"pc subdirect product", true, [ IsGroup and HasSubdirectProductWithEmbeddingsInfo, IsPosInt ], 0, function( S, i ) local prj, info; if not i in [1,2] then Error("only 2 embeddings"); fi; info := SubdirectProductWithEmbeddingsInfo( S ); if not IsBound(info.projections[i]) then TryNextMethod(); fi; return info.projections[i]; end); ############################################################################# ## #M Size( ) . . . . . . . . . . . . . . . . . . . . of subdirect product ## InstallMethod( Size,"subdirect product", true, [ IsGroup and HasSubdirectProductWithEmbeddingsInfo ], 0, function( S ) local info; info := SubdirectProductWithEmbeddingsInfo( S ); return Size( info.groups[ 1 ] ) * Size( info.groups[ 2 ] ) / Size( ImagesSource( info.homomorphisms[ 1 ] ) ); end ); ############################################################################# ## methods copied from gprdperm.gi ## ############################################################################# ## #M SubdirectProductWithEmbeddingsOp( , , , ) ## InstallMethod( SubdirectProductWithEmbeddingsOp, "permgroup", true, [ IsPermGroup, IsPermGroup, IsGroupHomomorphism, IsGroupHomomorphism ], 0, function( G1, G2, phi1, phi2 ) local S, # subdirect product of and , result gens, # generators of D, # direct product of and emb1, emb2, # embeddings of and into info, Dinfo,# info records gen; # one generator of or kernel of # make the direct product and the embeddings D := DirectProduct( G1, G2 ); emb1 := Embedding( D, 1 ); emb2 := Embedding( D, 2 ); # the subdirect product is generated by $(g_1,x_{g_1})$ where $g_1$ loops # over the generators of $G_1$ and $x_{g_1} \in G_2$ is abitrary such # that $g_1^{phi_1} = x_{g_1}^{phi_2}$ and by $(1,k_2)$ where $k_2$ loops # over the generators of the kernel of $phi_2$. gens := []; for gen in GeneratorsOfGroup( G1 ) do Add( gens, gen^emb1 * PreImagesRepresentativeNC(phi2,gen^phi1)^emb2 ); od; for gen in GeneratorsOfGroup( KernelOfMultiplicativeGeneralMapping( phi2 ) ) do Add( gens, gen ^ emb2 ); od; # and make the subdirect product S := GroupByGenerators( gens ); SetParent( S, D ); Dinfo := DirectProductInfo( D ); info := rec( groups := [G1, G2], homomorphisms := [phi1, phi2], olds := Dinfo.olds, news := Dinfo.news, perms := Dinfo.perms, projections := [] ); SetSubdirectProductWithEmbeddingsInfo( S, info ); return S; end ); ############################################################################# ## #R IsProjectionSubdirectProductWithEmbeddingsPermGroup( ) . projection onto factor ## DeclareRepresentation( "IsProjectionSubdirectProductWithEmbeddingsPermGroup", IsAttributeStoringRep and IsComponentObjectRep and IsGroupHomomorphism and IsSurjective and IsSPGeneralMapping, [ "component" ] ); ############################################################################# ## #M Projection( , ) . . . . . . . . . . . . . . . . . make projection ## InstallMethod( Projection,"perm subdirect product",true, [ IsPermGroup and HasSubdirectProductWithEmbeddingsInfo, IsPosInt ], 0, function( S, i ) local prj, info; info := SubdirectProductWithEmbeddingsInfo( S ); if IsBound( info.projections[i] ) then return info.projections[i]; fi; prj := Objectify( NewType( GeneralMappingsFamily( PermutationsFamily, PermutationsFamily ), IsProjectionSubdirectProductWithEmbeddingsPermGroup ), rec( component := i ) ); SetSource( prj, S ); info.projections[i] := prj; SetSubdirectProductWithEmbeddingsInfo( S, info ); return prj; end ); ############################################################################# ## #M Range( ) . . . . . . . . . . . . . . . . . . . . . . of projection ## InstallMethod( Range,"perm subdirect product projection", true, [ IsProjectionSubdirectProductWithEmbeddingsPermGroup ], 0, prj -> SubdirectProductWithEmbeddingsInfo( Source( prj ) ).groups[ prj!.component ] ); ############################################################################# ## #M ImagesRepresentative( , ) . . . . . . . . . . . . of projection ## InstallMethod( ImagesRepresentative,"perm subdirect product projection", FamSourceEqFamElm, [ IsProjectionSubdirectProductWithEmbeddingsPermGroup, IsMultiplicativeElementWithInverse ], 0, function( prj, g ) local info; info := SubdirectProductWithEmbeddingsInfo( Source( prj ) ); return RestrictedPermNC( g, info.news[ prj!.component ] ) ^ ( info.perms[ prj!.component ] ^ -1 ); end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . . . . . . of projection ## InstallMethod( PreImagesRepresentativeNC,"perm subdirect product projection", FamRangeEqFamElm, [ IsProjectionSubdirectProductWithEmbeddingsPermGroup, IsMultiplicativeElementWithInverse ], 0, function( prj, img ) local S, elm, # preimage of under , result info, # info record phi1, phi2; # homomorphisms of components S := Source( prj ); info := SubdirectProductWithEmbeddingsInfo( S ); # get the homomorphism phi1 := info.homomorphisms[1]; phi2 := info.homomorphisms[2]; # compute the preimage if 1 = prj!.component then elm := img ^ info.perms[1] * PreImagesRepresentativeNC(phi2,img^phi1) ^ info.perms[2]; else elm := img ^ info.perms[2] * PreImagesRepresentativeNC(phi1,img^phi2) ^ info.perms[1]; fi; # return the preimage return elm; end ); ############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( ) . . . . . . . of projection ## InstallMethod( KernelOfMultiplicativeGeneralMapping, "perm subdirect product projection",true, [ IsProjectionSubdirectProductWithEmbeddingsPermGroup ], 0, function( prj ) local D, i, info; D := Source( prj ); info := SubdirectProductWithEmbeddingsInfo( D ); i := 3 - prj!.component; return SubgroupNC( D, OnTuples ( GeneratorsOfGroup( KernelOfMultiplicativeGeneralMapping( info.homomorphisms[ i ] ) ), info.perms[ i ] ) ); end ); ############################################################################# ## #M ViewObj( ) . . . . . . . . . . . . . . . . . . . . view projection ## InstallMethod( ViewObj, "for projection from subdirect product", true, [ IsProjectionSubdirectProductWithEmbeddingsPermGroup ], 0, function( prj ) Print( Ordinal( prj!.component ), " projection of " ); View( Source( prj ) ); end ); ############################################################################# ## #M PrintObj( ) . . . . . . . . . . . . . . . . . . . print projection ## InstallMethod( PrintObj, "for projection from subdirect product", true, [ IsProjectionSubdirectProductWithEmbeddingsPermGroup ], 0, function( prj ) Print( "Projection( ", Source( prj ), ", ", prj!.component, " )" ); end ); ############################################################################# ## method copied from grpdpc.gi ## ############################################################################# ## #M SubdirectProductWithEmbeddingsOp( , , , ) ## InstallMethod( SubdirectProductWithEmbeddingsOp,"pcgroup", true, [ IsPcGroup, IsPcGroup, IsGroupHomomorphism, IsGroupHomomorphism ], 0, function( G, H, gh, hh ) local pg,ph,kg,kh,ig,ih,mg,mh,S,info; pg:=Pcgs(G); ph:=Pcgs(H); kg:=KernelOfMultiplicativeGeneralMapping(gh); kh:=KernelOfMultiplicativeGeneralMapping(hh); ig:=InducedPcgs(pg,kg); ih:=InducedPcgs(ph,kh); mg:=pg mod ig; mh:=List(mg,i->PreImagesRepresentativeNC(hh,Image(gh,i))); pg:=Concatenation(mg,ig,List(ih,i->One(G))); ph:=Concatenation(mh,List(ig,i->One(H)),ih); S:=SubdirProdPcGroups(G,pg,H,ph); pg:=GroupHomomorphismByImagesNC(S[1],G,S[2],pg); ph:=GroupHomomorphismByImagesNC(S[1],H,S[2],ph); S:=S[1]; info:=rec(groups:=[G,H], homomorphisms:=[gh,hh], projections:=[pg,ph]); SetSubdirectProductWithEmbeddingsInfo(S,info); return S; end); ############################################################################# ## #E groups.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/string.gd000644 000765 000024 00000001371 14621444241 020307 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W string.gd GAP4 package `Utils' Sebastian Gutsche ## Stefan Kohl ## #Y Copyright (C) 2015-2018, The GAP Group ############################################################################# ## this function has been transferred from ResClasses ## #F BlankFreeString( ) . . . . . . . . . . . . . string without blanks ## DeclareGlobalFunction( "BlankFreeString" ); ############################################################################# ## #E string.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/download.gi000644 000765 000024 00000016664 14621444241 020630 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W download.gi GAP4 package `Utils' Thomas Breuer ## #Y Copyright (C) 2022, The GAP Group ############################################################################# ## #V Download_Methods ## ## Use the following tools (in this order). ## ## - If the curlInterface package is available then call its ## 'DownloadURL' function. ## - If the URL starts with 'http://' and if the IO package is available ## then call the 'SingleHTTPRequest' function from this package. ## - If a 'wget' executable is available then call it. ## - If a 'curl' executable is available then call it. ## ## Note that currently the methods are *NOT* consistent in the case of ## failures: ## ## - The function 'SingleHTTPRequest' does not follow redirects as indicated ## by HTTP status codes 301 and 302. ## This happens for example if one asks for the file at ## 'http://www.gap-system.org/Packages/utils.html'. ## BindGlobal( "Download_Methods", [] ); Add( Download_Methods, rec( name:= "via DownloadURL (from the curlInterface package)", isAvailable:= {} -> IsPackageLoaded( "curlInterface" ) and CompareVersionNumbers( InstalledPackageVersion( "curlInterface" ), "2.3.0" ), download:= function( url, opt ) local res; opt:= ShallowCopy( opt ); if not IsBound( opt.failOnError ) then opt.failOnError:= true; fi; res:= ValueGlobal( "DownloadURL" )( url, opt ); if res.success = true and IsBound( opt.target ) and IsString( opt.target ) then FileString( opt.target, res.result ); Unbind( res.result ); fi; return res; end ) ); Add( Download_Methods, rec( name:= "via SingleHTTPRequest (from the IO package)", isAvailable:= {} -> IsBoundGlobal( "SingleHTTPRequest" ), download:= function( url, opt ) local rurl, pos, domain, uri, res; if not StartsWith( url, "http://" ) then return rec( success:= false, error:= "protocol is not http" ); fi; rurl:= ReplacedString( url, "http://", "" ); pos:= Position( rurl, '/' ); domain:= rurl{ [ 1 .. pos-1 ] }; uri:= rurl{ [ pos .. Length( rurl ) ] }; if IsBound( opt.target ) and IsString( opt.target ) then res:= ValueGlobal( "SingleHTTPRequest" )( domain, 80, "GET", uri, rec(), false, opt.target ); else res:= ValueGlobal( "SingleHTTPRequest" )( domain, 80, "GET", uri, rec(), false, false ); fi; if res.statuscode = 0 then return rec( success:= false, error:= res.status ); elif res.statuscode >= 400 then return rec( success:= false, error:= Concatenation( "HTTP error code ", res.statuscode ) ); elif not ( IsBound( opt.target ) and IsString( opt.target ) ) then return rec( success:= true, result:= res.body ); else return rec( success:= true ); fi; end ) ); Add( Download_Methods, rec( name:= "via wget", isAvailable:= function() local exec; exec:= Filename( DirectoriesSystemPrograms(), "wget" ); return exec <> fail and IsExecutableFile( exec ); end, download:= function( url, opt ) local res, outstream, exec, args, code; res:= ""; outstream:= OutputTextString( res, true ); exec:= Filename( DirectoriesSystemPrograms(), "wget" ); if IsBound( opt.target ) and IsString( opt.target ) then args:= [ "--quiet", "-O", opt.target, url ]; else args:= [ "--quiet", "-O", "-", url ]; fi; if IsBound( opt.verifyCert ) and opt.verifyCert = false then Add( args, "--no-check-certificate" ); fi; code:= Process( DirectoryCurrent(), exec, InputTextNone(), outstream, args ); CloseStream( outstream ); if code <> 0 then # wget may have created the target file; try to remove it if IsBound( opt.target ) and IsString( opt.target ) and IsExistingFile( opt.target ) and RemoveFile( opt.target ) <> true then Error( "Download cannot remove unwanted file ", opt.target ); fi; return rec( success:= false, error:= Concatenation( "Process returned ", String( code ) ) ); elif not ( IsBound( opt.target ) and IsString( opt.target ) ) then return rec( success:= true, result:= res ); else return rec( success:= true ); fi; end ) ); Add( Download_Methods, rec( name:= "via curl", isAvailable:= function() local exec; exec:= Filename( DirectoriesSystemPrograms(), "curl" ); return exec <> fail and IsExecutableFile( exec ); end, download:= function( url, opt ) local res, outstream, exec, args, code; res:= ""; outstream:= OutputTextString( res, true ); exec:= Filename( DirectoriesSystemPrograms(), "curl" ); args:= [ "--silent", "-L", "--fail" ]; if IsBound( opt.verifyCert ) and opt.verifyCert = false then Add( args, "-k" ); fi; Add( args, "--output" ); if IsBound( opt.target ) and IsString( opt.target ) then Add( args, opt.target ); else Add( args, "-" ); fi; Add( args, url ); code:= Process( DirectoryCurrent(), exec, InputTextNone(), outstream, args ); CloseStream( outstream ); if code <> 0 then return rec( success:= false, error:= Concatenation( "Process returned ", String( code ) ) ); elif not ( IsBound( opt.target ) and IsString( opt.target ) ) then return rec( success:= true, result:= res ); else return rec( success:= true ); fi; end ) ); ############################################################################# ## #M Download( [, ] ) ## ## Try to download the file described by the string , ## and return a record with the components 'success' ('true' or 'false'), ## and 'result' (a string, only if 'success' is 'true'), ## and 'error' (a string, only if 'success' is 'false'). ## InstallMethod( Download, [ "IsString" ], url -> Download( url, rec() ) ); InstallMethod( Download, [ "IsString", "IsRecord" ], function( url, opt ) local errors, r, res; # Set the default for 'verifyCert' if necessary. if not IsBound( opt.verifyCert ) and UserPreference( "utils", "DownloadVerifyCertificate" ) = false then opt.verifyCert:= false; fi; # Run over the methods. errors:= []; for r in Download_Methods do if r.isAvailable() then Info( InfoUtils, 2, "try Download method ", r.name ); res:= r.download( url, opt ); if res.success = true then return res; fi; Info( InfoUtils, 2, "Download method ", r.name, " failed with\n", "#I ", res.error ); Add( errors, Concatenation( r.name, ": ", res.error ) ); else Info( InfoUtils, 2, "Download method ", r.name, " is not available" ); fi; od; # No method was successful. if Length( errors ) = 0 then # No method was available, inform the user # that it is recommended to load or install some download tool. Info( InfoWarning, 1, "No 'Download' method is available.\n", "#I Please consider to install one of the tools, ", "see '?Download'" ); return rec( success:= false, error:= "no method was available" ); else # At least one method was tried but without success. return rec( success:= false, error:= JoinStringsWithSeparator( errors, "; " ) ); fi; end ); utils-0.86/lib/number.gi000644 000765 000024 00000015160 14621444241 020277 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W number.gi GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2018, The GAP Group ############################################################################# ## this function has been transferred from RCWA ## #F AllSmoothIntegers( , ) #F AllSmoothIntegers( , ) ## InstallGlobalFunction( AllSmoothIntegers, function ( maxp, maxn ) local extend, nums, primes, p; extend := function ( n, mini ) local i; if n > maxn then return; fi; Add(nums,n); for i in [mini..Length(primes)] do extend(primes[i]*n,i); od; end; if IsInt(maxp) then primes := Filtered([2..maxp],IsPrimeInt); elif IsList(maxp) and ForAll(maxp,p->IsInt(p) and IsPrimeInt(p)) then primes := maxp; else return fail; fi; if not IsPosInt(maxn) then return fail; fi; nums := []; extend(1,1); return Set(nums); end ); ############################################################################# ## this function has been transferred from RCWA ## #F NextProbablyPrimeInt( ) . . next integer passing `IsProbablyPrimeInt' ## InstallGlobalFunction( NextProbablyPrimeInt, function ( n ) if -3 = n then n := -2; elif -3 < n and n < 2 then n := 2; elif n mod 2 = 0 then n := n+1; else n := n+2; fi; while not IsProbablyPrimeInt(n) do if n mod 6 = 1 then n := n+4; else n := n+2; fi; od; return n; end ); ############################################################################# ## this function has been transferred from RCWA ## #F RestrictedPartitionsWithoutRepetitions( , ) ## ## Given a positive integer n and a set of positive integers S, this func- ## tion returns a list of all partitions of n into distinct elements of S. ## The only difference to `RestrictedPartitions' is that no repetitions are ## allowed. ## InstallGlobalFunction( RestrictedPartitionsWithoutRepetitions, function ( n, S ) local look, comps; look := function ( comp, remaining_n, remaining_S ) local newcomp, newremaining_n, newremaining_S, part, l; l := Reversed(remaining_S); for part in l do newcomp := Concatenation(comp,[part]); newremaining_n := remaining_n - part; if newremaining_n = 0 then Add(comps,newcomp); else newremaining_S := Set(Filtered(remaining_S, s->s [] then look(newcomp,newremaining_n,newremaining_S); fi; fi; od; end; comps := []; look([],n,S); return comps; end ); ############################################################################# ## this function has been transferred from RCWA ## #F PrimeNumbersIterator( ) #F PrimeNumbersIterator( chunksize ) ## InstallGlobalFunction( PrimeNumbersIterator, function ( arg ) local next, copy, chunksize, maxdiv, nrdivs, offset; if Length(arg) >= 1 and IsPosInt(arg[1]) then chunksize := Maximum(arg[1],100); # must be bigger than largest else chunksize := 10000000; fi; # prime gap in range looped over maxdiv := RootInt(chunksize); offset := List(Filtered([2..maxdiv],IsPrimeInt),p->[p,0]); nrdivs := Length(offset); return IteratorByFunctions( rec( NextIterator := function ( iter ) local sieve, range, p, q, pos, endpos, maxdiv_old, maxdiv, i, j; if iter!.index = 0 then sieve := ListWithIdenticalEntries(iter!.chunksize,0); if iter!.n = 0 then sieve[1] := 1; fi; for i in [1..iter!.nrdivs] do p := iter!.offset[i][1]; if p > iter!.n then pos := 2 * p; else pos := iter!.offset[i][2]; fi; if pos = 0 then pos := p; fi; endpos := pos + Int((iter!.chunksize-pos)/p) * p; if pos <= iter!.chunksize then range := [pos,pos+p..endpos]; if IsRangeRep(range) then ADD_TO_LIST_ENTRIES_PLIST_RANGE(sieve,range,1); else for j in range do sieve[j] := sieve[j] + 1; od; fi; fi; if endpos <= iter!.chunksize then iter!.offset[i][2] := endpos + p - iter!.chunksize; else iter!.offset[i][2] := iter!.offset[i][2] - iter!.chunksize; fi; od; iter!.primepos := Positions(sieve,0); fi; iter!.index := iter!.index + 1; p := iter!.n + iter!.primepos[iter!.index]; iter!.p := p; iter!.pi := iter!.pi + 1; if iter!.index = Length(iter!.primepos) then iter!.index := 0; iter!.n := iter!.n + iter!.chunksize; maxdiv_old := iter!.maxdiv; iter!.maxdiv := RootInt(iter!.n + iter!.chunksize); for q in Filtered([maxdiv_old+1..iter!.maxdiv],IsPrimeInt) do Add(iter!.offset,[q,(q-iter!.n) mod q]); od; iter!.nrdivs := Length(iter!.offset); fi; return p; end, ShallowCopy := function ( iter ) return rec( chunksize := iter!.chunksize, n := iter!.n, p := iter!.p, pi := iter!.pi, index := iter!.index, primepos := ShallowCopy(iter!.primepos), nrdivs := iter!.nrdivs, maxdiv := iter!.maxdiv, offset := StructuralCopy(iter!.offset) ); end, IsDoneIterator := ReturnFalse, chunksize := chunksize, n := 0, p := 0, pi := 0, index := 0, primepos := [], nrdivs := nrdivs, maxdiv := maxdiv, offset := offset ) ); end ); ############################################################################# ## this function has been transferred from RCWA ## #M AllProducts( , ) . . all products of -tuples of elements of #M AllProducts( , ) . . . . . . . . . . . . . . . . . . . . for lists ## InstallMethod( AllProducts, "for lists (RCWA)", ReturnTrue, [ IsList, IsPosInt ], 0, function(l,k) return List(Tuples(l,k),Product); end ); ############################################################################# ## #E number.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/latex.gd000644 000765 000024 00000001660 14621444241 020117 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W latex.gd GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2016, The GAP Group ############################################################################# ## this function has been transferred from ResClasses ## #F IntOrInfinityToLaTeX( n ) . LaTeX string representing integer or infinity ## DeclareGlobalFunction( "IntOrInfinityToLaTeX" ); ############################################################################# ## this function has been transferred from RCWA ## #F LaTeXStringFactorsInt( ) ## ## Returns the prime factorization of the integer as a string in LaTeX ## format. ## DeclareGlobalFunction( "LaTeXStringFactorsInt" ); ############################################################################# ## #E latex.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/lists.gd000644 000765 000024 00000003737 14621444241 020147 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W lists.gd GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2018, The GAP Group ############################################################################# ## these functions have been transferred from ResClasses ## #F DifferencesList( ) . . . . differences of consecutive list entries #F QuotientsList( ) . . . . . . quotients of consecutive list entries #F FloatQuotientsList( ) . . . . . . . . . . . . dito, but as floats ## DeclareGlobalFunction( "DifferencesList" ); DeclareGlobalFunction( "QuotientsList" ); DeclareGlobalFunction( "FloatQuotientsList" ); ############################################################################# ## this function has been transferred from ResClasses ## #F RandomCombination( S, k ) ## ## Returns a random unordered -tuple of distinct elements of the set . ## DeclareOperation( "RandomCombination", [ IsListOrCollection, IsPosInt ] ); ############################################################################# ## this function has been transferred from RCWA ## #F SearchCycle( ) . . . a utility function for detecting cycles in lists ## DeclareGlobalFunction( "SearchCycle" ); ############################################################################# ## these functions have been have been transferred from XMod ## #O DistinctRepresentatives( ) #O CommonRepresentatives( , ) #O CommonTransversal( , ) #O IsCommonTransversal( , , ) ## DeclareOperation( "DistinctRepresentatives", [ IsList ] ); DeclareOperation( "CommonRepresentatives", [ IsList, IsList ] ); DeclareOperation( "CommonTransversal", [ IsGroup, IsGroup ] ); DeclareOperation( "IsCommonTransversal", [ IsGroup, IsGroup, IsList ] ); ############################################################################# ## #E lists.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/lcset.gd000644 000765 000024 00000002646 14621444241 020121 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W lcset.gd GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2022, The GAP Group ############################################################################# ## #C IsLeftCoset( ) . . . . . . . . . . . . . . coset of the form gU #R IsLeftCosetDefaultRep #V IsLeftCosetFamily #T IsLeftCosetType ## DeclareCategory( "IsLeftCoset", IsDomain and IsExternalOrbit ); DeclareRepresentation( "IsLeftCosetDefaultRep", IsComponentObjectRep and IsAttributeStoringRep and IsLeftCoset, [ "Representative", "ActingDomain" ] ); BindGlobal( "IsLeftCosetFamily", NewFamily( "IsLeftCosetFamily", IsMultiplicativeElementWithInverse ) ); BindGlobal( "IsLeftCosetType", NewType( IsLeftCosetFamily, IsLeftCosetDefaultRep ) ); ############################################################################# ## #O LeftCoset( , ) . . . . . . . element g acts on the left of group U ## DeclareOperation( "LeftCoset", [ IsObject, IsGroup ] ); ############################################################################# ## #O LeftCosets( , ) . . . . . . . . . . . . . . . cosets gU for g in G #O LeftCosetsNC( , ) . . . . . . . . . . . . . . cosets gU for g in G ## DeclareGlobalFunction( "LeftCosets" ); DeclareOperation( "LeftCosetsNC", [ IsGroup, IsGroup ] ); utils-0.86/lib/print.gi000644 000765 000024 00000011204 14621444241 020136 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W print.gi GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2024, The GAP Group ############################################################################# ## these operations have not been transferred from any other package ## #M PrintSelection( ) #M PrintSelectionFromList( , , , ) #M PrintSelectionFromIterator( , , , ) ## InstallGlobalFunction( "PrintSelection", function( arg ) local nargs, obj, first, step, last, L, ok; nargs := Length( arg ); obj := arg[1]; if ( ( nargs = 1 ) or ( nargs > 4 ) ) then Error( "expecting 2, 3 or 4 arguments" ); elif ( nargs = 2 ) then L := arg[2]; if IsList( L ) then ok := ForAll( L, IsPosInt ); if not ok then Error( "L must only contain positive integers" ); fi; if IsList( obj ) then PrintSelectionFromListByList( obj, L ); elif IsIterator( obj ) then PrintSelectionFromIteratorByList( obj, L ); else PrintSelectionFromIteratorByList( Iterator( obj ), L ); fi; else Error( "second argument not a list" ); fi; else first := arg[2]; step := arg[3]; if ( nargs = 3 ) then if IsList( obj ) then last := Length( obj ); else last := infinity; fi; else last := arg[4]; fi; if IsList( obj ) then PrintSelectionFromList( obj, first, step, last ); elif IsIterator( obj ) then PrintSelectionFromIterator( obj, first, step, last ); else PrintSelectionFromIterator( Iterator( obj ), first, step, last ); fi; fi; end ); InstallMethod( PrintSelectionFromList, "generic method for lists", true, [ IsList, IsPosInt, IsPosInt, IsPosInt ], 0, function( L, first, step, last ) local len, i; len := Minimum( Length( L ), last ); if ( first <= len ) then Print( first, " : ", L[first], "\n" ); len := len-first; i := first; while ( len >= step ) do i := i+step; Print( i, " : ", L[i], "\n" ); len := len-step; od; fi; end ); InstallOtherMethod( PrintSelectionFromIterator, "generic method for iterators", true, [ IsIterator, IsPosInt, IsPosInt, IsAdditiveElement ], 0, function( iter0, first, step, last ) local iter, pos, i, x; if ( last < first ) then Error( "expecting first <= last" ); fi; iter := ShallowCopy( iter0 ); i := 0; while( ( i < first ) and not IsDoneIterator( iter ) ) do i := i+1; x := NextIterator( iter ); od; if ( i = first ) then pos := first; Print( pos, " : ", x, "\n" ); fi; while ( not IsDoneIterator( iter ) and ( pos < last ) ) do while ( not IsDoneIterator( iter ) and ( pos < last ) ) do i := 0; while( ( i ) ## ## This auxiliary function assigns the record components of ## to global variables with the same names. ## InstallGlobalFunction( AssignGlobals, function ( record ) local names, name; names := RecNames(record); for name in names do if IsBoundGlobal(name) then if IsReadOnlyGlobal(name) then MakeReadWriteGlobal(name); Info(InfoWarning,1,"The read-only global variable ",name, " has been overwritten."); else Info(InfoUtils,1,"The global variable ",name, " has been overwritten."); fi; UnbindGlobal(name); fi; BindGlobal(name,record.(name)); MakeReadWriteGlobal(name); od; Print("The following global variables have been assigned:\n", Set(names),"\n"); end ); InstallGlobalFunction( OptionRecordWithDefaults, function(default, useroptions) local name, ret; ret := rec(); if IsList(useroptions) then if IsEmpty(useroptions) then return default; elif Length(useroptions) = 1 then useroptions := useroptions[1]; else ErrorNoReturn("Too many arguments for function"); fi; fi; if not IsRecord(useroptions) then ErrorNoReturn("Options should be a record"); fi; ret := ShallowCopy(default); for name in RecNames(useroptions) do if not IsBound(default.(name)) then ErrorNoReturn(Concatenation("Unknown option: " , name)); else ret.(name) := useroptions.(name); fi; od; return ret; end); ############################################################################# ## #E record.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/matrix.gd000644 000765 000024 00000001023 14621444241 020277 0ustar00christopherwensleystaff000000 000000 ############################################################################ ## #W matrix.gd GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2023, The GAP Group ############################################################################# ## This function ... ## #O DirectSumDecompositionMatrices( ) ## DeclareOperation( "DirectSumDecompositionMatrices", [ IsMatrixOrMatrixObj ] ); DeclareOperation( "DirectSumBlock", [ IsMatrixOrMatrixObj, IsInt, IsList, IsList ] ); utils-0.86/lib/files.gd000644 000765 000024 00000002101 14621444241 020073 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W files.gd GAP4 package `Utils' Sebastian Gutsche ## Max Horn ## Stefan Kohl #Y Copyright (C) 2015-2018, The GAP Group ############################################################################# ## this function has been transferred from RCWA ## #F Log2HTML ( logfilename ) ## ## Utility to convert GAP log files to XHTML 1.0 Strict. ## ## Usage: ## ## - Issue Log2HTML( ). The extension of the input file must ## be *.log. The name of the output file is the same as the one of the ## input file except that the extension *.log is replaced by *.html. ## ## - Adapt the style file rcwa/doc/gaplog.css to your taste. ## DeclareGlobalFunction( "Log2HTML" ); ############################################################################# ## #E files.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/iterator.gi000644 000765 000024 00000020715 14621444241 020642 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W iterator.gi GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2019, The GAP Group ############################################################################## ## #M AllIsomorphismsIterator . . . . . . . . . . . . . . . for a pair of groups #M DoAllIsomorphismsIterator . . . . . . . . . . . . . . for a pair of groups #M AllIsomorphismsNumber . . . . . . . . . . . . . . . . for a pair of groups #M AllIsomorphisms . . . . . . . . . . . . . . . . . . . for a pair of groups ## BindGlobal( "NextIterator_AllIsomorphisms", function ( iter ) local a; if not IsDoneIterator( iter ) then a := NextIterator( iter!.autoIterator ); return CompositionMapping( iter!.firstiso, a ); fi; Error( "iterator is exhausted" ); end ); BindGlobal( "IsDoneIterator_AllIsomorphisms", iter -> IsDoneIterator( iter!.autoIterator ) ); BindGlobal( "ShallowCopy_AllIsomorphisms", iter -> rec( firstiso := iter!.firstiso, autoIterator := ShallowCopy( iter!.autoIterator ) ) ); InstallGlobalFunction( "DoAllIsomorphismsIterator", function( G, H ) local iso, autoiter, iter; if not IsGroup( G ) and IsGroup( H ) then Error( "G,H should be groups" ); fi; iso := IsomorphismGroups( G, H ); if ( iso = fail ) then ## there are no isomorphisms so return an empty iterator return IteratorList( [ ] ); fi; autoiter := Iterator( AutomorphismGroup( G ) ); iter := IteratorByFunctions( rec( firstiso := iso, autoIterator := ShallowCopy( autoiter ), NextIterator := NextIterator_AllIsomorphisms, IsDoneIterator := IsDoneIterator_AllIsomorphisms, ShallowCopy := ShallowCopy_AllIsomorphisms ) ); return iter; end ); InstallMethod( AllIsomorphismsIterator, "for a pair of groups", [ IsGroup, IsGroup ], 0, function( G, H ) return DoAllIsomorphismsIterator( G, H ); end ); InstallMethod( AllIsomorphisms, "for a pair of groups", [ IsGroup, IsGroup ], 0, function( G, H ) local iter, L, iso; iter := AllIsomorphismsIterator( G, H ); if IsDoneIterator( iter ) then return [ ]; fi; L := [ ]; for iso in iter do Add( L, iso ); od; return L; end ); InstallMethod( AllIsomorphismsNumber, "for a pair of groups", [ IsGroup, IsGroup ], 0, function( G, H ) local iter, n, iso; iter := AllIsomorphismsIterator( G, H ); if IsDoneIterator( iter ) then return 0; fi; n := 0; for iso in iter do n := n+1; od; return n; end ); ############################################################################## ## #M AllSubgroupsIterator . . . . . . . . . . . . . . . . . . . . . for a group #M DoAllSubgroupsIterator . . . . . . . . . . . . . . . . . . . . for a group ## BindGlobal( "NextIterator_AllSubgroups", function ( iter ) local class, i; if IsDoneIterator( iter!.subgpIterator ) then class := NextIterator( iter!.classIterator ); iter!.class := class; iter!.subgpIterator := IteratorList( [1..Size(class)] ); fi; i := NextIterator( iter!.subgpIterator ); return iter!.class[i]; end ); BindGlobal( "IsDoneIterator_AllSubgroups", iter -> IsDoneIterator( iter!.classIterator ) and IsDoneIterator( iter!.subgpIterator ) ); BindGlobal( "ShallowCopy_AllSubgroups", iter -> rec( class := iter!.class, classIterator := ShallowCopy( iter!.classIterator ), subgpIterator := ShallowCopy( iter!.subgpIterator ) ) ); InstallGlobalFunction( "DoAllSubgroupsIterator", function( G ) local lat, ccs, classIterator, subgpIterator, iter; lat := LatticeSubgroups( G ); ccs := ConjugacyClassesSubgroups( lat ); classIterator := IteratorList( ccs ); subgpIterator := 0; iter := IteratorByFunctions( rec( class := 0, classIterator := ShallowCopy( classIterator ), subgpIterator := IteratorList( [ ] ), NextIterator := NextIterator_AllSubgroups, IsDoneIterator := IsDoneIterator_AllSubgroups, ShallowCopy := ShallowCopy_AllSubgroups ) ); return iter; end ); InstallMethod( AllSubgroupsIterator, "for a group", [ IsGroup ], 0, function( G ) return DoAllSubgroupsIterator( G ); end ); ############################################################################## ## #M CartesianIterator . . . . . . . . . . . . . . . . . . . for two iterators #M DoCartesianIterator . . . . . . . . . . . . . . . . . . for two iterators ## BindGlobal( "NextIterator_CartesianIterator", function ( iter ) local first, second; if IsDoneIterator( iter!.Iterator2Copy ) then iter!.Iterator2Copy := ShallowCopy( iter!.Iterator2 ); first := NextIterator( iter!.Iterator1 ); iter!.first := first; else first := iter!.first; fi; second := NextIterator( iter!.Iterator2Copy ); return [ first, second ]; end ); BindGlobal( "IsDoneIterator_CartesianIterator", iter -> IsDoneIterator( iter!.Iterator1 ) and IsDoneIterator( iter!.Iterator2Copy ) ); BindGlobal( "ShallowCopy_CartesianIterator", iter -> rec( first := iter!.first, Iterator1 := ShallowCopy( iter!.Iterator1 ), Iterator2 := ShallowCopy( iter!.Iterator2 ), Iterator2Copy := ShallowCopy( iter!.Iterator2Copy ) ) ); InstallGlobalFunction( "DoCartesianIterator", function( iter1, iter2 ) local iter; if IsDoneIterator( iter1 ) or IsDoneIterator( iter2 ) then return IteratorList( [ ] ); fi; iter := IteratorByFunctions( rec( first := 0, Iterator1 := ShallowCopy( iter1 ), Iterator2 := ShallowCopy( iter2 ), Iterator2Copy := IteratorList( [ ] ), NextIterator := NextIterator_CartesianIterator, IsDoneIterator := IsDoneIterator_CartesianIterator, ShallowCopy := ShallowCopy_CartesianIterator ) ); return iter; end ); InstallMethod( CartesianIterator, "for two iterators", [ IsIterator, IsIterator ], 0, function( iter1, iter2 ) return DoCartesianIterator( iter1, iter2 ); end ); ############################################################################## ## #M UnorderedPairsIterator . . . . . . . . . . . . . . . . . . for an iterator #M DoUnorderedPairsIterator . . . . . . . . . . . . . . . . . for an iterator ## BindGlobal( "NextIterator_UnorderedPairs", function ( iter ) local first, second; if ( iter!.pos1 = iter!.pos2 ) then iter!.Iterator1Copy := ShallowCopy( iter!.Iterator1 ); iter!.pos1 := 0; second := NextIterator( iter!.Iterator2 ); iter!.pos2 := iter!.pos2 + 1; iter!.second := second; else second := iter!.second; fi; first := NextIterator( iter!.Iterator1Copy ); iter!.pos1 := iter!.pos1 + 1; return [ first, second ]; end ); BindGlobal( "IsDoneIterator_UnorderedPairs", iter -> IsDoneIterator( iter!.Iterator2 ) and IsDoneIterator( iter!.Iterator1Copy ) ); BindGlobal( "ShallowCopy_UnorderedPairs", iter -> rec( pos1 := iter!.pos1, pos2 := iter!.pos2, second := iter!.second, Iterator1 := ShallowCopy( iter!.Iterator1 ), Iterator2 := ShallowCopy( iter!.Iterator2 ), Iterator1Copy := ShallowCopy( iter!.Iterator1Copy ) ) ); InstallGlobalFunction( "DoUnorderedPairsIterator", function( iter0 ) local iter; if IsDoneIterator( iter0 ) then return IteratorList( [ ] ); fi; iter := IteratorByFunctions( rec( pos1 := 0, pos2 := 0, second := 0, Iterator1 := ShallowCopy( iter0 ), Iterator2 := ShallowCopy( iter0 ), Iterator1Copy := ShallowCopy( iter0 ), NextIterator := NextIterator_UnorderedPairs, IsDoneIterator := IsDoneIterator_UnorderedPairs, ShallowCopy := ShallowCopy_UnorderedPairs ) ); return iter; end ); InstallMethod( UnorderedPairsIterator, "for an iterator", [ IsIterator ], 0, function( iter0 ) return DoUnorderedPairsIterator( iter0 ); end ); utils-0.86/lib/maps.gd000644 000765 000024 00000004371 14621444241 017744 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W maps.gd GAP4 package `Utils' Stefan Kohl ## Chris Wensley #Y Copyright (C) 2015-2019, The GAP Group ############################################################################# ## these three functions were in RCWA and were initially transferred but, ## to simplify the situation, just EpimorphismByGenerators has been retained ## #O EpimorphismByGenerators( , ) . epi: gen's of ->gen's of #O EpimorphismByGeneratorsNC( , ) . . NC version as underlying oper #M EpimorphismByGeneratorsNC( , ) . . . . . . . . . . . . for groups ## DeclareOperation( "EpimorphismByGenerators", [ IsDomain, IsDomain ] ); ############################################################################# ## #O Pullback( , ) #A PullbackInfo( ) ## DeclareOperation( "Pullback", [ IsGroupHomomorphism, IsGroupHomomorphism ] ); DeclareAttribute( "PullbackInfo", IsGroup, "mutable" ); ############################################################################# ## #O CentralProduct( , , , ) #A CentralProductInfo( ) ## DeclareOperation( "CentralProduct", [ IsGroup, IsGroup, IsGroup, IsGroupHomomorphism ] ); DeclareAttribute( "CentralProductInfo", IsGroup, "mutable" ); ############################################################################# ## these functions compute idempotent endomorphisms on G with image R ## #O IdempotentEndomorphisms( ) #A IdempotentEndomorphismsWithImage( , ) #A IdempotentEndomorphismsData( ) ## DeclareOperation( "IdempotentEndomorphisms", [ IsGroup ] ); DeclareOperation( "IdempotentEndomorphismsWithImage", [ IsList, IsGroup ] ); DeclareAttribute( "IdempotentEndomorphismsData", IsGroup ); ############################################################################# ## #O DirectProductOfFunctions( , , , ) #O DirectProductOfAutomorphismGroups( , ) ## DeclareOperation( "DirectProductOfFunctions", [ IsGroup, IsGroup, IsGroupHomomorphism, IsGroupHomomorphism ] ); DeclareOperation( "DirectProductOfAutomorphismGroups", [ IsGroup, IsGroup ] ); utils-0.86/lib/magma.gi000644 000765 000024 00000020265 14621444241 020073 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W magma.gi GAP4 package `Utils' Max Horn ## Alexander Hulpke ## Frank Lübeck ## #Y Copyright (C) 2015-2022, The GAP Group ############################################################################# ## #F ConvertToMagmaInputString( ) . . output a string readable by Magma ## InstallGlobalFunction( ConvertToMagmaInputString, function ( arg ) local len, obj, s, str; len := Length( arg ); obj := arg[1]; if not IsGroup( obj ) then Error( "input obj should be a group" ); elif IsPcGroup( obj ) then str := PcGroupToMagmaFormat( obj ); elif IsPermGroup( obj ) then str := PermGroupToMagmaFormat( obj ); elif IsMatrixGroup( obj ) then str := MatrixGroupToMagmaFormat( obj ); elif IsFpGroup( obj ) then Error( "no conversion function yet available for fp-groups" ); ## str := FpGroupToMagmaFormat( obj ); else Error( "no conversion function yet available for this group" ); fi; if ( len > 1 ) then s := arg[2]; if IsMatrixGroup( obj ) then str := ReplacedString( str, "sub", Concatenation(s," := sub") ); else str := Concatenation( s, " := ", str ); fi; fi; return str; end ); ############################################################################# ## this function was originally authored by Alexander Hulpke; ## has been transferred from other.gi in the main library; ## and was originally named MagmaInputString ## InstallMethod( PermGroupToMagmaFormat, "perm group", true, [IsPermGroup], 0, function( g ) local s, i, nf; ## s := ShallowCopy(s); ## Append(s,":=PermutationGroup<"); s := "PermutationGroup<"; Append( s, String( LargestMovedPoint(g) ) ); Add( s, '|' ); nf := false; for i in GeneratorsOfGroup(g) do if nf then Append( s, ",\n" ); fi; nf:=true; Append( s, String(i) ); od; Append( s, ">;\n" ); return s; end ); ############################################################################# ## this function was private code of Max Horn ## InstallMethod( PcGroupToMagmaFormat, "pc-group", true, [IsPcGroup], 0, function(G) local str, g, n, r, gens, rels, i, j; g := Pcgs(G); n := Length(g); r := RelativeOrders(g); gens := List(g,String); str := "PolycyclicGroup< "; Append(str, JoinStringsWithSeparator(gens)); Append(str, " |\n"); rels := []; for i in [1..n] do if r[i] = 0 then continue; fi; if IsOne(g[i]^r[i]) then Add(rels, Concatenation(String(g[i]), "^", String(r[i]))); else Add(rels, Concatenation(String(g[i]), "^", String(r[i]), " = ", String(g[i]^r[i]))); fi; od; for i in [2..n] do for j in [1..i-1] do if g[i]*g[j] <> g[j]*g[i] then Add(rels, Concatenation(String(g[i]), "^", String(g[j]), " = ", String(g[i]^g[j]))); if r[j] = 0 then Add(rels, Concatenation(String(g[i]), "^", String(g[j]), "^-1 = ", String(g[i]^(g[j]^-1)))); fi; fi; od; od; Append(str, JoinStringsWithSeparator(rels, ",\n")); Append(str, "\n>;\n"); return str; end ); ############################################################################### ## This function has been converted from private code of Frank Lübeck. ## His GapToMagma(file,mats) wrote Magma code to a file 'file' for the group ## generated by a list 'mats' of matrices over same finite field. ## In this revised form the function inputs a matrix group over a finite ## field and outputs a string which can be read by Magma. ## InstallMethod( MatrixGroupToMagmaFormat, "matrix group over a finite field", true, [ IsMatrixGroup ], 0, function(G) local mats, nr, nc, F, tab, p, q, e, w, wp, pow, zero, one, val, cpn, npl, NmrIter, FinalIter, i, j, cno, isint, matrix, str; mats := GeneratorsOfGroup( G ); F := Field( Flat( mats ) ); p := Characteristic( F ); e := DegreeOverPrimeField( F ); q := Size( F ); w := PrimitiveElement( F ); zero := Zero( F ); one := One( F ); matrix := mats[1]; nr := Length( matrix ); nc := Length( matrix[1] ); str := Concatenation( "F := ", String(F), ";\n" ); Append( str, Concatenation( "P := GL(", String(nr), ",F);\n" ) ); matrix := mats; if ( e > 1 ) then Append( str, "w := PrimitiveElement(F);\n" ); fi; pow := (q-1)/(p-1); wp := w^pow; tab := [ ]; for i in [1..p-1] do tab[ LogFFE( i*one, wp ) + 1 ] := i; od; if ( p < 10 ) then cpn := 3; elif ( p < 100 ) then cpn := 4; elif ( p < 1000 ) then cpn := 5; elif ( p < 10000 ) then cpn := 6; else cpn := 7; fi; if ( e > 1 ) then cpn := cpn + 2; fi; npl := Int(76/(cpn)); ## should be 78, but it overflowed. Append( str, "gens := [\n"); FinalIter := Length( mats ); NmrIter := 0; for matrix in mats do NmrIter := NmrIter + 1; nr := Length( matrix ); nc := Length( matrix[1] ); Append( str, "P![" ); for i in [1..nr] do cno := 0; for j in [1..nc] do if ( matrix[i][j] = zero ) then val := 0; isint := true; else val := LogFFE( matrix[i][j], w ); if ( val mod pow = 0 ) then val := tab[ LogFFE( matrix[i][j], wp ) + 1]; isint := true; else isint := false; fi; fi; if ( q<10 ) or ( q<100 and val>=10 ) or ( q<1000 and val>=100 ) or ( q<10000 and val>=1000 ) or ( val>=10000 ) then if not (i = 1 and j = 1) then Append( str, "," ); fi; elif ( q<100 ) or ( q<1000 and val>=10 ) or ( q<10000 and val>=100 ) or ( val>=1000 ) then if not (i = 1 and j = 1) then Append( str, " , " ); fi; elif ( q<1000 ) or ( q<10000 and val>=10 ) or ( val>=100 ) then if not (i = 1 and j = 1) then Append( str, " , " ); fi; elif ( q<10000 ) or ( val>=10 ) then if not (i = 1 and j = 1) then Append( str, " , " ); fi; else if not (i = 1 and j = 1) then Append( str, " , " ); fi; fi; if ( e > 1 ) then if isint then Append( str, " " ); else Append( str, "w^" ); fi; fi; Append( str, String(val) ); cno := cno+1; if ( cno>=npl and j FinalIter ) then Append( str, "],\n" ); else Append( str, "]\n" ); fi; od; Append( str, "];\n" ); Append( str, "sub

;\n" ); return str; end ); ############################################################################# ## #E magma.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/groups.gd000644 000765 000024 00000005113 14621444241 020316 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W groups.gd GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2016, The GAP Group ############################################################################# ## this function has been transferred from ResClasses ## #O IsCommuting( , ) . checks whether two group elements etc. commute ## DeclareOperation( "IsCommuting", [ IsMultiplicativeElement, IsMultiplicativeElement ] ); ############################################################################# ## these functions have been transferred from ResClasses ## #A UpperFittingSeries( ) . . . . . . . . . . upper fitting series of #A LowerFittingSeries( ) . . . . . . . . . . lower fitting series of #A FittingLength( ) . . . . . . . . . . . . . . . fitting length of ## ## The upper and lower Fitting series and the Fitting length of a solvable ## group, as described here: https://en.wikipedia.org/wiki/Fitting_length ## if not IsBound( UpperFittingSeries ) then DeclareAttribute( "UpperFittingSeries", IsGroup ); fi; if not IsBound( LowerFittingSeries ) then DeclareAttribute( "LowerFittingSeries", IsGroup ); fi; if not IsBound( FittingLength ) then DeclareAttribute( "FittingLength", IsGroup ); fi; ############################################################################# ## this function has been transferred from RCWA ## #F ListOfPowers( , ) . . . . . . list of powers ^1 .. ^ ## DeclareGlobalFunction( "ListOfPowers" ); ############################################################################# ## this function has been transferred from RCWA ## #O GeneratorsAndInverses( ) list of generators of and their inverses #M GeneratorsAndInverses( ) . . . . . . . . . . . . . . . . . for groups ## DeclareOperation( "GeneratorsAndInverses", [ IsMagmaWithInverses ] ); ############################################################################# ## this function has been copied from main library gprd.gd and renamed ## #O SubdirectProductWithEmbeddings(, , , ) ## DeclareGlobalFunction("SubdirectProductWithEmbeddings"); DeclareOperation( "SubdirectProductWithEmbeddingsOp", [ IsGroup, IsGroup, IsGroupHomomorphism, IsGroupHomomorphism ] ); DeclareAttribute( "SubdirectProductWithEmbeddingsInfo", IsGroup, "mutable" ); ############################################################################# ## #E groups.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/start.gd000644 000765 000024 00000004552 14621444241 020142 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W start.gd GAP4 package `Utils' Chris Wensley ## #Y Copyright (C) 2015-2022, The GAP Group DeclareInfoClass( "InfoUtils" ); ## these version numbers refer to the latest package releases ## containing the code which is to be transferred UtilsPackageVersions := [ "autodoc", "2016.01.31", ## latest is 2017.09.08 "resclasses", "4.2.5", ## latest is 4.7.1, 18/12/17 "rcwa", "4.1.5" ## latest is 4.6.2, 26/06/18 ]; ## (04/09/18) removed QPA from this list - no functions transferred ## (02/06/18) removed xmod from this list ## functions being transferred cannot be used until the Home packages have ## been loaded: when this has been done the following variable is set true UtilsLoadingComplete := false; ############################################################################# ## #F OKtoReadFromUtils( ) . . . tests whether name still contains the ## code to be transferred to Utils #F OKtoReadFromUtilsSpec( , ) . . . special case of above ## BindGlobal( "OKtoReadFromUtils", function( Name ) local name, ver, ver0, pos, ok; name := LowercaseString( Name ); pos := Position( UtilsPackageVersions, name ); if ( pos = fail ) then Error( "package 'name' not in the list UtilsPackageVersions" ); fi; ver0 := UtilsPackageVersions[ pos+1 ]; ver := InstalledPackageVersion( name ); ok := ( ( ver = fail ) ## name is not installed on the system or ( ver > ver0 ) ); ## name still contains the code return ok; end ); BindGlobal( "OKtoReadFromUtilsSpec", function( Name, oldver ) local name, ver, pos, ok; name := LowercaseString( Name ); pos := Position( UtilsPackageVersions, name ); if ( pos = fail ) then Error( "package 'name' not in the list UtilsPackageVersions" ); fi; ver := InstalledPackageVersion( name ); ok := ( ( ver = fail ) ## name is not installed on the system or ( ver > oldver ) ); ## name still contains the code return ok; end ); ############################################################################# ## #E start.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/string.gi000644 000765 000024 00000001560 14621444241 020314 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W string.gi GAP4 package `Utils' Sebastian Gutsche ## Stefan Kohl ## #Y Copyright (C) 2015-2018, The GAP Group ############################################################################# ## this function has been transferred from ResClasses ## #F BlankFreeString( ) . . . . . . . . . . . . . string without blanks ## InstallGlobalFunction( BlankFreeString, function ( obj ) local str; str := String(obj); RemoveCharacters(str," "); return str; end ); ############################################################################# ## #E string.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/latex.gi000644 000765 000024 00000003224 14621444241 020122 0ustar00christopherwensleystaff000000 000000 ############################################################################# ## #W latex.gi GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2016, The GAP Group ############################################################################# ## this function has been transferred from ResClasses ## #F IntOrInfinityToLaTeX( n ) . LaTeX string for a given integer or infinity ## InstallGlobalFunction( IntOrInfinityToLaTeX, function( n ) if IsInt(n) then return String(n); elif IsInfinity(n) then return "\\infty"; else return fail; fi; end ); ############################################################################# ## this function has been transferred from RCWA ## #F LaTeXStringFactorsInt( ) . . . . prime factorization in LaTeX format ## InstallGlobalFunction( LaTeXStringFactorsInt, function ( n ) local facts, str, i; if not IsInt(n) then Error("usage: LaTeXStringFactorsInt( ) for an integer "); fi; if n < 0 then str := "-"; n := -n; else str := ""; fi; facts := Collected(Factors(n)); for i in [1..Length(facts)] do Append(str,String(facts[i][1])); if facts[i][2] > 1 then Append(str,"^"); if facts[i][2] >= 10 then Append(str,"{"); fi; Append(str,String(facts[i][2])); if facts[i][2] >= 10 then Append(str,"}"); fi; fi; if i < Length(facts) then Append(str," \\cdot "); fi; od; return str; end ); ############################################################################# ## #E latex.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/number.gd000644 000765 000024 00000004740 14621444241 020274 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W number.gd GAP4 package `Utils' Stefan Kohl ## #Y Copyright (C) 2015-2018, The GAP Group ############################################################################# ## this function has been transferred from RCWA ## #F NextProbablyPrimeInt( ) . . next integer passing `IsProbablyPrimeInt' ## ## Returns the smallest integer larger than which passes GAP's ## probabilistic primality test. ## ## The function `NextProbablyPrimeInt' does the same as `NextPrimeInt', ## except that for reasons of performance it tests numbers only for ## `IsProbablyPrimeInt' instead of `IsPrimeInt'. ## For large , this function is much faster than `NextPrimeInt'. ## DeclareGlobalFunction( "NextProbablyPrimeInt" ); ############################################################################# ## this function has been transferred from RCWA ## #F AllSmoothIntegers( , ) ## ## Returns the set of all integers in the range [1..] which have only ## prime divisors in the range [2..]. ## DeclareGlobalFunction( "AllSmoothIntegers" ); ############################################################################# ## this function has been transferred from RCWA ## #F PrimeNumbersIterator( ) #F PrimeNumbersIterator( chunksize ) ## ## Iterator running through the prime numbers in ascending order. ## DeclareGlobalFunction ( "PrimeNumbersIterator" ); ############################################################################# ## this function has been transferred from RCWA ## #F RestrictedPartitionsWithoutRepetitions( , ) ## ## Given a positive integer n and a set of positive integers S, this func- ## tion returns a list of all partitions of n into distinct elements of S. ## The only difference to `RestrictedPartitions' is that no repetitions are ## allowed. ## DeclareGlobalFunction( "RestrictedPartitionsWithoutRepetitions" ); ############################################################################# ## this function has been transferred from RCWA ## #O AllProducts( , ) . . all products of -tuples of elements of #M AllProducts( , ) . . . . . . . . . . . . . . . . . . . . for lists ## DeclareOperation( "AllProducts", [ IsListOrCollection, IsPosInt ] ); ############################################################################# ## #E number.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here utils-0.86/lib/download.gd000644 000765 000024 00000002243 14621444241 020607 0ustar00christopherwensleystaff000000 000000 ############################################################################## ## #W download.gd GAP4 package `Utils' Thomas Breuer ## #Y Copyright (C) 2022, The GAP Group ############################################################################# ## This function is intended to be used instead of similar ones from ## various packages (AtlasRep, FactInt, GAPDoc, PackageManager, ## StandardFF, ...) ## #O Download( [, ] ) ## DeclareOperation( "Download", [ IsString ] ); DeclareOperation( "Download", [ IsString, IsRecord ] ); ############################################################################# ## #U DownloadVerifyCertificate ## DeclareUserPreference( rec( name:= "DownloadVerifyCertificate", description:= [ "The value 'true' (the default) means that the server's certificate \ is checked in calls of 'Download' such that nothing gets downloaded \ if the certificate is invalid. \ If the value is 'false' then those download methods that are based on \ curl or wget will omit the check of the server's certificate." ], default:= true, values:= [ true, false ], multi:= false, package:= "utils", ) );