eyeling 1.14.1 → 1.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/HANDBOOK.md CHANGED
@@ -969,7 +969,9 @@ If the types don’t fit any supported case, the builtin fails.
969
969
 
970
970
  **Shape:** `( $base $exp ) math:exponentiation $result`
971
971
 
972
- - Forward direction: if base and exponent are numeric, computes `base ** exp`.
972
+ - Forward direction supports two modes:
973
+ - **Exact integer mode (BigInt):** if `$base` and `$exp` are integer literals and `$exp >= 0`, Eyeling computes the exact integer power using BigInt (with a safety cap on the estimated result size to avoid OOM).
974
+ - **Numeric mode (Number):** otherwise, if base and exponent parse as finite Numbers, computes `base ** exp`.
973
975
  - Reverse direction (limited): Eyeling can sometimes solve for the exponent if:
974
976
  - base and result are numeric, finite, and **positive**
975
977
  - base is not 1
@@ -977,6 +979,8 @@ If the types don’t fit any supported case, the builtin fails.
977
979
 
978
980
  This is a pragmatic inversion, not a full algebra system.
979
981
 
982
+ The **BigInt exact-integer mode** exists specifically to avoid rule-level “repeat multiply” derivations that can explode memory for large exponents (e.g., the Ackermann example).
983
+
980
984
  #### Unary “math relations” (often invertible)
981
985
 
982
986
  Eyeling implements these as a shared pattern: if the subject is numeric, compute object; else if the object is numeric, compute subject via an inverse function; if both sides are unbound, succeed once (don’t enumerate).
@@ -39,17 +39,24 @@
39
39
  (?Y ?Z) math:product ?A.
40
40
  }.
41
41
 
42
+ # exponentiation (x=3) — use BigInt-capable math:exponentiation to avoid blow-up
43
+ {
44
+ (3 ?Y ?Z) :ackermann ?A.
45
+ } <= {
46
+ (?Z ?Y) math:exponentiation ?A.
47
+ }.
48
+
42
49
  # exponentiation (x=3), tetration (x=4), pentation (x=5), hexation (x=6), etc
43
50
  {
44
51
  (?X 0 ?Z) :ackermann 1.
45
52
  } <= {
46
- ?X math:greaterThan 2.
53
+ ?X math:greaterThan 3.
47
54
  }.
48
55
 
49
56
  {
50
57
  (?X ?Y ?Z) :ackermann ?A.
51
58
  } <= {
52
- ?X math:greaterThan 2.
59
+ ?X math:greaterThan 3.
53
60
  ?Y math:notEqualTo 0.
54
61
  (?Y 1) math:difference ?B.
55
62
  (?X ?B ?Z) :ackermann ?C.
@@ -69,7 +76,7 @@
69
76
  (3 1000) :ackermann ?A7.
70
77
  (4 0) :ackermann ?A8.
71
78
  (4 1) :ackermann ?A9.
72
- #(4 2) :ackermann ?A10.
79
+ (4 2) :ackermann ?A10.
73
80
  (5 0) :ackermann ?A11.
74
81
  } => {
75
82
  :test :is {
@@ -83,7 +90,7 @@
83
90
  (3 1000) :ackermann ?A7.
84
91
  (4 0) :ackermann ?A8.
85
92
  (4 1) :ackermann ?A9.
86
- #(4 2) :ackermann ?A10.
93
+ (4 2) :ackermann ?A10.
87
94
  (5 0) :ackermann ?A11.
88
95
  }.
89
96
  }.
@@ -11,5 +11,6 @@
11
11
  (3 1000) :ackermann 85720688574901385675874003924800144844912384936442688595500031069628084089994889799455870305255668650207573833404251746014971622855385123487876620597588598431476542198593847883368596840498969135023633457224371799868655530139190140473324351568616503316569571821492337341283438653220995094697645344555005 .
12
12
  (4 0) :ackermann 13 .
13
13
  (4 1) :ackermann 65533 .
