monoid.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /**
  2. * This file is part of Gomu.
  3. *
  4. * Copyright 2016 by Jean Fromentin <jean.fromentin@math.cnrs.fr>
  5. *
  6. * Gomu is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Gomu is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Gomu. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef MONOID_HPP
  20. #define MONOID_HPP
  21. #include <cstdint>
  22. #include "../../array.hpp"
  23. #include "stacked_list.hpp"
  24. #define MAX_COMPLEMENT_SIZE 64
  25. //***************************
  26. //* Early class definitions *
  27. //***************************
  28. class Reversing;
  29. class LeftReversing;
  30. class RightReversing;
  31. class PresentedMonoid;
  32. class Word;
  33. //************
  34. //* Typedefs *
  35. //************
  36. //! Monoid generator
  37. typedef int16_t Generator;
  38. //! Complement function of a monoid
  39. typedef int(*SetComplement)(const Generator& x,const Generator& y,Generator* comp);
  40. //! Display function for monoid generator
  41. typedef string(*DisplayGenerator)(const Generator& x);
  42. //! Return the number of generators of the monoid of rank n among a monoid familly
  43. typedef size_t(*GeneratorsNumber)(size_t n);
  44. //! Return the rank of a Generator
  45. typedef size_t(*GeneratorRank)(const Generator& x);
  46. //! Ranked Generator bijection
  47. typedef Generator(*RankedGeneratorBijection)(size_t r,const Generator& x,int p);
  48. //! Return a ranked word
  49. typedef Word(*RankedWordFactory)(size_t r);
  50. //*********************
  51. //* Class definitions *
  52. //*********************
  53. //-----------
  54. // Reversing
  55. //-----------
  56. //! Common data and function between left and right reversing algorithms
  57. class Reversing{
  58. public:
  59. //! Internal word
  60. StackedList word;
  61. //! Next detected position to reverse
  62. deque<NInd> to_reverse;
  63. //! Destination structure for complement
  64. Generator comp[MAX_COMPLEMENT_SIZE];
  65. //! Complement function
  66. SetComplement set_comp;
  67. //! Clear internal word
  68. void clear();
  69. //! Display internal word
  70. void disp_word() const;
  71. //! Return internal word
  72. Word get_word() const;
  73. //! Init internal word to be of size s
  74. void init_word(size_t s);
  75. //! Number of detected position to reverse. O implies the word is reversed
  76. size_t remaining_size() const;
  77. //! Set internal word
  78. void set_word(const Word& w);
  79. };
  80. //----------------
  81. // Left reversing
  82. //----------------
  83. //! A class for left reversing algorithm
  84. class LeftReversing:public Reversing{
  85. public:
  86. //! Unique constructor
  87. LeftReversing(SetComplement sc);
  88. //! Test if full reversing gives a positive word when internal word is u.v^(-1)
  89. bool check_positivity();
  90. //! Return numerator of the word
  91. Word denominator();
  92. //! Reverse untill the is no more reversing step
  93. void full_reverse();
  94. //! Return numerator of the word
  95. Word numerator();
  96. //! Perform one reversing step
  97. void reverse();
  98. //! Set internal word to be w
  99. void set_word(const Word& w);
  100. //! Set internal word to be num.den^(-1)
  101. void set_word(const Word& num,const Word& den);
  102. };
  103. //-----------------
  104. // Right reversing
  105. //-----------------
  106. //! A class for right reversing
  107. class RightReversing:public Reversing{
  108. public:
  109. //! Unique constructor
  110. RightReversing(SetComplement sc);
  111. //! Test if full reversing gives a positive word when internal word is u^(-1).v
  112. bool check_positivity();
  113. //! Return numerator of the word
  114. Word denominator();
  115. //! Reverse untill the is no more reversing ste
  116. void full_reverse();
  117. //! Return numerator of the word
  118. Word numerator();
  119. //! Perform one reversing
  120. void reverse();
  121. //! Set internal word
  122. void set_word(const Word& w);
  123. //! Set internal word to be den^(-1).num
  124. void set_word(const Word& den,const Word& num);
  125. };
  126. //-------------
  127. // MonoidTrait
  128. //-------------
  129. //! Class for procedure attached to monoid
  130. class MonoidTrait{
  131. public:
  132. //! Pointer to a LeftReversing
  133. LeftReversing* left_reversing;
  134. //! Pointer to a RightReversing
  135. RightReversing* right_reversing;
  136. //! Extra data
  137. void* data;
  138. //! Empty constructor
  139. MonoidTrait();
  140. //! Destructor
  141. ~MonoidTrait();
  142. //! Test if two words are equivalent
  143. bool are_equivalent(const Word& u,const Word& v);
  144. //! Test if the family has a left complement
  145. bool has_left_complement() const;
  146. //! Test if the family has a right complement
  147. bool has_right_complement() const;
  148. //! Test if a is left divisible by b, i.e.,if it exists c such that a=b.c */
  149. bool is_left_divisible(const Word& a,const Word& b);
  150. //! Return a Couple (f,c) such that f equals true if a is left divisible by b,
  151. //! i.e.,if it exists c such that a=b.c
  152. pair <bool,Word> is_left_divisible_x(const Word& a,const Word& b);
  153. //! Test if a is right divisible by b, i.e.,if it exists c such that a=c.b
  154. bool is_right_divisible(const Word& a,const Word& b);
  155. //! Return a Couple (f,c) such that f equals true if a is right divisible by b,
  156. //! i.e.,if it exists c such that a=c.b
  157. pair<bool,Word> is_right_divisible_x(const Word& a,const Word& b);
  158. //! Return left complement of x and y
  159. Word left_complement(const Generator& x,const Generator& y);
  160. //! Return the left denominator
  161. Word left_denominator();
  162. //! Return the left gcd of a and b, i.e., a maximal element c
  163. //! such that there exist x with a=c.x and y with b=c.y
  164. Word left_gcd(const Word& a,const Word& b);
  165. //! Return a Couple (c,d) where c is the left gcd of a and d is such that a=c.d
  166. pair<Word,Word> left_gcd_x(const Word& a,const Word& b);
  167. //! Return the left lcm of a and b, i.e., a minimal element c
  168. //! such that there exist x with c=x.a and y with c=y.a
  169. Word left_lcm(const Word& a,const Word& b);
  170. //! Return the left lcm complement of a and b, i.e.,
  171. //! an element d such that d.a is equal to the left lcm of a and b
  172. Word left_lcm_complement(const Word& a,const Word& b);
  173. //! Return the left numerator
  174. Word left_numerator();
  175. //! Left reverse the word w
  176. Word left_reverse(const Word& w);
  177. //! Left reverse the u.v^(-1)
  178. Word left_reverse(const Word& u,const Word& v);
  179. //! Return right complement of x and y
  180. Word right_complement(const Generator& x,const Generator& y);
  181. //! Return the right denominator
  182. Word right_denominator();
  183. //! Return the left gcd of a and b, i.e., a maximal element c
  184. //! such that there exist x with a=c.x and y with b=c.y
  185. Word right_gcd(const Word& a,const Word& b);
  186. //! Return a Couple (c,d) where c is the right gcd of a and d is such that a=d.c
  187. pair<Word,Word> right_gcd_x(const Word& a,const Word& b);
  188. //! Return the right lcm of a and b, i.e., a minimal element c
  189. //! such that there exist x with c=a.x and y with c=a.y
  190. Word right_lcm(const Word& a,const Word& b);
  191. //! Return the right lcm complement of a and b, i.e.,
  192. //! an element d such that a.d is equal to the right lcm of a and b
  193. Word right_lcm_complement(const Word& a,const Word& b);
  194. //! Return right numerator
  195. Word right_numerator();
  196. //! Right reverse the word w
  197. Word right_reverse(const Word& w);
  198. //! Right reverse the u^(-1).v
  199. Word right_reverse(const Word& u,const Word& v);
  200. //! Set left complement
  201. void set_left_complement(SetComplement sc);
  202. //! Set right complement
  203. void set_right_complement(SetComplement sc);
  204. };
  205. //--------------
  206. // MonoidFamily
  207. //--------------
  208. //! A class for familly of monoid
  209. class MonoidFamily:public MonoidTrait{
  210. public:
  211. //! Function to display generators
  212. DisplayGenerator gdisp;
  213. //! Function returning the number of generators for a given rank
  214. GeneratorsNumber gnum;
  215. //! Return rank of a generator
  216. GeneratorRank grank;
  217. //! Label of the monoid family
  218. string label;
  219. //! Ranked Garside automorphism germ
  220. RankedGeneratorBijection ranked_phi_germ;
  221. //! Ranked Garside element factory
  222. RankedWordFactory ranked_garside_word_factory;
  223. //! Unique constructor
  224. MonoidFamily(string l,DisplayGenerator d,GeneratorsNumber n,GeneratorRank r);
  225. //! Destructor
  226. ~MonoidFamily();
  227. //! Apply phi_r^p to the word
  228. void apply_phi(size_t r,Word& w,int p=1);
  229. //! Display
  230. string display() const;
  231. //! Return garside_element of rank r
  232. Word garside_element(size_t r);
  233. //! Return number of generators for rank n
  234. size_t generators_number(size_t n);
  235. //! Test if the family has a Garside automorphism
  236. bool has_garside_automorphism() const;
  237. //! Test if the family has a Garside element
  238. bool has_garside_element() const;
  239. //! Return the word obtained under phi_r^p
  240. Word phi(size_t r,const Word& w,int p=1);
  241. //! Return phi-normal form of an element
  242. Word phi_normal(const Word& w);
  243. //! Return phi-normal form of an element of rank r
  244. Word phi_normal(size_t r,const Word& w);
  245. //! Return ranked phi-tail of an element
  246. Word phi_tail(size_t r,const Word& w);
  247. //! Return ranked phi-tail of an element together with remainder
  248. pair<Word,Word> phi_tail_x(size_t r,const Word& w);
  249. //! Return the ranked phi-splitting of an element
  250. Array<Word> phi_splitting(size_t r,const Word& w);
  251. //! Return rank of a Word
  252. size_t rank(const Word& w);
  253. //! Set ranked phi germ
  254. void set_ranked_phi_germ(RankedGeneratorBijection rpg);
  255. //! Set ranked garside word factory
  256. void set_ranked_garside_word_factory(RankedWordFactory rgwf);
  257. };
  258. //------
  259. // Word
  260. //------
  261. //! Class for word
  262. class Word:public Array<Generator>{
  263. public:
  264. //! Empty constructor
  265. Word();
  266. //! Construct a word from a list of Generator
  267. Word(const initializer_list<Generator>& l);
  268. //! Recopy constructor
  269. Word(const Word&);
  270. //! Move constructor
  271. Word(Word&&);
  272. //! Construct a word from an array
  273. Word(const Array<Generator>&);
  274. Word(Array<Generator>&&);
  275. //! Assignement operator with copy
  276. Word& operator=(const Word& w);
  277. //! Assignement operator with move
  278. Word& operator=(Word&& w);
  279. //! Concatenate a word to this one
  280. Word concatenate(const Word& w) const;
  281. //! Return the word inverse of this one
  282. Word inverse() const;
  283. //! Display a word
  284. string display(DisplayGenerator d) const;
  285. };
  286. //***********************
  287. //* Auxiliary functions *
  288. //***********************
  289. //! Comparison function for Generator
  290. //! \param x a generator
  291. //! \param y a generator
  292. //! \return -1 if x<y, 0 if x==y and 1 if x>y
  293. int cmp(const Generator& x,const Generator& y);
  294. //! Display a generator with letter
  295. string disp_alpha(const Generator& x);
  296. //! Multiply word
  297. //! \param u a word
  298. //! \param w a word
  299. //! \return the word uv
  300. Word operator*(const Word& u,const Word& v);
  301. //***********************
  302. //* Inline declarations *
  303. //***********************
  304. //-----------
  305. // Reversing
  306. //-----------
  307. inline void
  308. Reversing::clear(){
  309. to_reverse.clear();
  310. }
  311. inline void
  312. Reversing::disp_word() const{
  313. cout<<word<<endl;
  314. }
  315. inline void
  316. Reversing::init_word(size_t s){
  317. word.init(s);
  318. }
  319. inline size_t
  320. Reversing::remaining_size() const{
  321. return to_reverse.size();
  322. }
  323. inline void
  324. Reversing::set_word(const Word& w){
  325. word.init((NData*)w.array,w.size());
  326. }
  327. //----------------
  328. // Left reversing
  329. //----------------
  330. inline
  331. LeftReversing::LeftReversing(SetComplement sc){
  332. set_comp=sc;
  333. }
  334. inline void
  335. LeftReversing::full_reverse(){
  336. while(not to_reverse.empty())
  337. reverse();
  338. }
  339. //-----------------
  340. // Right reversing
  341. //-----------------
  342. inline
  343. RightReversing::RightReversing(SetComplement sc){
  344. set_comp=sc;
  345. }
  346. inline void
  347. RightReversing::full_reverse(){
  348. while(not to_reverse.empty()) reverse();
  349. }
  350. //--------------
  351. // MonoidFamily
  352. //--------------
  353. inline
  354. MonoidFamily::~MonoidFamily(){
  355. }
  356. inline string
  357. MonoidFamily::display() const{
  358. return label+" monoid family";
  359. }
  360. inline Word
  361. MonoidFamily::garside_element(size_t r){
  362. return ranked_garside_word_factory(r);
  363. }
  364. inline size_t
  365. MonoidFamily::generators_number(size_t n){
  366. return gnum(n);
  367. }
  368. inline bool
  369. MonoidFamily::has_garside_element() const{
  370. return ranked_garside_word_factory!=nullptr;
  371. }
  372. inline bool
  373. MonoidFamily::has_garside_automorphism() const{
  374. return ranked_phi_germ!=nullptr;
  375. }
  376. inline Word
  377. MonoidFamily::phi_normal(const Word& w){
  378. return phi_normal(rank(w),w);
  379. }
  380. inline void
  381. MonoidFamily::set_ranked_phi_germ(RankedGeneratorBijection rpg){
  382. ranked_phi_germ=rpg;
  383. }
  384. inline void
  385. MonoidFamily::set_ranked_garside_word_factory(RankedWordFactory rgwf){
  386. ranked_garside_word_factory=rgwf;
  387. }
  388. //-------------
  389. // MonoidTrait
  390. //-------------
  391. inline bool
  392. MonoidTrait::has_left_complement() const{
  393. return left_reversing!=nullptr;
  394. }
  395. inline bool
  396. MonoidTrait::has_right_complement() const{
  397. return right_reversing!=nullptr;
  398. }
  399. inline bool
  400. MonoidTrait::is_left_divisible(const Word& a,const Word& b){
  401. right_reversing->set_word(b,a);
  402. return right_reversing->check_positivity();
  403. }
  404. inline bool
  405. MonoidTrait::is_right_divisible(const Word& a,const Word& b){
  406. left_reversing->set_word(a,b);
  407. return left_reversing->check_positivity();
  408. }
  409. inline Word
  410. MonoidTrait::left_denominator(){
  411. return left_reversing->denominator();
  412. }
  413. inline Word
  414. MonoidTrait::left_lcm_complement(const Word& a,const Word& b){
  415. left_reverse(b,a);
  416. return left_numerator();
  417. }
  418. inline Word
  419. MonoidTrait::left_lcm(const Word& a,const Word& b){
  420. return left_lcm_complement(a,b)*a;
  421. }
  422. inline Word
  423. MonoidTrait::left_numerator(){
  424. return left_reversing->numerator();
  425. }
  426. inline Word
  427. MonoidTrait::left_reverse(const Word& w){
  428. left_reversing->set_word(w);
  429. left_reversing->full_reverse();
  430. return left_reversing->get_word();
  431. }
  432. inline Word
  433. MonoidTrait::left_reverse(const Word& u,const Word& v){
  434. left_reversing->set_word(u,v);
  435. left_reversing->full_reverse();
  436. return left_reversing->get_word();
  437. }
  438. inline Word
  439. MonoidTrait::right_denominator(){
  440. return right_reversing->denominator();
  441. }
  442. inline Word
  443. MonoidTrait::right_lcm(const Word& a,const Word& b){
  444. return a*right_lcm_complement(a,b);
  445. }
  446. inline Word
  447. MonoidTrait::right_lcm_complement(const Word& a,const Word& b){
  448. right_reverse(a,b);
  449. return right_numerator();
  450. }
  451. inline Word
  452. MonoidTrait::right_numerator(){
  453. return right_reversing->numerator();
  454. }
  455. inline Word
  456. MonoidTrait::right_reverse(const Word& w){
  457. right_reversing->set_word(w);
  458. right_reversing->full_reverse();
  459. return right_reversing->get_word();
  460. }
  461. inline Word
  462. MonoidTrait::right_reverse(const Word& u,const Word& v){
  463. right_reversing->set_word(u,v);
  464. right_reversing->full_reverse();
  465. return right_reversing->get_word();
  466. }
  467. inline void
  468. MonoidTrait::set_left_complement(SetComplement sc){
  469. left_reversing=new LeftReversing(sc);
  470. }
  471. inline void
  472. MonoidTrait::set_right_complement(SetComplement sc){
  473. right_reversing=new RightReversing(sc);
  474. }
  475. //------
  476. // Word
  477. //------
  478. inline
  479. Word::Word(){}
  480. inline
  481. Word::Word(const Word& w):Array(w){}
  482. inline
  483. Word::Word(Word&& w):Array(w){}
  484. inline
  485. Word::Word(const Array<Generator>& a):Array(a){}
  486. inline
  487. Word::Word(Array<Generator>&& a):Array(a){}
  488. inline Word
  489. Word::concatenate(const Word& w) const{
  490. return Word(append(w));
  491. }
  492. inline Word&
  493. Word::operator=(const Word& w){
  494. Array::operator=(w);
  495. }
  496. inline Word&
  497. Word::operator=(Word&& w){
  498. Array::operator=(w);
  499. }
  500. //***********************
  501. //* Auxiliary functions *
  502. //***********************
  503. inline int
  504. cmp(const Generator& x,const Generator& y){
  505. if(x<y) return -1;
  506. if(x==y) return 0;
  507. return 1;
  508. }
  509. inline string
  510. disp_alpha(const Generator& x){
  511. if(x==0) return "e";
  512. string res="";
  513. if(x>0) return res+char(x-1+'a');
  514. return res+char(-x-1+'A');
  515. }
  516. inline Word
  517. operator*(const Word& u,const Word& v){
  518. return u.append(v);
  519. }
  520. #endif