1############################################################################# 2## 3#W classes.gi Testing properties/varieties [loops] 4## 5## 6#Y Copyright (C) 2004, G. P. Nagy (University of Szeged, Hungary), 7#Y P. Vojtechovsky (University of Denver, USA) 8## 9 10############################################################################# 11## ASSOCIATIVITY, COMMUTATIVITY AND GENERALIZATIONS 12## ------------------------------------------------------------------------- 13 14# (PROG) IsAssociative is already implemented for magmas, but we provide 15# a new method based on sections. This new method is much faster for groups, 16# and a bit slower for nonassociative loops. 17 18InstallOtherMethod( IsAssociative, "for loops", 19 [ IsLoop ], 0, 20function( Q ) 21 local sLS, x, y; 22 sLS := Set( LeftSection( Q ) ); 23 for x in LeftSection( Q ) do 24 for y in LeftSection( Q ) do 25 if not x*y in sLS then return false; fi; 26 od; 27 od; 28 return true; 29end); 30 31# implies 32# InstallTrueMethod( IsExtraLoop, IsAssociative and IsLoop ); 33 34############################################################################# 35## 36#P IsCommutative( Q ) 37## 38## Returns true if <Q> is commutative. 39 40InstallOtherMethod( IsCommutative, "for quasigroup", 41 [ IsQuasigroup ], 42function( Q ) 43 return LeftSection( Q ) = RightSection( Q ); 44end ); 45 46############################################################################# 47## 48#P IsPowerAssociative( Q ) 49## 50## Returns true if <Q> is a power associative quasigroup. 51 52InstallOtherMethod( IsPowerAssociative, "for quasigroup", 53 [ IsQuasigroup ], 54function( Q ) 55 local checked, x, S; 56 checked := []; 57 repeat 58 x := Difference( Elements(Q), checked ); 59 if IsEmpty( x ) then 60 return true; 61 fi; 62 S := Subquasigroup( Q, [x[1]] ); 63 if not IsAssociative( S ) then 64 return false; 65 fi; 66 checked := Union( checked, Elements( S ) ); # S is a group, so every subquasigroup of S is a group 67 until 0=1; 68end ); 69 70# implies 71# InstallTrueMethod( HasTwosidedInverses, IsPowerAssociative and IsLoop ); 72 73############################################################################# 74## 75#P IsDiassociative( Q ) 76## 77## Returns true if <Q> is a diassociative quasigroup. 78 79InstallOtherMethod( IsDiassociative, "for quasigroup", 80 [ IsQuasigroup ], 81function( Q ) 82 local checked, all_pairs, x, S; 83 checked := []; 84 all_pairs := Combinations( PosInParent( Elements( Q ) ), 2 ); # it is faster to work with integers 85 repeat 86 x := Difference( all_pairs, checked ); 87 if IsEmpty( x ) then 88 return true; 89 fi; 90 S := Subquasigroup( Q, x[1] ); 91 if not IsAssociative( S ) then 92 return false; 93 fi; 94 checked := Union( checked, Combinations( PosInParent( Elements( S ) ), 2 ) ); 95 until 0=1; 96end ); 97 98# implies 99# InstallTrueMethod( IsPowerAlternative, IsDiassociative ); 100# InstallTrueMethod( IsFlexible, IsDiassociative ); 101 102############################################################################# 103## INVERSE PROPERTIES 104## ------------------------------------------------------------------------- 105 106############################################################################# 107## 108#P HasLeftInverseProperty( L ) 109## 110## Returns true if <L> has the left inverse property. 111 112InstallMethod( HasLeftInverseProperty, "for loop", 113 [ IsLoop ], 114function( L ) 115 return ForAll( LeftSection( L ), a -> a^-1 in LeftSection( L ) ); 116end ); 117 118############################################################################# 119## 120#P HasRightInverseProperty( L ) 121## 122## Returns true if <L> has the right inverse property. 123 124InstallMethod( HasRightInverseProperty, "for loop", 125 [ IsLoop ], 126function( L ) 127 return ForAll( RightSection( L ), a -> a^-1 in RightSection( L ) ); 128end ); 129 130############################################################################# 131## 132#P HasInverseProperty( L ) 133## 134## Returns true if <L> has the inverse property. 135 136InstallMethod( HasInverseProperty, "for loop", 137 [ IsLoop ], 138function( L ) 139 return HasLeftInverseProperty( L ) and HasRightInverseProperty( L ); 140end ); 141 142############################################################################# 143## 144#P HasWeakInverseProperty( L ) 145## 146## Returns true if <L> has the weak inverse property. 147 148InstallMethod( HasWeakInverseProperty, "for loop", 149 [ IsLoop ], 150function( L ) 151 return ForAll( L, x -> ForAll( L, y -> LeftInverse(x*y)*x=LeftInverse(y) )); 152end ); 153 154############################################################################# 155## 156#P HasTwosidedInverses( L ) 157## 158## Returns true if <L> has two-sided inverses. 159 160InstallMethod( HasTwosidedInverses, "for loop", 161 [ IsLoop ], 162function( L ) 163 return ForAll( L, x -> LeftInverse( x ) = RightInverse( x ) ); 164end ); 165 166############################################################################# 167## 168#P HasAutomorphicInverseProperty( L ) 169## 170## Returns true if <L> has the automorphic inverse property. 171 172InstallMethod( HasAutomorphicInverseProperty, "for loop", 173 [ IsLoop ], 174function( L ) 175 return ForAll( L, x -> ForAll( L, y -> 176 LeftInverse( x*y ) = LeftInverse( x )*LeftInverse( y ) ) ); 177end ); 178 179############################################################################# 180## 181#P HasAntiautomorphicInverseProperty( L ) 182## 183## Returns true if <L> has the antiautomorphic inverse property. 184 185InstallMethod( HasAntiautomorphicInverseProperty, "for loop", 186 [ IsLoop ], 187function( L ) 188 return ForAll( L, x -> ForAll( L, y -> 189 LeftInverse( x*y ) = LeftInverse( y )*LeftInverse( x ) ) ); 190end ); 191 192# implies and is implied by (for inverse properties) 193# InstallTrueMethod( HasAntiautomorphicInverseProperty, HasAutomorphicInverseProperty and IsCommutative ); 194# InstallTrueMethod( HasAutomorphicInverseProperty, HasAntiautomorphicInverseProperty and IsCommutative ); 195# InstallTrueMethod( HasLeftInverseProperty, HasInverseProperty ); 196# InstallTrueMethod( HasRightInverseProperty, HasInverseProperty ); 197# InstallTrueMethod( HasWeakInverseProperty, HasInverseProperty ); 198# InstallTrueMethod( HasAntiautomorphicInverseProperty, HasInverseProperty ); 199# InstallTrueMethod( HasTwosidedInverses, HasAntiautomorphicInverseProperty ); 200# InstallTrueMethod( HasInverseProperty, HasLeftInverseProperty and IsCommutative ); 201# InstallTrueMethod( HasInverseProperty, HasRightInverseProperty and IsCommutative ); 202# InstallTrueMethod( HasInverseProperty, HasLeftInverseProperty and HasRightInverseProperty ); 203# InstallTrueMethod( HasInverseProperty, HasLeftInverseProperty and HasWeakInverseProperty ); 204# InstallTrueMethod( HasInverseProperty, HasRightInverseProperty and HasWeakInverseProperty ); 205# InstallTrueMethod( HasInverseProperty, HasLeftInverseProperty and HasAntiautomorphicInverseProperty ); 206# InstallTrueMethod( HasInverseProperty, HasRightInverseProperty and HasAntiautomorphicInverseProperty ); 207# InstallTrueMethod( HasInverseProperty, HasWeakInverseProperty and HasAntiautomorphicInverseProperty ); 208# InstallTrueMethod( HasTwosidedInverses, HasLeftInverseProperty ); 209# InstallTrueMethod( HasTwosidedInverses, HasRightInverseProperty ); 210# InstallTrueMethod( HasTwosidedInverses, IsFlexible and IsLoop ); 211 212 213############################################################################# 214## PROPERTIES OF QUASIGROUPS 215## ------------------------------------------------------------------------- 216 217############################################################################# 218## 219#P IsSemisymmetric( Q ) 220## 221## Returns true if the quasigroup <Q> is semisymmetric, i.e., (xy)x=y. 222 223InstallMethod( IsSemisymmetric, "for quasigroup", 224 [ IsQuasigroup ], 225function( Q ) 226 return ForAll( Q, x -> 227 LeftTranslation( Q, x ) * RightTranslation( Q, x ) = () ); 228end ); 229 230############################################################################# 231## 232#P IsTotallySymmetric( Q ) 233## 234## Returns true if the quasigroup <Q> is totally symmetric, i.e, 235## commutative and semisymmetric. 236 237InstallMethod( IsTotallySymmetric, "for quasigroup", 238 [ IsQuasigroup ], 239function( Q ) 240 return IsCommutative( Q ) and IsSemisymmetric( Q ); 241end ); 242 243############################################################################# 244## 245#P IsIdempotent( Q ) 246## 247## Returns true if the quasigroup <Q> is idempotent, i.e., x*x=x. 248 249InstallMethod( IsIdempotent, "for quasigroup", 250 [ IsQuasigroup ], 251function( Q ) 252 return ForAll( Q, x -> x*x = x ); 253end ); 254 255############################################################################# 256## 257#P IsSteinerQuasigroup( Q ) 258## 259## Returns true if the quasigroup <Q> is a Steiner quasigroup, i.e., 260## idempotent and totally symmetric. 261 262InstallMethod( IsSteinerQuasigroup, "for quasigroup", 263 [ IsQuasigroup ], 264function( Q ) 265 return IsIdempotent( Q ) and IsTotallySymmetric( Q ); 266end ); 267 268############################################################################# 269## 270#P IsUnipotent( Q ) 271## 272## Returns true if the quasigroup <Q> is unipotent, i.e., x*x=y*y. 273 274InstallMethod( IsUnipotent, "for quasigroup", 275 [ IsQuasigroup ], 276function( Q ) 277 local square; 278 if IsLoop( Q ) then return IsIdempotent( Q ); fi; 279 square := Elements( Q )[ 1 ]^2; 280 return ForAll( Q, y -> y^2 = square ); 281end ); 282 283############################################################################# 284## 285#P IsLDistributive( Q ) 286## 287## Returns true if the quasigroup <Q> is left distributive. 288 289InstallOtherMethod( IsLDistributive, "for Quasigroup", 290 [ IsQuasigroup ], 291function( Q ) 292 # BETTER ALGORITHM LATER? 293 local x, y, z; 294 for x in Q do for y in Q do for z in Q do 295 if not x*(y*z) = (x*y)*(x*z) then return false; fi; 296 od; od; od; 297 return true; 298end ); 299 300############################################################################# 301## 302#P IsRDistributive( Q ) 303## 304## Returns true if the quasigroup <Q> is right distributive. 305 306InstallOtherMethod( IsRDistributive, "for Quasigroup", 307 [ IsQuasigroup ], 308function( Q ) 309 # BETTER ALGORITHM LATER? 310 local x, y, z; 311 for x in Q do for y in Q do for z in Q do 312 if not (x*y)*z = (x*z)*(y*z) then return false; fi; 313 od; od; od; 314 return true; 315end ); 316 317############################################################################# 318## 319#P IsEntropic( Q ) 320## 321## Returns true if the quasigroup <Q> is entropic. 322 323InstallMethod( IsEntropic, "for quasigroup", 324 [ IsQuasigroup ], 325function( Q ) 326 # BETTER ALGORITHM LATER? 327 local x, y, z, w; 328 for x in Q do for y in Q do for z in Q do for w in Q do 329 if not (x*y)*(z*w) = (x*z)*(y*w) then return false; fi; 330 od; od; od; od; 331 return true; 332end ); 333 334############################################################################# 335## LOOPS OF BOL-MOUFANG 336## ------------------------------------------------------------------------- 337 338############################################################################# 339## 340#P IsExtraLoop( L ) 341## 342## Returns true if <L> is an extra loop. 343 344InstallMethod( IsExtraLoop, "for loop", 345 [ IsLoop ], 346function( L ) 347 return IsMoufangLoop( L ) and IsNuclearSquareLoop( L ); 348end ); 349 350# implies 351# InstallTrueMethod( IsMoufangLoop, IsExtraLoop ); 352# InstallTrueMethod( IsCLoop, IsExtraLoop ); 353 354# is implied by 355# InstallTrueMethod( IsExtraLoop, IsMoufangLoop and IsLeftNuclearSquareLoop ); 356# InstallTrueMethod( IsExtraLoop, IsMoufangLoop and IsMiddleNuclearSquareLoop ); 357# InstallTrueMethod( IsExtraLoop, IsMoufangLoop and IsRightNuclearSquareLoop ); 358 359############################################################################# 360## 361#P IsMoufangLoop( L ) 362## 363## Returns true if <L> is a Moufang loop. 364 365InstallMethod( IsMoufangLoop, "for loop", 366 [ IsLoop ], 367function( L ) 368 return IsLeftBolLoop( L ) and HasRightInverseProperty( L ); 369end ); 370 371# implies 372# InstallTrueMethod( IsLeftBolLoop, IsMoufangLoop ); 373# InstallTrueMethod( IsRightBolLoop, IsMoufangLoop ); 374# InstallTrueMethod( IsDiassociative, IsMoufangLoop ); 375 376# is implied by 377# InstallTrueMethod( IsMoufangLoop, IsLeftBolLoop and IsRightBolLoop ); 378 379############################################################################# 380## 381#P IsCLoop( L ) 382## 383## Returns true if <L> is a C-loop. 384 385InstallMethod( IsCLoop, "for loop", 386 [ IsLoop ], 387function( L ) 388 return IsLCLoop( L ) and IsRCLoop( L ); 389end ); 390 391# implies 392# InstallTrueMethod( IsLCLoop, IsCLoop ); 393# InstallTrueMethod( IsRCLoop, IsCLoop ); 394# InstallTrueMethod( IsDiassociative, IsCLoop and IsFlexible); 395 396# is implied by 397# InstallTrueMethod( IsCLoop, IsLCLoop and IsRCLoop ); 398 399############################################################################# 400## 401#P IsLeftBolLoop( L ) 402## 403## Returns true if <L> is a left Bol loop. 404 405InstallMethod( IsLeftBolLoop, "for loop", 406 [ IsLoop ], 407function( L ) 408 return ForAll( LeftSection( L ), a -> 409 ForAll( LeftSection( L ), b -> a*b*a in LeftSection( L ) ) ); 410end ); 411 412# implies 413# InstallTrueMethod( IsRightBolLoop, IsLeftBolLoop and IsCommutative ); 414# InstallTrueMethod( IsLeftPowerAlternative, IsLeftBolLoop ); 415 416############################################################################# 417## 418#P IsRightBolLoop( L ) 419## 420## Returns true if <L> is a right Bol loop. 421 422InstallMethod( IsRightBolLoop, "for loop", 423 [ IsLoop ], 424function( L ) 425 return ForAll( RightSection( L ), a -> 426 ForAll( RightSection( L ), b -> a*b*a in RightSection( L ) ) ); 427end ); 428 429# implies 430# InstallTrueMethod( IsLeftBolLoop, IsRightBolLoop and IsCommutative ); 431# InstallTrueMethod( IsRightPowerAlternative, IsRightBolLoop ); 432 433############################################################################# 434## 435#P IsLCLoop( L ) 436## 437## Returns true if <L> is an LC-loop. 438 439InstallMethod( IsLCLoop, "for loop", 440 [ IsLoop ], 441function( L ) 442 return ForAll( LeftSection( L ), a -> 443 ForAll( RightSection( L ), b -> b^(-1)*a*a*b in LeftSection( L ) ) ); 444end ); 445 446# implies 447# InstallTrueMethod( IsLeftPowerAlternative, IsLCLoop ); 448# InstallTrueMethod( IsLeftNuclearSquareLoop, IsLCLoop ); 449# InstallTrueMethod( IsMiddleNuclearSquareLoop, IsLCLoop ); 450# InstallTrueMethod( IsRCLoop, IsLCLoop and IsCommutative ); 451 452############################################################################# 453## 454#P IsRCLoop( L ) 455## 456## Returns true if <L> is an RC-loop. 457 458InstallMethod( IsRCLoop, "for loop", 459 [ IsLoop ], 460function( L ) 461 return ForAll( LeftSection( L ), a -> 462 ForAll( RightSection( L ), b -> a^(-1)*b*b*a in RightSection( L ) ) ); 463end ); 464 465# implies 466# InstallTrueMethod( IsRightPowerAlternative, IsRCLoop ); 467# InstallTrueMethod( IsRightNuclearSquareLoop, IsRCLoop ); 468# InstallTrueMethod( IsMiddleNuclearSquareLoop, IsRCLoop ); 469# InstallTrueMethod( IsLCLoop, IsRCLoop and IsCommutative ); 470 471############################################################################# 472## 473#P IsLeftNuclearSquareLoop( L ) 474## 475## Returns true if <L> is a left nuclear square loop. 476 477InstallMethod( IsLeftNuclearSquareLoop, "for loop", 478 [ IsLoop ], 479function( L ) 480 return ForAll( L, x -> x^2 in LeftNucleus( L ) ); 481end ); 482 483#implies 484# InstallTrueMethod( IsRightNuclearSquareLoop, IsLeftNuclearSquareLoop and IsCommutative ); 485 486############################################################################# 487## 488#P IsMiddleNuclearSquareLoop( L ) 489## 490## Returns true if <L> is a middle nuclear square loop. 491 492InstallMethod( IsMiddleNuclearSquareLoop, "for loop", 493 [ IsLoop ], 494function( L ) 495 return ForAll( L, x -> x^2 in MiddleNucleus( L ) ); 496end ); 497 498############################################################################# 499## 500#P IsRightNuclearSquareLoop( L ) 501## 502## Returns true if <L> is a right nuclear square loop. 503 504InstallMethod( IsRightNuclearSquareLoop, "for loop", 505 [ IsLoop ], 506function( L ) 507 return ForAll( L, x -> x^2 in RightNucleus( L ) ); 508end ); 509 510# implies 511# InstallTrueMethod( IsLeftNuclearSquareLoop, IsRightNuclearSquareLoop and IsCommutative ); 512 513############################################################################# 514## 515#P IsNuclearSquareLoop( L ) 516## 517## Returns true if <L> is a nuclear square loop. 518 519InstallMethod( IsNuclearSquareLoop, "for loop", 520 [ IsLoop ], 521function( L ) 522 return IsLeftNuclearSquareLoop( L ) and IsRightNuclearSquareLoop( L ) 523 and IsMiddleNuclearSquareLoop( L ); 524end ); 525 526# implies 527# InstallTrueMethod( IsLeftNuclearSquareLoop, IsNuclearSquareLoop ); 528# InstallTrueMethod( IsRightNuclearSquareLoop, IsNuclearSquareLoop ); 529# InstallTrueMethod( IsMiddleNuclearSquareLoop, IsNuclearSquareLoop ); 530 531# is implied by 532# InstallTrueMethod( IsNuclearSquareLoop, IsLeftNuclearSquareLoop 533# and IsRightNuclearSquareLoop and IsMiddleNuclearSquareLoop ); 534 535############################################################################# 536## 537#P IsFlexible( Q ) 538## 539## Returns true if <Q> is a flexible quasigroup. 540 541InstallMethod( IsFlexible, "for quasigroup", 542 [ IsQuasigroup ], 543function( Q ) 544 local LS, RS; 545 LS := LeftSection( Q ); 546 RS := RightSection( Q ); 547 return ForAll( [1..Size( Q )], i -> LS[ i ] * RS[ i ] = RS[ i ] * LS[ i ] ); 548end ); 549 550# is implied by 551# InstallTrueMethod( IsFlexible, IsCommutative ); 552 553############################################################################# 554## 555#P IsLeftAlternative( Q ) 556## 557## Returns true if <Q> is a left alternative quasigroup. 558 559InstallMethod( IsLeftAlternative, "for quasigroup", 560 [ IsQuasigroup], 561function( Q ) 562 if IsLoop( Q ) then 563 return ForAll( LeftSection( Q ), a -> a*a in LeftSection( Q ) ); 564 fi; 565 return ForAll( Q, x -> ForAll( Q, y -> x*(x*y) = (x*x)*y ) ); 566end ); 567 568# implies 569# InstallTrueMethod( IsRightAlternative, IsLeftAlternative and IsCommutative ); 570 571############################################################################# 572## 573#P IsRightAlternative( Q ) 574## 575## Returns true if <Q> is a right alternative quasigroup. 576 577InstallMethod( IsRightAlternative, "for quasigroup", 578 [ IsQuasigroup ], 579function( Q ) 580 if IsLoop( Q ) then 581 return ForAll( RightSection( Q ), a -> a*a in RightSection( Q ) ); 582 fi; 583 return ForAll( Q, x -> ForAll( Q, y -> (x*y)*y = x*(y*y) ) ); 584end ); 585 586# implies 587# InstallTrueMethod( IsLeftAlternative, IsRightAlternative and IsCommutative ); 588 589############################################################################# 590## 591#P IsAlternative( Q ) 592## 593## Returns true if <Q> is an alternative quasigroup. 594 595InstallMethod( IsAlternative, "for quasigroup", 596 [ IsQuasigroup ], 597function( Q ) 598 return IsLeftAlternative( Q ) and IsRightAlternative( Q ); 599end ); 600 601# implies 602# InstallTrueMethod( IsLeftAlternative, IsAlternative ); 603# InstallTrueMethod( IsRightAlternative, IsAlternative ); 604 605# is implied by 606# InstallTrueMethod( IsAlternative, IsLeftAlternative and IsRightAlternative ); 607 608############################################################################# 609## POWER ALTERNATIVE LOOPS 610## ------------------------------------------------------------------------- 611 612############################################################################# 613## 614#P IsLeftPowerAlternative( L ) 615## 616## Returns true if <L> is a left power alternative loop. 617 618InstallMethod( IsLeftPowerAlternative, "for loop", 619 [ IsLoop ], 620function( L ) 621 local i, M; 622 if Size( L ) = 1 then return true; fi; 623 for i in [ 2..Size( L )] do 624 M := Subloop( L, [ Elements( L )[ i ] ]); 625 if not Size( RelativeLeftMultiplicationGroup( L, M ) ) = Size( M ) then 626 return false; 627 fi; 628 od; 629 return true; 630end ); 631 632# implies 633# InstallTrueMethod( IsLeftAlternative, IsLeftPowerAlternative ); 634# InstallTrueMethod( HasLeftInverseProperty, IsLeftPowerAlternative ); 635# InstallTrueMethod( IsPowerAssociative, IsLeftPowerAlternative ); 636 637############################################################################# 638## 639#P IsRightPowerAlternative( L ) 640## 641## Returns true if <L> is a right power alternative loop. 642 643InstallMethod( IsRightPowerAlternative, "for loop", 644 [ IsLoop ], 645function( L ) 646 local i, M; 647 if Size( L ) = 1 then return true; fi; 648 for i in [ 2..Size( L ) ] do 649 M := Subloop( L, [ Elements( L )[ i ] ] ); 650 if not Size( RelativeRightMultiplicationGroup( L, M ) ) = Size( M ) then 651 return false; 652 fi; 653 od; 654 return true; 655end ); 656 657# implies 658# InstallTrueMethod( IsRightAlternative, IsRightPowerAlternative ); 659# InstallTrueMethod( HasRightInverseProperty, IsRightPowerAlternative ); 660# InstallTrueMethod( IsPowerAssociative, IsRightPowerAlternative ); 661 662############################################################################# 663## 664#P IsPowerAlternative( L ) 665## 666## Returns true if <L> is a power alternative loop. 667 668InstallMethod( IsPowerAlternative, "for loop", 669 [ IsLoop ], 670function( L ) 671 return ( IsLeftPowerAlternative( L ) and IsRightPowerAlternative( L ) ); 672end ); 673 674# implies 675# InstallTrueMethod( IsLeftPowerAlternative, IsPowerAlternative ); 676# InstallTrueMethod( IsRightPowerAlternative, IsPowerAlternative ); 677 678############################################################################# 679## CC-LOOPS AND RELATED PROPERTIES 680## ------------------------------------------------------------------------- 681 682############################################################################# 683## 684#P IsLCCLoop( L ) 685## 686## Returns true if <L> is a left conjugacy closed loop. 687 688InstallMethod( IsLCCLoop, "for loop", 689 [ IsLoop ], 690function( L ) 691 return ForAll( LeftSection( L ), a -> 692 ForAll( LeftSection( L ), b -> b*a*b^(-1) in LeftSection( L ) ) ); 693end ); 694 695# implies 696# InstallTrueMethod( IsAssociative, IsLCCLoop and IsCommutative ); 697# InstallTrueMethod( IsExtraLoop, IsLCCLoop and IsMoufangLoop ); 698 699############################################################################# 700## 701#P IsRCCLoop( L ) 702## 703## Returns true if <L> is a right conjugacy closed loop. 704 705InstallMethod( IsRCCLoop, "for loop", 706 [ IsLoop ], 707function( L ) 708 return ForAll( RightSection( L ), a -> 709 ForAll( RightSection( L ), b -> b*a*b^(-1) in RightSection( L ) ) ); 710end ); 711 712# implies 713# InstallTrueMethod( IsAssociative, IsRCCLoop and IsCommutative ); 714# InstallTrueMethod( IsExtraLoop, IsRCCLoop and IsMoufangLoop ); 715 716############################################################################# 717## 718#P IsCCLoop( L ) 719## 720## Returns true if <L> is a conjugacy closed loop. 721 722InstallMethod( IsCCLoop, "for loop", 723 [ IsLoop ], 724function( L ) 725 return IsLCCLoop( L ) and IsRCCLoop( L ); 726end ); 727 728# implies 729# InstallTrueMethod( IsLCCLoop, IsCCLoop ); 730# InstallTrueMethod( IsRCCLoop, IsCCLoop ); 731 732# is implied by 733# InstallTrueMethod( IsCCLoop, IsLCCLoop and IsRCCLoop ); 734 735############################################################################# 736## 737#P IsOsbornLoop( L ) 738## 739## Returns true if <L> is an Osborn loop. 740 741InstallMethod( IsOsbornLoop, "for loop", 742 [ IsLoop ], 743function( L ) 744 # MIGHT REDO LATER 745 return ForAll(L, x-> ForAll(L, y-> 746 ForAll(L, z-> x*((y*z)*x) = LeftDivision(LeftInverse(x),y)*(z*x)) 747 )); 748end ); 749 750# is implied by 751# InstallTrueMethod( IsOsbornLoop, IsMoufangLoop ); 752# InstallTrueMethod( IsOsbornLoop, IsCCLoop ); 753 754############################################################################# 755## ADDITIONAL VARIETIES OF LOOPS 756## ------------------------------------------------------------------------- 757 758############################################################################# 759## 760#P IsCodeLoop( L ) 761## 762## Returns true if <L> is an even code loop. 763 764InstallMethod( IsCodeLoop, "for loop", 765 [ IsLoop ], 766function( L ) 767 # even code loops are precisely Moufang 2-loops with Frattini subloop of order 1, 2 768 return Set( Factors( Size( L ) ) ) = [ 2 ] 769 and IsMoufangLoop( L ) 770 and Size( FrattiniSubloop( L ) ) in [1, 2]; 771end ); 772 773# implies 774# InstallTrueMethod( IsExtraLoop, IsCodeLoop ); 775# InstallTrueMethod( IsCCLoop, IsCodeLoop ); 776 777############################################################################# 778## 779#P IsSteinerLoop( L ) 780## 781## Returns true if <L> is a Steiner loop. 782 783InstallMethod( IsSteinerLoop, "for loop", 784 [ IsLoop ], 785function( L ) 786 # Steiner loops are inverse property loops of exponent at most 2. 787 return HasInverseProperty( L ) and Exponent( L )<=2; 788end ); 789 790# implies 791# InstallTrueMethod( IsCommutative, IsSteinerLoop ); 792# InstallTrueMethod( IsCLoop, IsSteinerLoop ); 793 794############################################################################# 795## 796#P IsLeftBruckLoop( L ) 797## 798## Returns true if <L> is a left Bruck loop. 799 800InstallMethod( IsLeftBruckLoop, "for loop", 801 [ IsLoop ], 802function( L ) 803 return IsLeftBolLoop( L ) and HasAutomorphicInverseProperty( L ); 804end ); 805 806# implies 807# InstallTrueMethod( HasAutomorphicInverseProperty, IsLeftBruckLoop ); 808# InstallTrueMethod( IsLeftBolLoop, IsLeftBruckLoop ); 809# InstallTrueMethod( IsRightBruckLoop, IsLeftBruckLoop and IsCommutative ); 810 811# is implied by 812# InstallTrueMethod( IsLeftBruckLoop, IsLeftBolLoop and HasAutomorphicInverseProperty ); 813 814############################################################################# 815## 816#P IsRightBruckLoop( L ) 817## 818## Returns true if <L> is a right Bruck loop. 819 820InstallMethod( IsRightBruckLoop, "for loop", 821 [ IsLoop ], 822function( L ) 823 return IsRightBolLoop( L ) and HasAutomorphicInverseProperty( L ); 824end ); 825 826# implies 827# InstallTrueMethod( HasAutomorphicInverseProperty, IsRightBruckLoop ); 828# InstallTrueMethod( IsRightBolLoop, IsRightBruckLoop ); 829# InstallTrueMethod( IsLeftBruckLoop, IsRightBruckLoop and IsCommutative ); 830 831# is implied by 832# InstallTrueMethod( IsRightBruckLoop, IsRightBolLoop and HasAutomorphicInverseProperty ); 833 834############################################################################# 835## 836#P IsLeftALoop( L ) 837## 838## Returns true if <L> is a left A-loop, that is if 839## all left inner mappings are automorphisms of <L>. 840 841InstallMethod( IsLeftALoop, "for loop", 842 [ IsLoop ], 843function( L ) 844 local gens; 845 gens := GeneratorsOfGroup( LeftInnerMappingGroup( L ) ); 846 return ForAll(gens, f -> ForAll(L, x -> ForAll(L, y -> (x * y)^f = x^f * y^f ))); 847end); 848 849############################################################################# 850## 851#P IsRightALoop( L ) 852## 853## Returns true if <L> is a right A-loop, that is if 854## all right inner mappings are automorphisms of <L>. 855 856InstallMethod( IsRightALoop, "for loop", 857 [ IsLoop ], 858function( L ) 859 local gens; 860 gens := GeneratorsOfGroup( RightInnerMappingGroup( L ) ); 861 return ForAll(gens, f -> ForAll(L, x -> ForAll(L, y -> (x * y)^f = x^f * y^f ))); 862end); 863 864############################################################################# 865## 866#P IsMiddleALoop( L ) 867## 868## Returns true if <L> is a middle A-loop, that is if 869## all middle inner mappings (conjugations) are automorphisms of <L>. 870 871InstallMethod( IsMiddleALoop, "for loop", 872 [ IsLoop ], 873function( L ) 874 local gens; 875 gens := GeneratorsOfGroup( MiddleInnerMappingGroup( L ) ); 876 return ForAll(gens, f -> ForAll(L, x -> ForAll(L, y -> (x * y)^f = x^f * y^f ))); 877end); 878 879############################################################################# 880## 881#P IsALoop( L ) 882## 883## Returns true if <L> is an A-loop, that is if 884## all inner mappings are automorphisms of <L>. 885 886InstallMethod( IsALoop, "for loop", 887 [ IsLoop ], 888function( Q ) 889 return IsRightALoop(Q) and IsMiddleALoop(Q); 890 # Theorem: rigth A-loop + middle A-loop implies left A-loop 891end); 892 893# implies 894# InstallTrueMethod( IsLeftALoop, IsALoop ); 895# InstallTrueMethod( IsRightALoop, IsALoop ); 896# InstallTrueMethod( IsMiddleALoop, IsALoop ); 897# InstallTrueMethod( IsLeftALoop, IsRightALoop and HasAntiautomorphicInverseProperty ); 898# InstallTrueMethod( IsRightALoop, IsLeftALoop and HasAntiautomorphicInverseProperty ); 899# InstallTrueMethod( IsFlexible, IsMiddleALoop ); 900# InstallTrueMethod( HasAntiautomorphicInverseProperty, IsFlexible and IsLeftALoop ); 901# InstallTrueMethod( HasAntiautomorphicInverseProperty, IsFlexible and IsRightALoop ); 902# InstallTrueMethod( IsMoufangLoop, IsALoop and IsLeftAlternative ); 903# InstallTrueMethod( IsMoufangLoop, IsALoop and IsRightAlternative ); 904# InstallTrueMethod( IsMoufangLoop, IsALoop and HasLeftInverseProperty ); 905# InstallTrueMethod( IsMoufangLoop, IsALoop and HasRightInverseProperty ); 906# InstallTrueMethod( IsMoufangLoop, IsALoop and HasWeakInverseProperty ); 907 908# is implied by 909# InstallTrueMethod( IsMiddleALoop, IsCommutative and IsLoop); 910# InstallTrueMethod( IsLeftALoop, IsLeftBruckLoop ); 911# InstallTrueMethod( IsLeftALoop, IsLCCLoop ); 912# InstallTrueMethod( IsRightALoop, IsRightBruckLoop ); 913# InstallTrueMethod( IsRightALoop, IsRCCLoop ); 914# InstallTrueMethod( IsALoop, IsCommutative and IsMoufangLoop ); 915# InstallTrueMethod( IsALoop, IsLeftALoop and IsMiddleALoop ); 916# InstallTrueMethod( IsALoop, IsRightALoop and IsMiddleALoop ); 917# InstallTrueMethod( IsALoop, IsAssociative and IsLoop); 918