14
+ (4 2) :ackermann 2003529930406846464979072351560255750447825475569751419265016973710894059556311453089506130880933348101038234342907263181822949382118812668869506364761547029165041871916351587966347219442930927982084309104855990570159318959639524863372367203002916969592156108764948889254090805911457037675208500206671563702366126359747144807111774815880914135742720967190151836282560618091458852699826141425030123391108273603843767876449043205960379124490905707560314035076162562476031863793126484703743782954975613770981604614413308692118102485959152380195331030292162800160568670105651646750568038741529463842244845292537361442533614373729088303794601274724958414864915930647252015155693922628180691650796381064132275307267143998158508811292628901134237782705567421080070065283963322155077831214288551675554073345107213112427399562982719769150054883905223804357045848197956393157853510018992000024141963706813559840464039472194016069517690156119726982337890017641517190051133466306898140219383481435426387306539552969691388024158161859561100640362119796101859534802787167200122604642492385111393400464351623867567078745259464670903886547743483217897012764455529409092021959585751622973333576159552394885297579954028471943529913543763705986928913757153740001986394332464890052543106629669165243419174691389632476560289415199775477703138064781342309596190960654591300890188887588084733625956065444888501447335706058817090162108499714529568344061979690565469813631162053579369791403236328496233046421066136200220175787851857409162050489711781820400187282939943446186224328009837323764931814789848119452713007440220765680910376203999203492023906626264491909167985461515778839060397720759279378852241294301017458086862263369284725851403039615558564330385450688652213114813638408384778263790459607186876728509763471271988890680478243230394718650525660978150729861141430305816927924971409161059417185352275887504477592218301158780701975535722241400019548102005661773589781499532325208589753463547007786690406429016763808161740550405117670093673202804549339027992491867306539931640720492238474815280619166900933805732120816350707634351669869625020969023162859350071874190579161241536897514808261904847946571736601005892476655445840838334790544144817684255327207315586349347605137419779525190365032198020108764738368682531025183377533908861426184800374008082238104076468878471647552945326947661700424461063311238021134588694532200116564076327023074292426051582811070387018345324567635625951430032037432740780879056283663406965030844225855967039271869461158513793386475699748568670079823960604393478850861649260304945061743412365828352144806726676841807083754862211408236579802961200027441324438432402331257403545019352428776430880232850855886089962774458164680857875115807014743763867976955049991643998284357290415378143438847303484261903388841494031366139854257635577105335580206622185577060082551288893332226436281984838613239570676191409638533832374343758830859233722284644287996245605476932428998432652677378373173288063210753211238680604674708428051166488709084770291208161104912555598322366244868556651402684641209694982590565519216188104341226838996283071654868525536914850299539675503954938371853405900096187489473992880432496373165753803673586710175783994818471798498246948060532081996066183434012476096639519778021441199752546704080608499344178256285092726523709898651539462193004607364507926212975917698293892367015170992091531567814439791248475706237804600009918293321306880570046591458387208088016887445835557926258465124763087148566313528934166117490617526671492672176128330845273936469244582892571388877839056300482483799839692029222215486145902373478222682521639957440801727144146179559226175083889020074169926238300282286249284182671243405751424188569994272331606998712986882771820617214453142574944015066139463169197629181506579745526236191224848063890033669074365989226349564114665503062965960199720636202603521917776740668777463549375318899587866282125469797102065747232721372918144666659421872003474508942830911535189271114287108376159222380276605327823351661555149369375778466670145717971901227117812780450240026384758788339396817962950690798817121690686929538248529830023476068454114178139110648560236549754227497231007615131870024053910510913817843721791422528587432098524957878034683703337818421444017138688124249984418618129271198533315382567321870421530631197748535214670955334626336610864667332292409879849256691109516143618601548909740241913509623043612196128165950518666022030715613684732364660868905014263913906515063908199378852318365059897299125404479443425166774299659811849233151555272883274028352688442408752811283289980625912673699546247341543333500147231430612750390307397135252069338173843322950701049061867539433130784798015655130384758155685236218010419650255596181934986315913233036096461905990236112681196023441843363334594927631946101716652913823717182394299216272538461776065694542297877071383198817036964588689811863210976900355735884624464835706291453052757101278872027965364479724025405448132748391794128826423835171949197209797145936887537198729130831738033911016128547415377377715951728084111627597186384924222802373441925469991983672192131287035585307966942713416391033882754318613643490100943197409047331014476299861725424423355612237435715825933382804986243892498222780715951762757847109475119033482241412025182688713728193104253478196128440176479531505057110722974314569915223451643121848657575786528197564843508958384722923534559464521215831657751471298708225909292655638836651120681943836904116252668710044560243704200663709001941185557160472044643696932850060046928140507119069261393993902735534545567470314903886022024639948260501762431969305640666366626090207048887438898907498152865444381862917382901051820869936382661868303915273264581286782806601337500096593364625146091723180312930347877421234679118454791311109897794648216922505629399956793483801699157439700537542134485874586856047286751065423341893839099110586465595113646061055156838541217459801807133163612573079611168343863767667307354583494789788316330129240800836356825939157113130978030516441716682518346573675934198084958947940983292500086389778563494693212473426103062713745077286156922596628573857905533240641849018451328284632709269753830867308409142247659474439973348130810986399417379789657010687026734161967196591599588537834822988270125605842365589539690306474965584147981310997157542043256395776070485100881578291408250777738559790129129407309462785944505859412273194812753225152324801503466519048228961406646890305102510916237770448486230229488966711380555607956620732449373374027836767300203011615227008921843515652121379215748206859356920790214502277133099987729459596952817044582181956080965811702798062669891205061560742325686842271306295009864421853470810407128917646906550836129916694778023822502789667843489199409657361704586786242554006942516693979292624714524945408858422726153755260071904336329196375777502176005195800693847635789586878489536872122898557806826518192703632099480155874455575175312736471421295536494084385586615208012115079075068553344489258693283859653013272046970694571546959353658571788894862333292465202735853188533370948455403336565356988172582528918056635488363743793348411845580168331827676834646291995605513470039147876808640322629616641560667508153710646723108461964247537490553744805318226002710216400980584497526023035640038083472053149941172965736785066421400842696497103241919182121213206939769143923368374709228267738708132236680086924703491586840991153098315412063566123187504305467536983230827966457417620806593177265685841681837966106144963432544111706941700222657817358351259821080769101961052229263879745049019254311900620561906577452416191913187533984049343976823310298465893318373015809592522829206820862230332585280119266496314441316442773003237792274712330696417149945532261035475145631290668854345426869788447742981777493710117614651624183616680254815296335308490849943006763654806102940094693750609845588558043970485914449584445079978497045583550685408745163316464118083123079704389849190506587586425810738422420591191941674182490452700288263983057950057341711487031187142834184499153456702915280104485145176055306971441761368582384102787659324662689978418319620312262421177391477208004883578333569204533935953254564897028558589735505751235129536540502842081022785248776603574246366673148680279486052445782673626230852978265057114624846595914210278122788941448163994973881884622768244851622051817076722169863265701654316919742651230041757329904473537672536845792754365412826553581858046840069367718605020070547247548400805530424951854495267247261347318174742180078574693465447136036975884118029408039616746946288540679172138601225419503819704538417268006398820656328792839582708510919958839448297775647152026132871089526163417707151642899487953564854553553148754978134009964854498635824847690590033116961303766127923464323129706628411307427046202032013368350385425360313636763575212604707425311209233402837482949453104727418969287275572027615272268283376741393425652653283068469997597097750005560889932685025049212884068274139881631540456490350775871680074055685724021758685439053228133770707415830756269628316955687424060527726485853050611356384851965918968649596335568216975437621430778665934730450164822432964891270709898076676625671517269062058815549666382573829274182082278960684488222983394816670984039024283514306813767253460126007269262969468672750794346190439996618979611928750519442356402644303271737341591281496056168353988188569484045342311424613559925272330064881627466723523751234311893442118885085079358163848994487544756331689213869675574302737953785262542329024881047181939037220666894702204258836895840939998453560948869946833852579675161882159410981624918741813364726965123980677561947912557957446471427868624053750576104204267149366084980238274680575982591331006919941904651906531171908926077949119217946407355129633864523035673345588033313197080365457184791550432654899559705862888286866606618021882248602144999973122164138170653480175510438406624412822803616648904257377640956326482825258407669045608439490325290526337532316509087681336614242398309530806549661879381949120033919489494065132398816642080088395554942237096734840072642705701165089075196155370186264797456381187856175457113400473810762763014953309735174180655479112660938034311378532532883533352024934365979129341284854970946826329075830193072665337782559314331110963848053940859283988907796210479847919686876539987477095912788727475874439806779824968278272200926449944559380414608770641941810440758269805688038949654616587983904660587645341810289907194293021774519976104495043196841503455514044820928933378657363052830619990077748726922998608279053171691876578860908941817057993404890218441559791092676862796597583952483926734883634745651687016166240642424241228961118010615682342539392180052483454723779219911228595914191877491793823340010078128326506710281781396029120914720100947878752551263372884222353869490067927664511634758101193875319657242121476038284774774571704578610417385747911301908583877890152334343013005282797038580359815182929600305682612091950943737325454171056383887047528950563961029843641360935641632589408137981511693338619797339821670761004607980096016024823096943043806956620123213650140549586250615282588033022908385812478469315720323233601899469437647726721879376826431828382603564520699468630216048874528424363593558622333506235945002890558581611275341783750455936126130852640828051213873177490200249552738734585956405160830583053770732533971552620444705429573538361113677523169972740292941674204423248113875075631319078272188864053374694213842169928862940479635305150560788126366206497231257579019598873041195626227343728900516561111094111745277965482790471250581999077498063821559376885546498822938985408291325129076478386322494781016753491693489288104203015610283386143827378160946341335383578340765314321417150655877547820252454780657301342277470616744241968952613164274104695474621483756288299771804186785084546965619150908695874251184435837306590951460980451247409411373899927822492983367796011015387096129749705566301637307202750734759922943792393824427421186158236161317886392553095117188421298508307238259729144142251579403883011359083331651858234967221259621812507058113759495525022747274674369887131926670769299199084467161228738858457584622726573330753735572823951616964175198675012681745429323738294143824814377139861906716657572945807804820559511881687188075212971832636442155336787751274766940790117057509819575084563565217389544179875074523854455200133572033332379895074393905312918212255259833790909463630202185353848854825062897715616963860712382771725621313460549401770413581731931763370136332252819127547191443450920711848838366818174263342949611870091503049165339464763717766439120798347494627397822171502090670190302469762151278521956142070806461631373236517853976292092025500288962012970141379640038055734949269073535145961208674796547733692958773628635660143767964038430796864138563447801328261284589184898528048048844180821639423974014362903481665458114454366460032490618763039502356402044530748210241366895196644221339200757479128683805175150634662569391937740283512075666260829890491877287833852178522792045771846965855278790447562192663992008409302075673925363735628390829817577902153202106409617373283598494066652141198183810884515459772895164572131897797907491941013148368544639616904607030107596818933741217575988165127000761262789169510406315857637534787420070222051070891257612361658026806815858499852631465878086616800733264676830206391697203064894405628195406190685242003053463156621891327309069687353181641094514288036605995220248248886711554429104721929134248346438705368508648749099178812670565665387191049721820042371492740164460943459845392536706132210616533085662021188968234005752675486101476993688738209584552211571923479686888160853631615862880150395949418529489227074410828207169303387818084936204018255222271010985653444817207470756019245915599431072949578197878590578940052540122867517142511184356437184053563024181225473266093302710397968091064939272722683035410467632591355279683837705019855234621222858410557119921731717969804339317707750755627056047831779844447637560254637033369247114220815519973691371975163241302748712199863404548248524570118553342675264715978310731245663429805221455494156252724028915333354349341217862037007260315279870771872491234494477147909520734761385425485311552773301030342476835865496093722324007154518129732692081058424090557725645803681462234493189708138897143299831347617799679712453782310703739151473878692119187566700319321281896803322696594459286210607438827416919465162267632540665070881071030394178860564893769816734159025925194611823642945652669372203155504700213598846292758012527715422016629954863130324912311029627923723899766416803497141226527931907636326136814145516376656559839788489381733082668779901962886932296597379951931621187215455287394170243669885593888793316744533363119541518404088283815193421234122820030950313341050704760159987985472529190665222479319715440331794836837373220821885773341623856441380700541913530245943913502554531886454796252260251762928374330465102361057583514550739443339610216229675461415781127197001738611494279501411253280621254775810512972088465263158094806633687670147310733540717710876615935856814098212967730759197382973441445256688770855324570888958320993823432102718224114763732791357568615421252849657903335093152776925505845644010552192644505312073756287744998163646332835816140330175813967359427327690448920361880386754955751806890058532927201493923500525845146706982628548257883267398735220457228239290207144822219885587102896991935873074277815159757620764023951243860202032596596250212578349957710085626386118233813318509014686577064010676278617583772772895892746039403930337271873850536912957126715066896688493880885142943609962012966759079225082275313812849851526902931700263136328942095797577959327635531162066753488651317323872438748063513314512644889967589828812925480076425186586490241111127301357197181381602583178506932244007998656635371544088454866393181708395735780799059730839094881804060935959190907473960904410150516321749681412100765719177483767355751000733616922386537429079457803200042337452807566153042929014495780629634138383551783599764708851349004856973697965238695845994595592090709058956891451141412684505462117945026611750166928260250950770778211950432617383223562437601776799362796099368975191394965033358507155418436456852616674243688920371037495328425927131610537834980740739158633817967658425258036737206469351248652238481341663808061505704829059890696451936440018597120425723007316410009916987524260377362177763430621616744884930810929901009517974541564251204822086714586849255132444266777127863728211331536224301091824391243380214046242223349153559516890816288487989988273630445372432174280215755777967021666317047969728172483392841015642274507271779269399929740308072770395013581545142494049026536105825409373114653104943382484379718606937214444600826798002471229489405761853892203425608302697052876621377373594394224114707074072902725461307358541745691419446487624357682397065703184168467540733466346293673983620004041400714054277632480132742202685393698869787607009590048684650626771363070979821006557285101306601010780633743344773073478653881742681230743766066643312775356466578603715192922768440458273283243808212841218776132042460464900801054731426749260826922155637405486241717031027919996942645620955619816454547662045022411449404749349832206807191352767986747813458203859570413466177937228534940031631599544093684089572533438702986717829770373332806801764639502090023941931499115009105276821119510999063166150311585582835582607179410052528583611369961303442790173811787412061288182062023263849861515656451230047792967563618345768105043341769543067538041113928553792529241347339481050532025708728186307291158911335942014761872664291564036371927602306283840650425441742335464549987055318726887926424102147363698625463747159744354943443899730051742525110877357886390946812096673428152585919924857640488055071329814299359911463239919113959926752576359007446572810191805841807342227734721397723218231771716916400108826112549093361186780575722391018186168549108500885272274374212086524852372456248697662245384819298671129452945515497030585919307198497105414181636968976131126744027009648667545934567059936995464500558921628047976365686133316563907395703272034389175415267500915011198856872708848195531676931681272892143031376818016445477367518353497857924276463354162433601125960252109501612264110346083465648235597934274056868849224458745493776752120324703803035491157544831295275891939893680876327685438769557694881422844311998595700727521393176837831770339130423060958999137314684569010422095161967070506420256733873446115655276175992727151877660010238944760539789516945708802728736225121076224091810066700883474737605156285533943565843756271241244457651663064085939507947550920463932245202535463634444791755661725962187199279186575490857852950012840229035061514937310107009446151011613712423761426722541732055959202782129325725947146417224977321316381845326555279604270541871496236585252458648933254145062642337885651464670604298564781968461593663288954299780722542264790400616019751975007460545150060291806638271497016110987951336633771378434416194053121445291855180136575558667615019373029691932076120009255065081583275508499340768797252369987023567931026804136745718956641431852679054717169962990363015545645090044802789055701968328313630718997699153166679208958768572290600915472919636381673596673959975710326015571920237348580521128117458610065152598883843114511894880552129145775699146577530041384717124577965048175856395072895337539755822087777506072339445587895905719156733 .
14
15
  (5 0) :ackermann 65533 .
