diff --git a/docs/pictures/to-table.svg b/docs/pictures/to-table.svg
index 332e7fbec..120bdfbe6 100644
--- a/docs/pictures/to-table.svg
+++ b/docs/pictures/to-table.svg
@@ -4,7 +4,7 @@
height="231.103pt"
viewBox="0 0 420.566 231.103"
version="1.1"
- id="svg2168"
+ id="svg726"
sodipodi:docname="to-table.pdf"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
@@ -12,408 +12,408 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
+ id="defs106">
+ id="g65">
+ id="path1" />
+ id="path2" />
+ id="path3" />
+ id="path4" />
+ id="path5" />
+ id="path6" />
+ id="path7" />
+ id="path8" />
+ id="path9" />
+ id="path10" />
+ id="path11" />
+ id="path12" />
+ id="path13" />
+ id="path14" />
+ id="path15" />
+ id="path16" />
+ id="path17" />
+ id="path18" />
+ id="path19" />
+ id="path20" />
+ id="path21" />
+ id="path22" />
+ id="path23" />
+ id="path24" />
+ id="path25" />
+ id="path26" />
+ id="path27" />
+ id="path28" />
+ id="path29" />
+ id="path30" />
+ id="path31" />
+ id="path32" />
+ id="path33" />
+ id="path34" />
+ id="path35" />
+ id="path36" />
+ id="path37" />
+ id="path38" />
+ id="path39" />
+ id="path40" />
+ id="path41" />
+ id="path42" />
+ id="path43" />
+ id="path44" />
+ id="path45" />
+ id="path46" />
+ id="path47" />
+ id="path48" />
+ id="path49" />
+ id="path50" />
+ id="path51" />
+ id="path52" />
+ id="path53" />
+ id="path54" />
+ id="path55" />
+ id="path56" />
+ id="path57" />
+ id="path58" />
+ id="path59" />
+ id="path60" />
+ id="path61" />
+ id="path62" />
+ id="path63" />
+ id="path64" />
+ id="path65" />
+ id="path66" />
+ id="path67" />
+ id="path68" />
+ id="path69" />
+ id="path70" />
+ id="path71" />
+ id="path72" />
+ id="path73" />
+ id="path74" />
+ id="path75" />
+ id="path76" />
+ id="path77" />
+ id="path78" />
+ id="path79" />
+ id="path80" />
+ id="path81" />
+ id="path82" />
+ id="path83" />
+ id="path84" />
+ id="path85" />
+ id="path86" />
+ id="path87" />
+ id="path88" />
+ id="path89" />
+ id="path90" />
+ id="path91" />
+ id="path92" />
+ id="path93" />
+ id="path94" />
+ id="path95" />
+ id="path96" />
+ id="path97" />
+ id="path98" />
+ id="path99" />
+ id="path100" />
+ id="path101" />
+ id="path102" />
+ id="path103" />
+ id="path104" />
+ id="path105" />
+ id="path106" />
+ id="path107" />
+ id="g116">
+ id="use107" />
+ id="use108" />
+ id="use109" />
+ id="use110" />
+ id="use111" />
+ id="use112" />
+ id="use113" />
+ id="use114" />
+ id="use115" />
+ id="use116" />
+ id="path116" />
+ id="g127">
+ id="use117" />
+ id="use118" />
+ id="use119" />
+ id="use120" />
+ id="use121" />
+ id="use122" />
+ id="use123" />
+ id="use124" />
+ id="use125" />
+ id="use126" />
+ id="use127" />
+ id="path127" />
+ id="g146">
+ id="use128" />
+ id="use129" />
+ id="use130" />
+ id="use131" />
+ id="use132" />
+ id="use133" />
+ id="use134" />
+ id="use135" />
+ id="use136" />
+ id="use137" />
+ id="use138" />
+ id="use139" />
+ id="use140" />
+ id="use141" />
+ id="use142" />
+ id="use143" />
+ id="use144" />
+ id="use145" />
+ id="use146" />
+ id="path146" />
+ id="g154">
+ id="use147" />
+ id="use148" />
+ id="use149" />
+ id="use150" />
+ id="use151" />
+ id="use152" />
+ id="use153" />
+ id="use154" />
+ id="path154" />
+ id="g165">
+ id="use155" />
+ id="use156" />
+ id="use157" />
+ id="use158" />
+ id="use159" />
+ id="use160" />
+ id="use161" />
+ id="use162" />
+ id="use163" />
+ id="use164" />
+ id="use165" />
+ id="path165" />
+ id="g174">
+ id="use166" />
+ id="use167" />
+ id="use168" />
+ id="use169" />
+ id="use170" />
+ id="use171" />
+ id="use172" />
+ id="use173" />
+ id="use174" />
+ id="path174" />
+ id="g186">
+ id="use175" />
+ id="use176" />
+ id="use177" />
+ id="use178" />
+ id="use179" />
+ id="use180" />
+ id="use181" />
+ id="use182" />
+ id="use183" />
+ id="use184" />
+ id="use185" />
+ id="use186" />
+ id="path186" />
+ id="g198">
+ id="use187" />
+ id="use188" />
+ id="use189" />
+ id="use190" />
+ id="use191" />
+ id="use192" />
+ id="use193" />
+ id="use194" />
+ id="use195" />
+ id="use196" />
+ id="use197" />
+ id="use198" />
+ id="path198" />
+ id="g205">
+ id="use199" />
+ id="use200" />
+ id="use201" />
+ id="use202" />
+ id="use203" />
+ id="use204" />
+ id="use205" />
+ id="path205" />
+ id="g216">
+ id="use206" />
+ id="use207" />
+ id="use208" />
+ id="use209" />
+ id="use210" />
+ id="use211" />
+ id="use212" />
+ id="use213" />
+ id="use214" />
+ id="use215" />
+ id="use216" />
+ id="path216" />
+ id="g225">
+ id="use217" />
+ id="use218" />
+ id="use219" />
+ id="use220" />
+ id="use221" />
+ id="use222" />
+ id="use223" />
+ id="use224" />
+ id="use225" />
+ id="g226">
+ id="path225" />
+ id="g234">
+ id="use226" />
+ id="use227" />
+ id="use228" />
+ id="use229" />
+ id="use230" />
+ id="use231" />
+ id="use232" />
+ id="use233" />
+ id="use234" />
+ id="g251">
+ id="use235" />
+ id="use236" />
+ id="use237" />
+ id="use238" />
+ id="use239" />
+ id="use240" />
+ id="use241" />
+ id="use242" />
+ id="use243" />
+ id="use244" />
+ id="use245" />
+ id="use246" />
+ id="use247" />
+ id="use248" />
+ id="use249" />
+ id="use250" />
+ id="use251" />
+ id="path251" />
+ id="path252" />
+ id="g252">
+ id="use252" />
+ id="path253" />
+ id="path254" />
+ id="g254">
+ id="use254" />
+ id="path255" />
+ id="path256" />
+ id="g256">
+ id="use256" />
+ id="path257" />
+ id="path258" />
+ id="g258">
+ id="use258" />
+ id="path259" />
+ id="path260" />
+ id="g260">
+ id="use260" />
+ id="path261" />
+ id="path262" />
+ id="g262">
+ id="use262" />
+ id="path263" />
+ id="path264" />
+ id="g264">
+ id="use264" />
+ id="path265" />
+ id="path266" />
+ id="g266">
+ id="use266" />
+ id="path267" />
+ id="path268" />
+ id="g268">
+ id="use268" />
+ id="path269" />
+ id="path270" />
+ id="g270">
+ id="use270" />
+ id="path271" />
+ id="g272">
+ id="path272" />
+ id="g273">
+ id="use272" />
+ id="g274">
+ id="path273" />
+ id="g282">
+ id="use274" />
+ id="use275" />
+ id="use276" />
+ id="use277" />
+ id="use278" />
+ id="use279" />
+ id="use280" />
+ id="use281" />
+ id="use282" />
+ id="g300">
+ id="use283" />
+ id="use284" />
+ id="use285" />
+ id="use286" />
+ id="use287" />
+ id="use288" />
+ id="use289" />
+ id="use290" />
+ id="use291" />
+ id="use292" />
+ id="use293" />
+ id="use294" />
+ id="use295" />
+ id="use296" />
+ id="use297" />
+ id="use298" />
+ id="use299" />
+ id="use300" />
+ id="path300" />
+ id="path301" />
+ id="g301">
+ id="use301" />
+ id="path302" />
+ id="path303" />
+ id="g303">
+ id="use303" />
+ id="path304" />
+ id="path305" />
+ id="g305">
+ id="use305" />
+ id="path306" />
+ id="path307" />
+ id="g307">
+ id="use307" />
+ id="path308" />
+ id="path309" />
+ id="g309">
+ id="use309" />
+ id="path310" />
+ id="path311" />
+ id="g311">
+ id="use311" />
+ id="path312" />
+ id="path313" />
+ id="g313">
+ id="use313" />
+ id="path314" />
+ id="path315" />
+ id="g315">
+ id="use315" />
+ id="path316" />
+ id="path317" />
+ id="g317">
+ id="use317" />
+ id="path318" />
+ id="path319" />
+ id="g319">
+ id="use319" />
+ id="path320" />
+ id="g321">
+ id="path321" />
+ id="g322">
+ id="use321" />
+ id="g323">
+ id="path322" />
+ id="g331">
+ id="use323" />
+ id="use324" />
+ id="use325" />
+ id="use326" />
+ id="use327" />
+ id="use328" />
+ id="use329" />
+ id="use330" />
+ id="use331" />
+ id="g357">
+ id="use332" />
+ id="use333" />
+ id="use334" />
+ id="use335" />
+ id="use336" />
+ id="use337" />
+ id="use338" />
+ id="use339" />
+ id="use340" />
+ id="use341" />
+ id="use342" />
+ id="use343" />
+ id="use344" />
+ id="use345" />
+ id="use346" />
+ id="use347" />
+ id="use348" />
+ id="use349" />
+ id="use350" />
+ id="use351" />
+ id="use352" />
+ id="use353" />
+ id="use354" />
+ id="use355" />
+ id="use356" />
+ id="use357" />
+ id="path357" />
+ id="path358" />
+ id="g358">
+ id="use358" />
+ id="path359" />
+ id="path360" />
+ id="g360">
+ id="use360" />
+ id="path361" />
+ id="path362" />
+ id="g362">
+ id="use362" />
+ id="path363" />
+ id="path364" />
+ id="g364">
+ id="use364" />
+ id="path365" />
+ id="path366" />
+ id="g366">
+ id="use366" />
+ id="path367" />
+ id="path368" />
+ id="g368">
+ id="use368" />
+ id="path369" />
+ id="path370" />
+ id="g370">
+ id="use370" />
+ id="path371" />
+ id="path372" />
+ id="g372">
+ id="use372" />
+ id="path373" />
+ id="path374" />
+ id="g374">
+ id="use374" />
+ id="path375" />
+ id="path376" />
+ id="g376">
+ id="use376" />
+ id="path377" />
+ id="g378">
+ id="path378" />
+ id="g379">
+ id="use378" />
+ id="g380">
+ id="path379" />
+ id="g388">
+ id="use380" />
+ id="use381" />
+ id="use382" />
+ id="use383" />
+ id="use384" />
+ id="use385" />
+ id="use386" />
+ id="use387" />
+ id="use388" />
+ id="g403">
+ id="use389" />
+ id="use390" />
+ id="use391" />
+ id="use392" />
+ id="use393" />
+ id="use394" />
+ id="use395" />
+ id="use396" />
+ id="use397" />
+ id="use398" />
+ id="use399" />
+ id="use400" />
+ id="use401" />
+ id="use402" />
+ id="use403" />
+ id="path403" />
+ id="path404" />
+ id="g404">
+ id="use404" />
+ id="path405" />
+ id="path406" />
+ id="g406">
+ id="use406" />
+ id="path407" />
+ id="path408" />
+ id="g408">
+ id="use408" />
+ id="path409" />
+ id="path410" />
+ id="g410">
+ id="use410" />
+ id="path411" />
+ id="path412" />
+ id="g412">
+ id="use412" />
+ id="path413" />
+ id="path414" />
+ id="g414">
+ id="use414" />
+ id="path415" />
+ id="path416" />
+ id="g416">
+ id="use416" />
+ id="path417" />
+ id="path418" />
+ id="g418">
+ id="use418" />
+ id="path419" />
+ id="path420" />
+ id="g420">
+ id="use420" />
+ id="path421" />
+ id="path422" />
+ id="g422">
+ id="use422" />
+ id="path423" />
+ id="g424">
+ id="path424" />
+ id="g425">
+ id="use424" />
+ id="g426">
+ id="path425" />
+ id="g434">
+ id="use426" />
+ id="use427" />
+ id="use428" />
+ id="use429" />
+ id="use430" />
+ id="use431" />
+ id="use432" />
+ id="use433" />
+ id="use434" />
+ id="g452">
+ id="use435" />
+ id="use436" />
+ id="use437" />
+ id="use438" />
+ id="use439" />
+ id="use440" />
+ id="use441" />
+ id="use442" />
+ id="use443" />
+ id="use444" />
+ id="use445" />
+ id="use446" />
+ id="use447" />
+ id="use448" />
+ id="use449" />
+ id="use450" />
+ id="use451" />
+ id="use452" />
+ id="path452" />
+ id="path453" />
+ id="g453">
+ id="use453" />
+ id="path454" />
+ id="path455" />
+ id="g455">
+ id="use455" />
+ id="path456" />
+ id="path457" />
+ id="g457">
+ id="use457" />
+ id="path458" />
+ id="path459" />
+ id="g459">
+ id="use459" />
+ id="path460" />
+ id="path461" />
+ id="g461">
+ id="use461" />
+ id="path462" />
+ id="path463" />
+ id="g463">
+ id="use463" />
+ id="path464" />
+ id="path465" />
+ id="g465">
+ id="use465" />
+ id="path466" />
+ id="path467" />
+ id="g467">
+ id="use467" />
+ id="path468" />
+ id="path469" />
+ id="g469">
+ id="use469" />
+ id="path470" />
+ id="path471" />
+ id="g471">
+ id="use471" />
+ id="path472" />
+ id="g473">
+ id="path473" />
+ id="g474">
+ id="use473" />
+ id="g475">
+ id="path474" />
+ id="g483">
+ id="use475" />
+ id="use476" />
+ id="use477" />
+ id="use478" />
+ id="use479" />
+ id="use480" />
+ id="use481" />
+ id="use482" />
+ id="use483" />
+ id="g499">
+ id="use484" />
+ id="use485" />
+ id="use486" />
+ id="use487" />
+ id="use488" />
+ id="use489" />
+ id="use490" />
+ id="use491" />
+ id="use492" />
+ id="use493" />
+ id="use494" />
+ id="use495" />
+ id="use496" />
+ id="use497" />
+ id="use498" />
+ id="use499" />
+ id="path499" />
+ id="path500" />
+ id="g500">
+ id="use500" />
+ id="path501" />
+ id="path502" />
+ id="g502">
+ id="use502" />
+ id="path503" />
+ id="path504" />
+ id="g504">
+ id="use504" />
+ id="path505" />
+ id="path506" />
+ id="g506">
+ id="use506" />
+ id="path507" />
+ id="path508" />
+ id="g508">
+ id="use508" />
+ id="path509" />
+ id="path510" />
+ id="g510">
+ id="use510" />
+ id="path511" />
+ id="path512" />
+ id="g512">
+ id="use512" />
+ id="path513" />
+ id="path514" />
+ id="g514">
+ id="use514" />
+ id="path515" />
+ id="path516" />
+ id="g516">
+ id="use516" />
+ id="path517" />
+ id="path518" />
+ id="g518">
+ id="use518" />
+ id="path519" />
+ id="g520">
+ id="path520" />
+ id="g521">
+ id="use520" />
+ id="g522">
+ id="path521" />
+ id="g530">
+ id="use522" />
+ id="use523" />
+ id="use524" />
+ id="use525" />
+ id="use526" />
+ id="use527" />
+ id="use528" />
+ id="use529" />
+ id="use530" />
+ id="g549">
+ id="use531" />
+ id="use532" />
+ id="use533" />
+ id="use534" />
+ id="use535" />
+ id="use536" />
+ id="use537" />
+ id="use538" />
+ id="use539" />
+ id="use540" />
+ id="use541" />
+ id="use542" />
+ id="use543" />
+ id="use544" />
+ id="use545" />
+ id="use546" />
+ id="use547" />
+ id="use548" />
+ id="use549" />
+ id="path549" />
+ id="path550" />
+ id="g550">
+ id="use550" />
+ id="path551" />
+ id="path552" />
+ id="g552">
+ id="use552" />
+ id="path553" />
+ id="path554" />
+ id="g554">
+ id="use554" />
+ id="path555" />
+ id="path556" />
+ id="g556">
+ id="use556" />
+ id="path557" />
+ id="path558" />
+ id="g558">
+ id="use558" />
+ id="path559" />
+ id="path560" />
+ id="g560">
+ id="use560" />
+ id="path561" />
+ id="path562" />
+ id="g562">
+ id="use562" />
+ id="path563" />
+ id="path564" />
+ id="g564">
+ id="use564" />
+ id="path565" />
+ id="path566" />
+ id="g566">
+ id="use566" />
+ id="path567" />
+ id="path568" />
+ id="g568">
+ id="use568" />
+ id="path569" />
+ id="g570">
+ id="path570" />
+ id="g571">
+ id="use570" />
+ id="g572">
+ id="path571" />
+ id="g580">
+ id="use572" />
+ id="use573" />
+ id="use574" />
+ id="use575" />
+ id="use576" />
+ id="use577" />
+ id="use578" />
+ id="use579" />
+ id="use580" />
+ id="g599">
+ id="use581" />
+ id="use582" />
+ id="use583" />
+ id="use584" />
+ id="use585" />
+ id="use586" />
+ id="use587" />
+ id="use588" />
+ id="use589" />
+ id="use590" />
+ id="use591" />
+ id="use592" />
+ id="use593" />
+ id="use594" />
+ id="use595" />
+ id="use596" />
+ id="use597" />
+ id="use598" />
+ id="use599" />
+ id="path599" />
+ id="path600" />
+ id="g600">
+ id="use600" />
+ id="path601" />
+ id="path602" />
+ id="g602">
+ id="use602" />
+ id="path603" />
+ id="path604" />
+ id="g604">
+ id="use604" />
+ id="path605" />
+ id="path606" />
+ id="g606">
+ id="use606" />
+ id="path607" />
+ id="path608" />
+ id="g608">
+ id="use608" />
+ id="path609" />
+ id="path610" />
+ id="g610">
+ id="use610" />
+ id="path611" />
+ id="path612" />
+ id="g612">
+ id="use612" />
+ id="path613" />
+ id="path614" />
+ id="g614">
+ id="use614" />
+ id="path615" />
+ id="path616" />
+ id="g616">
+ id="use616" />
+ id="path617" />
+ id="path618" />
+ id="g618">
+ id="use618" />
+ id="path619" />
+ id="g620">
+ id="path620" />
+ id="g621">
+ id="use620" />
+ id="g622">
+ id="path621" />
+ id="g630">
+ id="use622" />
+ id="use623" />
+ id="use624" />
+ id="use625" />
+ id="use626" />
+ id="use627" />
+ id="use628" />
+ id="use629" />
+ id="use630" />
+ id="g644">
+ id="use631" />
+ id="use632" />
+ id="use633" />
+ id="use634" />
+ id="use635" />
+ id="use636" />
+ id="use637" />
+ id="use638" />
+ id="use639" />
+ id="use640" />
+ id="use641" />
+ id="use642" />
+ id="use643" />
+ id="use644" />
+ id="path644" />
+ id="path645" />
+ id="g645">
+ id="use645" />
+ id="path646" />
+ id="path647" />
+ id="g647">
+ id="use647" />
+ id="path648" />
+ id="path649" />
+ id="g649">
+ id="use649" />
+ id="path650" />
+ id="path651" />
+ id="g651">
+ id="use651" />
+ id="path652" />
+ id="path653" />
+ id="g653">
+ id="use653" />
+ id="path654" />
+ id="path655" />
+ id="g655">
+ id="use655" />
+ id="path656" />
+ id="path657" />
+ id="g657">
+ id="use657" />
+ id="path658" />
+ id="path659" />
+ id="g659">
+ id="use659" />
+ id="path660" />
+ id="path661" />
+ id="g661">
+ id="use661" />
+ id="path662" />
+ id="path663" />
+ id="g663">
+ id="use663" />
+ id="path664" />
+ id="g665">
+ id="path665" />
+ id="g666">
+ id="use665" />
+ id="g667">
+ id="path666" />
+ id="g675">
+ id="use667" />
+ id="use668" />
+ id="use669" />
+ id="use670" />
+ id="use671" />
+ id="use672" />
+ id="use673" />
+ id="use674" />
+ id="use675" />
+ id="g693">
+ id="use676" />
+ id="use677" />
+ id="use678" />
+ id="use679" />
+ id="use680" />
+ id="use681" />
+ id="use682" />
+ id="use683" />
+ id="use684" />
+ id="use685" />
+ id="use686" />
+ id="use687" />
+ id="use688" />
+ id="use689" />
+ id="use690" />
+ id="use691" />
+ id="use692" />
+ id="use693" />
+ id="g694">
+ id="path693" />
+ id="g695">
+ id="path694" />
+ id="g696">
+ id="use695" />
+ id="g697">
+ id="path696" />
+ id="g698">
+ id="path697" />
+ id="g699">
+ id="use698" />
+ id="g700">
+ id="path699" />
+ id="g701">
+ id="path700" />
+ id="g702">
+ id="use701" />
+ id="g703">
+ id="path702" />
+ id="g704">
+ id="path703" />
+ id="g705">
+ id="use704" />
+ id="g706">
+ id="path705" />
+ id="g707">
+ id="path706" />
+ id="g708">
+ id="use707" />
+ id="g709">
+ id="path708" />
+ id="g710">
+ id="path709" />
+ id="g711">
+ id="use710" />
+ id="g712">
+ id="path711" />
+ id="g713">
+ id="path712" />
+ id="g714">
+ id="use713" />
+ id="g715">
+ id="path714" />
+ id="g716">
+ id="path715" />
+ id="g717">
+ id="use716" />
+ id="g718">
+ id="path717" />
+ id="g719">
+ id="path718" />
+ id="g720">
+ id="use719" />
+ id="g721">
+ id="path720" />
+ id="g722">
+ id="path721" />
+ id="g723">
+ id="use722" />
+ id="g724">
+ id="path723" />
+ id="g725">
+ id="path724" />
+ id="g726">
+ id="use725" />
diff --git a/src/libsemigroups_pybind11/presentation/__init__.py b/src/libsemigroups_pybind11/presentation/__init__.py
index 6b8dc872f..5ba424612 100644
--- a/src/libsemigroups_pybind11/presentation/__init__.py
+++ b/src/libsemigroups_pybind11/presentation/__init__.py
@@ -220,9 +220,7 @@ def __init__(self: _Self, *args, **kwargs) -> None:
assert isinstance(args[0], Presentation)
self.py_template_params = args[0].py_template_params
- self.init_cxx_obj()
- self.alphabet(args[0].alphabet())
- self.rules = args[0].rules
+ self.init_cxx_obj(args[0])
_copy_cxx_mem_fns(_InversePresentationWord, InversePresentation)
diff --git a/src/libsemigroups_pybind11/stephen.py b/src/libsemigroups_pybind11/stephen.py
index 5598cce44..c5f60f834 100644
--- a/src/libsemigroups_pybind11/stephen.py
+++ b/src/libsemigroups_pybind11/stephen.py
@@ -13,9 +13,13 @@
from typing_extensions import Self as _Self
from _libsemigroups_pybind11 import (
+ InversePresentationString as _InversePresentationString,
InversePresentationWord as _InversePresentationWord,
+ PresentationString as _PresentationString,
PresentationWord as _PresentationWord,
+ StephenInversePresentationString as _StephenInversePresentationString,
StephenInversePresentationWord as _StephenInversePresentationWord,
+ StephenPresentationString as _StephenPresentationString,
StephenPresentationWord as _StephenPresentationWord,
stephen_accepts as _stephen_accepts,
stephen_dot as _stephen_dot,
@@ -46,8 +50,10 @@ class Stephen(_CxxWrapper):
__doc__ = _StephenPresentationWord.__doc__
_py_template_params_to_cxx_type = {
- (_PresentationWord,): _StephenPresentationWord,
+ (_InversePresentationString,): _StephenInversePresentationString,
(_InversePresentationWord,): _StephenInversePresentationWord,
+ (_PresentationString,): _StephenPresentationString,
+ (_PresentationWord,): _StephenPresentationWord,
}
_cxx_type_to_py_template_params = dict(
diff --git a/src/stephen.cpp b/src/stephen.cpp
index 9691f99c5..09d741c0f 100644
--- a/src/stephen.cpp
+++ b/src/stephen.cpp
@@ -34,7 +34,8 @@ namespace libsemigroups {
namespace {
template
void bind_stephen(py::module& m, std::string const& name) {
- using Stephen_ = Stephen;
+ using Stephen_ = Stephen;
+ using native_word_type = typename Stephen_::native_word_type;
py::class_ thing(m,
name.c_str(),
@@ -213,11 +214,9 @@ Get the input presentation.
:returns: A presentation.
:rtype: Presentation | InversePresentation
)pbdoc");
- // TODO(2): Change to support std::string once we have that implemented
- // in libsemigroups itself
thing.def(
"set_word",
- [](Stephen_& self, word_type const& word) -> Stephen_& {
+ [](Stephen_& self, native_word_type const& word) -> Stephen_& {
return stephen::set_word(self, word);
},
py::arg("word"),
@@ -379,10 +378,14 @@ it labels a path in :any:`Stephen.word_graph` with source ``0``.
this function may never terminate.
)pbdoc");
- m.def("stephen_left_factors",
- &stephen::left_factors,
- py::arg("s"),
- R"pbdoc(
+ m.def(
+ "stephen_left_factors",
+ [](Stephen_& s) {
+ auto range = stephen::left_factors(s);
+ return py::make_iterator(rx::begin(range), rx::end(range));
+ },
+ py::arg("s"),
+ R"pbdoc(
:sig=(s: Stephen) -> Paths:
:only-document-once:
Returns a :any:`Paths` object containing all the words (in short-lex order)
@@ -504,10 +507,14 @@ equivalent to :math:`u` in the semigroup defined by
this function may never terminate.
)pbdoc");
- m.def("stephen_words_accepted",
- &stephen::words_accepted,
- py::arg("s"),
- R"pbdoc(
+ m.def(
+ "stephen_words_accepted",
+ [](Stephen_& s) {
+ auto range = stephen::words_accepted(s);
+ return py::make_iterator(rx::begin(range), rx::end(range));
+ },
+ py::arg("s"),
+ R"pbdoc(
:sig=(s: Stephen) -> Paths:
:only-document-once:
@@ -537,11 +544,12 @@ been triggered already).
} // namespace
void init_stephen(py::module& m) {
- // TODO(2): figure out how to handle std::string Stephens once that's
- // supported
bind_stephen>(m, "StephenPresentationWord");
bind_stephen>(
m, "StephenInversePresentationWord");
+ bind_stephen>(m, "StephenPresentationString");
+ bind_stephen>(
+ m, "StephenInversePresentationString");
}
} // namespace libsemigroups
diff --git a/tests/test_stephen.py b/tests/test_stephen.py
index f9be2e326..5a76dd45d 100644
--- a/tests/test_stephen.py
+++ b/tests/test_stephen.py
@@ -39,7 +39,6 @@
def check_000(s):
s.set_word([0]).run()
assert s.word_graph().number_of_nodes() == 2
- # TODO(1): use UNDEFINED once that works
assert s.word_graph() == WordGraph(2, [[1, UNDEFINED], [UNDEFINED, 1]])
assert stephen.number_of_words_accepted(s) == POSITIVE_INFINITY
assert list(islice(stephen.words_accepted(s), 10)) == [
@@ -89,7 +88,7 @@ def verify_c4_normal_form(p, word, nf):
assert sorted(list(stephen.words_accepted(S)), key=lexicographic_compare_key_func)[0] == nf
assert all(stephen.accepts(S, w) for w in stephen.words_accepted(S))
- assert stephen.number_of_words_accepted(S) == len(stephen.words_accepted(S))
+ assert stephen.number_of_words_accepted(S) == sum(1 for _ in stephen.words_accepted(S))
def verify_c4_equal_to(p, word1, word2):
@@ -323,8 +322,6 @@ def test_stephen_002():
)
-# TODO(2): add a version of all test cases for std::string once this is
-# allowed by Stephen.
@pytest.mark.quick
def test_stephen_003():
"""from step_hen 002"""
@@ -354,6 +351,34 @@ def test_stephen_003():
assert stephen.accepts(S, to_word("bbaba"))
+@pytest.mark.quick
+def test_stephen_003_str():
+ """from step_hen 002"""
+ ReportGuard(False)
+ p = Presentation("ab")
+ presentation.add_rule(p, "aaa", "a")
+ presentation.add_rule(p, "bbb", "b")
+ presentation.add_rule(p, "abab", "aa")
+
+ S = Stephen(p)
+ S.set_word("bbab")
+
+ assert stephen.accepts(S, "bbaaba")
+ assert not stephen.accepts(S, "")
+ assert not stephen.accepts(S, "aaaaaaaaaa")
+ assert not stephen.accepts(S, "bbb")
+
+ S.set_word("bba")
+ assert stephen.accepts(S, "bbabb")
+ assert stephen.accepts(S, "bba")
+ assert not stephen.accepts(S, "bbb")
+ assert not stephen.accepts(S, "a")
+ assert not stephen.accepts(S, "ab")
+
+ S.set_word("bbaab")
+ assert stephen.accepts(S, "bbaba")
+
+
@pytest.mark.quick
def test_stephen_004():
"""from step_hen 003"""
@@ -454,6 +479,40 @@ def test_stephen_005():
]
+@pytest.mark.quick
+def test_stephen_005_str():
+ """from step_hen 004"""
+ ReportGuard(False)
+ p = Presentation("abc")
+ presentation.add_rule(p, "ab", "ba")
+ presentation.add_rule(p, "ac", "cc")
+ presentation.add_rule(p, "ac", "a")
+ presentation.add_rule(p, "cc", "a")
+ presentation.add_rule(p, "bc", "cc")
+ presentation.add_rule(p, "bcc", "b")
+ presentation.add_rule(p, "bc", "b")
+ presentation.add_rule(p, "cc", "b")
+ presentation.add_rule(p, "a", "b")
+
+ S = Stephen(p)
+ S.set_word("abcc").run()
+ assert stephen.accepts(S, "baac")
+ assert S.word_graph().number_of_nodes() == 3
+ assert stephen.number_of_words_accepted(S) == POSITIVE_INFINITY
+ assert list(islice(stephen.words_accepted(S), 10)) == [
+ "a",
+ "b",
+ "aa",
+ "ab",
+ "ac",
+ "ba",
+ "bb",
+ "bc",
+ "ca",
+ "cb",
+ ]
+
+
@pytest.mark.quick
def test_stephen_006():
"""from step_hen 005"""
@@ -521,7 +580,7 @@ def test_stephen_008():
] == to_word("dfabcdf")
assert all(stephen.accepts(S, w) for w in stephen.words_accepted(S))
- assert stephen.number_of_words_accepted(S) == len(stephen.words_accepted(S))
+ assert stephen.number_of_words_accepted(S) == sum(1 for _ in stephen.words_accepted(S))
S.set_word(to_word("abcdfceg")).run()
assert stephen.number_of_words_accepted(S) == 16
@@ -572,7 +631,7 @@ def test_Stephen_009():
S.set_word(to_word("acba")).run()
- assert list(stephen.words_accepted(S)) == [to_word("aabc"), to_word("acba")]
+ assert list(stephen.words_accepted(S)) == [to_word("acba"), to_word("aabc")]
verify_c4_normal_form(p, to_word("acba"), to_word("aabc"))
@@ -918,34 +977,13 @@ def test_stephen_031():
"""Test behaviour when uninitialised"""
ReportGuard(False)
p = Presentation([])
- S = Stephen(p)
with pytest.raises(LibsemigroupsError):
- S.accept_state()
- with pytest.raises(LibsemigroupsError):
- S.word()
- with pytest.raises(LibsemigroupsError):
- S.word_graph()
-
- with pytest.raises(LibsemigroupsError):
- stephen.is_left_factor(S, [0, 0, 0])
- with pytest.raises(LibsemigroupsError):
- stephen.accepts(S, [0, 0, 0])
- with pytest.raises(LibsemigroupsError):
- stephen.number_of_left_factors(S)
- with pytest.raises(LibsemigroupsError):
- stephen.number_of_words_accepted(S)
- with pytest.raises(LibsemigroupsError):
- S.run()
-
- with pytest.raises(LibsemigroupsError):
- stephen.words_accepted(S)
- with pytest.raises(LibsemigroupsError):
- stephen.left_factors(S)
+ S = Stephen(p)
p = Presentation([0, 1])
presentation.add_rule(p, [0, 1], [1, 0])
- S.init(p)
+ S = Stephen(p)
with pytest.raises(LibsemigroupsError):
S.accept_state()
@@ -1236,9 +1274,6 @@ def test_stephen_044():
assert stephen.accepts(T.set_word(ww), ww)
-# TODO(2): add test_case_45 once we fix it
-
-
@pytest.mark.quick
def test_stephen_046():
"""non-inverse presentation -- operator=="""
@@ -1434,7 +1469,7 @@ def test_stephen_045():
T.set_word(T.word() * 2)
T.run()
assert S == T
- assert stephen.words_accepted(S).get() == [0, 2, 0, 2]
+ assert next(stephen.words_accepted(S)) == [0, 2, 0, 2]
assert stephen.number_of_left_factors(S) == POSITIVE_INFINITY
S.set_word(to_word("aBbcaABAabCc"))
T.set_word(to_word("CcBAabaACBbA"))
@@ -1471,7 +1506,7 @@ def test_stephen_049():
presentation.add_rule(p, [0, 0, 0], [1, 1])
presentation.add_rule(p, [0, 0, 1], [1, 0])
- S = Stephen(Presentation([]))
+ S = Stephen(p)
assert repr(S) == f""
S.init(p)
assert repr(S) == f""
@@ -1512,27 +1547,24 @@ def test_stephen_049():
S.init(p)
assert repr(S) == f""
- to_word = ToWord("abcABC")
- pi = InversePresentation(to_word("abcABC"))
- pi.inverses(to_word("ABCabc"))
- presentation.add_rule(pi, to_word("ac"), to_word("ca"))
- presentation.add_rule(pi, to_word("ab"), to_word("ba"))
- presentation.add_rule(pi, to_word("bc"), to_word("cb"))
+ pi = InversePresentation("abcABC")
+ pi.inverses("ABCabc")
+ presentation.add_rule(pi, "ac", "ca")
+ presentation.add_rule(pi, "ab", "ba")
+ presentation.add_rule(pi, "bc", "cb")
- IS = Stephen(InversePresentation([]))
+ IS = Stephen(pi)
assert repr(IS) == f""
IS.init(pi)
assert repr(IS) == f""
- IS.set_word(to_word("BaAbaBcAb"))
+ IS.set_word("BaAbaBcAb")
assert (
- repr(IS)
- == f""
)
IS.run()
assert (
- repr(IS)
- == f""
)
@@ -1541,28 +1573,27 @@ def test_stephen_049():
def test_stephen_051():
"""Incomplete Munn tree products"""
ReportGuard(False)
- to_word = ToWord("abcABC")
- p = InversePresentation(to_word("abcABC"))
- p.inverses(to_word("ABCabc"))
+ p = InversePresentation("abcABC")
+ p.inverses("ABCabc")
S = Stephen(p)
Si = Stephen(p)
T = Stephen(p)
Ti = Stephen(p)
- S.set_word(to_word("aBbcaABAabCc")).run()
- T.set_word(to_word("aBbcaABAabCc")).run()
+ S.set_word("aBbcaABAabCc").run()
+ T.set_word("aBbcaABAabCc").run()
S *= T
S.run()
- Si.set_word(to_word("aBbcaABAabCc"))
+ Si.set_word("aBbcaABAabCc")
Si *= T
Si.run()
assert Si == S
- Si.set_word(to_word("aBbcaABAabCc"))
- Ti.set_word(to_word("aBbcaABAabCc"))
+ Si.set_word("aBbcaABAabCc")
+ Ti.set_word("aBbcaABAabCc")
Si.run()
Si *= Ti
Si.run()
@@ -1572,14 +1603,13 @@ def test_stephen_051():
@pytest.mark.quick
def test_stephen_return_policy():
ReportGuard(False)
- to_word = ToWord("abcABC")
- p = InversePresentation(to_word("abcABC"))
- p.inverses(to_word("ABCabc"))
+ p = InversePresentation("abcABC")
+ p.inverses("ABCabc")
S = Stephen(p)
assert S.copy() is not S
assert S.init(p) is S
- assert S.set_word([0, 1]) is S
+ assert S.set_word("ab") is S
assert S.word_graph() is S.word_graph()