15
16
  } .
@@ -99,7 +99,7 @@ math:rounded a ex:Builtin ; ex:kind ex:Function ;
99
99
  rdfs:comment "Rounds subject to nearest integer (JS tie-breaking: toward +∞). Binds/unifies object with the rounded integer value." .
100
100
 
101
101
  math:exponentiation a ex:Builtin ; ex:kind ex:Function ;
102
- rdfs:comment "Exponentiation. Forward: (base exponent) -> result. Limited inverse: if base is numeric and exponent is a variable, may solve exponent via logs for positive base != 1 and positive result." .
102
+ rdfs:comment "Exponentiation. Forward: (base exponent) -> result. If both arguments are integer literals and exponent is non-negative, Eyeling uses exact BigInt exponentiation (with a safety cap on result size). Otherwise it falls back to Number exponentiation. Limited inverse: if base is numeric and exponent is a variable, may solve exponent via logs for positive base != 1 and positive result (Number mode only)." .
103
103
 
104
104
  math:absoluteValue a ex:Builtin ; ex:kind ex:Function ;
105
105
  rdfs:comment "Absolute value. Computes |s| and unifies/binds object; output datatype follows common numeric datatype selection." .
package/eyeling.js CHANGED
@@ -64,6 +64,11 @@ const __parseNumericInfoCache = new Map(); // lit string -> info|null
64
64
  // Caching them retains giant strings/BigInts in global Maps and can cause OOM.
65
65
  const MAX_NUMERIC_CACHE_KEY_LEN = 1024;
66
66
 
67
+ // Safety cap for BigInt exponentiation results.
68
+ // Prevents accidental creation of enormous integers that would OOM the process.
69
+ // (Ackermann(4,2) is ~65k bits, so well below this.)
70
+ const MAX_BIGINT_POW_RESULT_BITS = 2_000_000n;
71
+
67
72
  function __useNumericCacheKey(key) {
68
73
  return typeof key === 'string' && key.length <= MAX_NUMERIC_CACHE_KEY_LEN;
69
74
  }
@@ -603,6 +608,31 @@ function pow10n(k) {
603
608
  return 10n ** BigInt(k);
604
609
  }
605
610
 
611
+ function absBigInt(x) {
612
+ return x < 0n ? -x : x;
613
+ }
614
+
615
+ function bigintBitLength(x) {
616
+ // Returns the bit length of |x| as a BigInt (0 for 0).
617
+ const a = absBigInt(x);
618
+ if (a === 0n) return 0n;
619
+ // toString(2) is fine here: we only use this as a conservative size guard.
620
+ return BigInt(a.toString(2).length);
621
+ }
622
+
623
+ function estimatePowResultBits(base, exp) {
624
+ // Conservative estimate of bit length for |base| ** exp (exp >= 0).
625
+ // For |base| in {0,1} this is tiny; otherwise ~ exp * log2(|base|).
626
+ if (exp === 0n) return 1n;
627
+ const a = absBigInt(base);
628
+ if (a === 0n) return 1n; // 0**k (k>0) => 0
629
+ if (a === 1n) return 1n;
630
+ const bl = bigintBitLength(a);
631
+ // If bl is the bit length, then 2^(bl-1) <= a < 2^bl.
632
+ // So a^exp has < bl*exp bits and >= (bl-1)*exp+1 bits.
633
+ return (bl - 1n) * exp + 1n;
634
+ }
635
+
606
636
  // ===========================================================================
607
637
  // Time & duration builtin helpers
608
638
  // ===========================================================================
@@ -1762,50 +1792,83 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
1762
1792
  }
1763
1793
 
1764
1794
  // math:exponentiation
1795
+ // Schema: ( $base $exp ) math:exponentiation $result
1796
+ // Supports exact integer exponentiation via BigInt when both inputs are integers and exp >= 0.
1765
1797
  if (pv === MATH_NS + 'exponentiation') {
1766
- if (g.s instanceof ListTerm && g.s.elems.length === 2) {
1767
- const baseTerm = g.s.elems[0];
1768
- const expTerm = g.s.elems[1];
1798
+ if (!(g.s instanceof ListTerm) || g.s.elems.length !== 2) return [];
1799
+ const baseTerm = g.s.elems[0];
1800
+ const expTerm = g.s.elems[1];
1801
+
1802
+ // 1) Exact integer mode (BigInt): (base exponent) -> result
1803
+ // This avoids huge intermediate derivations for things like Ackermann(4,2).
1804
+ const baseI = parseIntLiteral(baseTerm);
1805
+ const expI = parseIntLiteral(expTerm);
1806
+ if (baseI !== null && expI !== null && expI >= 0n) {
1807
+ // Size guard: refuse powers that would almost certainly OOM.
1808
+ const estBits = estimatePowResultBits(baseI, expI);
1809
+ if (estBits > MAX_BIGINT_POW_RESULT_BITS) return [];
1810
+
1811
+ let out;
1812
+ try {
1813
+ out = baseI ** expI;
1814
+ } catch {
1815
+ return [];
1816
+ }
1769
1817
 
1770
- const a = parseNum(baseTerm);
1771
- let b = null;
1772
- if (a !== null) b = parseNum(expTerm);
1818
+ const lit = makeNumericOutputLiteral(out, XSD_INTEGER_DT);
1773
1819
 
1774
- // Forward mode: base and exponent are numeric
1775
- if (a !== null && b !== null) {
1776
- const cVal = a ** b;
1777
- if (!Number.isFinite(cVal)) return [];
1820
+ if (g.o instanceof Var) {
1821
+ const s2 = { ...subst };
1822
+ s2[g.o.name] = lit;
1823
+ return [s2];
1824
+ }
1825
+ if (g.o instanceof Blank) return [{ ...subst }];
1778
1826
 
1779
- let dtOut = commonNumericDatatype([baseTerm, expTerm], g.o);
1780
- if (dtOut === XSD_INTEGER_DT && !Number.isInteger(cVal)) dtOut = XSD_DECIMAL_DT;
1781
- const lit = makeNumericOutputLiteral(cVal, dtOut);
1827
+ const oi = parseIntLiteral(g.o);
1828
+ if (oi !== null && oi === out) return [{ ...subst }];
1782
1829
 
1783
- if (g.o instanceof Var) {
1784
- const s2 = { ...subst };
1785
- s2[g.o.name] = lit;
1786
- return [s2];
1787
- }
1788
- if (g.o instanceof Blank) return [{ ...subst }];
1789
- if (numEqualTerm(g.o, cVal)) return [{ ...subst }];
1830
+ const s2 = unifyTerm(g.o, lit, subst);
1831
+ return s2 !== null ? [s2] : [];
1832
+ }
1833
+
1834
+ // 2) Numeric mode (Number): forward + limited inverse
1835
+ const a = parseNum(baseTerm);
1836
+ const b = a !== null ? parseNum(expTerm) : null;
1837
+
1838
+ // Forward
1839
+ if (a !== null && b !== null) {
1840
+ const cVal = a ** b;
1841
+ if (!Number.isFinite(cVal)) return [];
1842
+
1843
+ let dtOut = commonNumericDatatype([baseTerm, expTerm], g.o);
1844
+ if (dtOut === XSD_INTEGER_DT && !Number.isInteger(cVal)) dtOut = XSD_DECIMAL_DT;
1845
+ const lit = makeNumericOutputLiteral(cVal, dtOut);
1846
+
1847
+ if (g.o instanceof Var) {
1848
+ const s2 = { ...subst };
1849
+ s2[g.o.name] = lit;
1850
+ return [s2];
1790
1851
  }
1852
+ if (g.o instanceof Blank) return [{ ...subst }];
1853
+ if (numEqualTerm(g.o, cVal)) return [{ ...subst }];
1854
+ }
1791
1855
 
1792
- // Inverse mode: solve exponent
1793
- const c = parseNum(g.o);
1794
- if (a !== null && expTerm instanceof Var && c !== null) {
1795
- if (a > 0.0 && a !== 1.0 && c > 0.0) {
1796
- const bVal = Math.log(c) / Math.log(a);
1797
- if (!Number.isFinite(bVal)) return [];
1856
+ // Inverse: solve exponent using logs (Number mode only)
1857
+ const c = parseNum(g.o);
1858
+ if (a !== null && expTerm instanceof Var && c !== null) {
1859
+ if (a > 0.0 && a !== 1.0 && c > 0.0) {
1860
+ const bVal = Math.log(c) / Math.log(a);
1861
+ if (!Number.isFinite(bVal)) return [];
1798
1862
 
1799
- let dtB = commonNumericDatatype([baseTerm, g.o], expTerm);
1800
- if (dtB === XSD_INTEGER_DT && !Number.isInteger(bVal)) dtB = XSD_DECIMAL_DT;
1863
+ let dtB = commonNumericDatatype([baseTerm, g.o], expTerm);
1864
+ if (dtB === XSD_INTEGER_DT && !Number.isInteger(bVal)) dtB = XSD_DECIMAL_DT;
1801
1865
 
1802
- const s2 = { ...subst };
1803
- s2[expTerm.name] = makeNumericOutputLiteral(bVal, dtB);
1804
- return [s2];
1805
- }
1866
+ const s2 = { ...subst };
1867
+ s2[expTerm.name] = makeNumericOutputLiteral(bVal, dtB);
1868
+ return [s2];
1806
1869
  }
1807
- return [];
1808
1870
  }
1871
+ return [];
1809
1872
  }
1810
1873
 
1811
1874
  // math:absoluteValue
@@ -3556,9 +3619,6 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
3556
3619
  // Deterministic 31-bit LCG (same as the GA demo):
3557
3620
  // state = (1103515245 * state + 12345) % 2^31
3558
3621
  // and randRound(N) = Math.round((state/2^31) * N) with state advanced once per draw.
3559
- //
3560
- // This builtin exists to keep GA-style "many samples × many characters" loops out of
3561
- // the proof search (dramatically reducing memory use).
3562
3622
  if (pv === STRING_NS + 'mutateSelectBest') {
3563
3623
  if (!(g.s instanceof ListTerm) || g.s.elems.length !== 5) return [];
3564
3624
 
package/lib/builtins.js CHANGED
@@ -52,6 +52,11 @@ const __parseNumericInfoCache = new Map(); // lit string -> info|null
52
52
  // Caching them retains giant strings/BigInts in global Maps and can cause OOM.
53
53
  const MAX_NUMERIC_CACHE_KEY_LEN = 1024;
54
54
 
55
+ // Safety cap for BigInt exponentiation results.
56
+ // Prevents accidental creation of enormous integers that would OOM the process.
57
+ // (Ackermann(4,2) is ~65k bits, so well below this.)
58
+ const MAX_BIGINT_POW_RESULT_BITS = 2_000_000n;
59
+
55
60
  function __useNumericCacheKey(key) {
56
61
  return typeof key === 'string' && key.length <= MAX_NUMERIC_CACHE_KEY_LEN;
57
62
  }
@@ -591,6 +596,31 @@ function pow10n(k) {
591
596
  return 10n ** BigInt(k);
592
597
  }
593
598
 
599
+ function absBigInt(x) {
600
+ return x < 0n ? -x : x;
601
+ }
602
+
603
+ function bigintBitLength(x) {
604
+ // Returns the bit length of |x| as a BigInt (0 for 0).
605
+ const a = absBigInt(x);
606
+ if (a === 0n) return 0n;
607
+ // toString(2) is fine here: we only use this as a conservative size guard.
608
+ return BigInt(a.toString(2).length);
609
+ }
610
+
611
+ function estimatePowResultBits(base, exp) {
612
+ // Conservative estimate of bit length for |base| ** exp (exp >= 0).
613
+ // For |base| in {0,1} this is tiny; otherwise ~ exp * log2(|base|).
614
+ if (exp === 0n) return 1n;
615
+ const a = absBigInt(base);
616
+ if (a === 0n) return 1n; // 0**k (k>0) => 0
617
+ if (a === 1n) return 1n;
618
+ const bl = bigintBitLength(a);
619
+ // If bl is the bit length, then 2^(bl-1) <= a < 2^bl.
620
+ // So a^exp has < bl*exp bits and >= (bl-1)*exp+1 bits.
621
+ return (bl - 1n) * exp + 1n;
622
+ }
623
+
594
624
  // ===========================================================================
595
625
  // Time & duration builtin helpers
596
626
  // ===========================================================================
@@ -1750,50 +1780,83 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen, maxResults) {
1750
1780
  }
1751
1781
 
1752
1782
  // math:exponentiation
1783
+ // Schema: ( $base $exp ) math:exponentiation $result
1784
+ // Supports exact integer exponentiation via BigInt when both inputs are integers and exp >= 0.
1753
1785
  if (pv === MATH_NS + 'exponentiation') {
1754
- if (g.s instanceof ListTerm && g.s.elems.length === 2) {
1755
- const baseTerm = g.s.elems[0];
1756
- const expTerm = g.s.elems[1];
1786
+ if (!(g.s instanceof ListTerm) || g.s.elems.length !== 2) return [];
1787
+ const baseTerm = g.s.elems[0];
1788
+ const expTerm = g.s.elems[1];
1789
+
1790
+ // 1) Exact integer mode (BigInt): (base exponent) -> result
1791
+ // This avoids huge intermediate derivations for things like Ackermann(4,2).
1792
+ const baseI = parseIntLiteral(baseTerm);
1793
+ const expI = parseIntLiteral(expTerm);
1794
+ if (baseI !== null && expI !== null && expI >= 0n) {
1795
+ // Size guard: refuse powers that would almost certainly OOM.
1796
+ const estBits = estimatePowResultBits(baseI, expI);
1797
+ if (estBits > MAX_BIGINT_POW_RESULT_BITS) return [];
1798
+
1799
+ let out;
1800
+ try {
1801
+ out = baseI ** expI;
1802
+ } catch {
1803
+ return [];
1804
+ }
1757
1805
 
1758
- const a = parseNum(baseTerm);
1759
- let b = null;
1760
- if (a !== null) b = parseNum(expTerm);
1806
+ const lit = makeNumericOutputLiteral(out, XSD_INTEGER_DT);
1761
1807
 
1762
- // Forward mode: base and exponent are numeric
1763
- if (a !== null && b !== null) {
1764
- const cVal = a ** b;
1765
- if (!Number.isFinite(cVal)) return [];
1808
+ if (g.o instanceof Var) {
1809
+ const s2 = { ...subst };
1810
+ s2[g.o.name] = lit;
1811
+ return [s2];
1812
+ }
1813
+ if (g.o instanceof Blank) return [{ ...subst }];
1766
1814
 
1767
- let dtOut = commonNumericDatatype([baseTerm, expTerm], g.o);
1768
- if (dtOut === XSD_INTEGER_DT && !Number.isInteger(cVal)) dtOut = XSD_DECIMAL_DT;
1769
- const lit = makeNumericOutputLiteral(cVal, dtOut);
1815
+ const oi = parseIntLiteral(g.o);
1816
+ if (oi !== null && oi === out) return [{ ...subst }];
1770
1817
 
1771
- if (g.o instanceof Var) {
1772
- const s2 = { ...subst };
1773
- s2[g.o.name] = lit;
1774
- return [s2];
1775
- }
1776
- if (g.o instanceof Blank) return [{ ...subst }];
1777
- if (numEqualTerm(g.o, cVal)) return [{ ...subst }];
1818
+ const s2 = unifyTerm(g.o, lit, subst);
1819
+ return s2 !== null ? [s2] : [];
1820
+ }
1821
+
1822
+ // 2) Numeric mode (Number): forward + limited inverse
1823
+ const a = parseNum(baseTerm);
1824
+ const b = a !== null ? parseNum(expTerm) : null;
1825
+
1826
+ // Forward
1827
+ if (a !== null && b !== null) {
1828
+ const cVal = a ** b;
1829
+ if (!Number.isFinite(cVal)) return [];
1830
+
1831
+ let dtOut = commonNumericDatatype([baseTerm, expTerm], g.o);
1832
+ if (dtOut === XSD_INTEGER_DT && !Number.isInteger(cVal)) dtOut = XSD_DECIMAL_DT;
1833
+ const lit = makeNumericOutputLiteral(cVal, dtOut);
1834
+
1835
+ if (g.o instanceof Var) {
1836
+ const s2 = { ...subst };
1837
+ s2[g.o.name] = lit;
1838
+ return [s2];
1778
1839
  }
1840
+ if (g.o instanceof Blank) return [{ ...subst }];
1841
+ if (numEqualTerm(g.o, cVal)) return [{ ...subst }];
1842
+ }
1779
1843
 
1780
- // Inverse mode: solve exponent
1781
- const c = parseNum(g.o);
1782
- if (a !== null && expTerm instanceof Var && c !== null) {
1783
- if (a > 0.0 && a !== 1.0 && c > 0.0) {
1784
- const bVal = Math.log(c) / Math.log(a);
1785
- if (!Number.isFinite(bVal)) return [];
1844
+ // Inverse: solve exponent using logs (Number mode only)
1845
+ const c = parseNum(g.o);
1846
+ if (a !== null && expTerm instanceof Var && c !== null) {
1847
+ if (a > 0.0 && a !== 1.0 && c > 0.0) {
1848
+ const bVal = Math.log(c) / Math.log(a);
1849
+ if (!Number.isFinite(bVal)) return [];
1786
1850
 
1787
- let dtB = commonNumericDatatype([baseTerm, g.o], expTerm);
1788
- if (dtB === XSD_INTEGER_DT && !Number.isInteger(bVal)) dtB = XSD_DECIMAL_DT;
1851
+ let dtB = commonNumericDatatype([baseTerm, g.o], expTerm);
1852
+ if (dtB === XSD_INTEGER_DT && !Number.isInteger(bVal)) dtB = XSD_DECIMAL_DT;
1789
1853
 
1790
- const s2 = { ...subst };
1791
- s2[expTerm.name] = makeNumericOutputLiteral(bVal, dtB);
1792
- return [s2];
1793
- }
1854
+ const s2 = { ...subst };
1855
+ s2[expTerm.name] = makeNumericOutputLiteral(bVal, dtB);
1856
+ return [s2];
1794
1857
  }
1795
- return [];
1796
1858
  }
1859
+ return [];
1797
1860
  }
1798
1861
 
1799
1862
  // math:absoluteValue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.14.1",
3
+ "version": "1.14.3",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [