isl_map.c 374 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451
  1. /*
  2. * Copyright 2008-2009 Katholieke Universiteit Leuven
  3. * Copyright 2010 INRIA Saclay
  4. * Copyright 2012-2014 Ecole Normale Superieure
  5. * Copyright 2014 INRIA Rocquencourt
  6. * Copyright 2016 INRIA Paris
  7. * Copyright 2016 Sven Verdoolaege
  8. * Copyright 2018-2019 Cerebras Systems
  9. *
  10. * Use of this software is governed by the MIT license
  11. *
  12. * Written by Sven Verdoolaege, K.U.Leuven, Departement
  13. * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
  14. * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
  15. * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
  16. * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
  17. * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
  18. * B.P. 105 - 78153 Le Chesnay, France
  19. * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
  20. * CS 42112, 75589 Paris Cedex 12, France
  21. * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
  22. */
  23. #include <string.h>
  24. #include <isl_ctx_private.h>
  25. #include <isl_map_private.h>
  26. #include <isl_blk.h>
  27. #include <isl_id_private.h>
  28. #include <isl/constraint.h>
  29. #include "isl_space_private.h"
  30. #include "isl_equalities.h"
  31. #include <isl_lp_private.h>
  32. #include <isl_seq.h>
  33. #include <isl/set.h>
  34. #include <isl/map.h>
  35. #include <isl_reordering.h>
  36. #include "isl_sample.h"
  37. #include <isl_sort.h>
  38. #include "isl_tab.h"
  39. #include <isl/vec.h>
  40. #include <isl_mat_private.h>
  41. #include <isl_vec_private.h>
  42. #include <isl_dim_map.h>
  43. #include <isl_local_space_private.h>
  44. #include <isl_aff_private.h>
  45. #include <isl_options_private.h>
  46. #include <isl_morph.h>
  47. #include <isl_val_private.h>
  48. #include <isl_printer_private.h>
  49. #include <bset_to_bmap.c>
  50. #include <bset_from_bmap.c>
  51. #include <set_to_map.c>
  52. #include <set_from_map.c>
  53. /* Treat "bset" as a basic map.
  54. * Internally, isl_basic_set is defined to isl_basic_map, so in practice,
  55. * this function performs a redundant cast.
  56. */
  57. static __isl_keep const isl_basic_map *const_bset_to_bmap(
  58. __isl_keep const isl_basic_set *bset)
  59. {
  60. return (const isl_basic_map *) bset;
  61. }
  62. #undef TYPE
  63. #define TYPE isl_basic_map
  64. #include "has_single_reference_templ.c"
  65. static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
  66. {
  67. switch (type) {
  68. case isl_dim_param: return 1;
  69. case isl_dim_in: return 1 + space->nparam;
  70. case isl_dim_out: return 1 + space->nparam + space->n_in;
  71. default: return 0;
  72. }
  73. }
  74. isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
  75. enum isl_dim_type type)
  76. {
  77. if (!bmap)
  78. return isl_size_error;
  79. switch (type) {
  80. case isl_dim_cst: return 1;
  81. case isl_dim_param:
  82. case isl_dim_in:
  83. case isl_dim_out: return isl_space_dim(bmap->dim, type);
  84. case isl_dim_div: return bmap->n_div;
  85. case isl_dim_all: return isl_basic_map_total_dim(bmap);
  86. default: return 0;
  87. }
  88. }
  89. /* Return the space of "map".
  90. */
  91. __isl_keep isl_space *isl_map_peek_space(__isl_keep const isl_map *map)
  92. {
  93. return map ? map->dim : NULL;
  94. }
  95. /* Return the space of "set".
  96. */
  97. __isl_keep isl_space *isl_set_peek_space(__isl_keep isl_set *set)
  98. {
  99. return isl_map_peek_space(set_to_map(set));
  100. }
  101. isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
  102. {
  103. return isl_space_dim(isl_map_peek_space(map), type);
  104. }
  105. /* Return the dimensionality of the domain (tuple) of the map.
  106. */
  107. isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map)
  108. {
  109. return isl_map_dim(map, isl_dim_in);
  110. }
  111. /* Return the dimensionality of the range (tuple) of the map.
  112. */
  113. isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map)
  114. {
  115. return isl_map_dim(map, isl_dim_out);
  116. }
  117. isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type)
  118. {
  119. return isl_map_dim(set_to_map(set), type);
  120. }
  121. /* Return the dimensionality of the (tuple of the) set.
  122. */
  123. isl_size isl_set_tuple_dim(__isl_keep isl_set *set)
  124. {
  125. return isl_set_dim(set, isl_dim_set);
  126. }
  127. /* Return the position of the variables of the given type
  128. * within the sequence of variables of "bmap".
  129. */
  130. isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap,
  131. enum isl_dim_type type)
  132. {
  133. isl_space *space;
  134. space = isl_basic_map_peek_space(bmap);
  135. if (!space)
  136. return isl_size_error;
  137. switch (type) {
  138. case isl_dim_param:
  139. case isl_dim_in:
  140. case isl_dim_out: return isl_space_offset(space, type);
  141. case isl_dim_div: return isl_space_dim(space, isl_dim_all);
  142. case isl_dim_cst:
  143. default:
  144. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  145. "invalid dimension type", return isl_size_error);
  146. }
  147. }
  148. /* Return the position of the variables of the given type
  149. * within the sequence of variables of "bset".
  150. */
  151. isl_size isl_basic_set_var_offset(__isl_keep isl_basic_set *bset,
  152. enum isl_dim_type type)
  153. {
  154. return isl_basic_map_var_offset(bset_to_bmap(bset), type);
  155. }
  156. /* Return the position of the coefficients of the variables of the given type
  157. * within the sequence of coefficients of "bmap".
  158. */
  159. unsigned isl_basic_map_offset(__isl_keep isl_basic_map *bmap,
  160. enum isl_dim_type type)
  161. {
  162. switch (type) {
  163. case isl_dim_cst: return 0;
  164. case isl_dim_param:
  165. case isl_dim_in:
  166. case isl_dim_out:
  167. case isl_dim_div: return 1 + isl_basic_map_var_offset(bmap, type);
  168. default: return 0;
  169. }
  170. }
  171. unsigned isl_basic_set_offset(__isl_keep isl_basic_set *bset,
  172. enum isl_dim_type type)
  173. {
  174. return isl_basic_map_offset(bset, type);
  175. }
  176. static unsigned map_offset(__isl_keep isl_map *map, enum isl_dim_type type)
  177. {
  178. return pos(map->dim, type);
  179. }
  180. isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset,
  181. enum isl_dim_type type)
  182. {
  183. return isl_basic_map_dim(bset, type);
  184. }
  185. isl_size isl_basic_set_n_dim(__isl_keep isl_basic_set *bset)
  186. {
  187. return isl_basic_set_dim(bset, isl_dim_set);
  188. }
  189. isl_size isl_basic_set_n_param(__isl_keep isl_basic_set *bset)
  190. {
  191. return isl_basic_set_dim(bset, isl_dim_param);
  192. }
  193. isl_size isl_basic_set_total_dim(__isl_keep const isl_basic_set *bset)
  194. {
  195. return isl_basic_map_total_dim(const_bset_to_bmap(bset));
  196. }
  197. isl_size isl_set_n_dim(__isl_keep isl_set *set)
  198. {
  199. return isl_set_dim(set, isl_dim_set);
  200. }
  201. isl_size isl_set_n_param(__isl_keep isl_set *set)
  202. {
  203. return isl_set_dim(set, isl_dim_param);
  204. }
  205. isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap)
  206. {
  207. isl_size dim;
  208. if (!bmap)
  209. return isl_size_error;
  210. dim = isl_space_dim(bmap->dim, isl_dim_all);
  211. if (dim < 0)
  212. return isl_size_error;
  213. return dim + bmap->n_div;
  214. }
  215. /* Return the number of equality constraints in the description of "bmap".
  216. * Return isl_size_error on error.
  217. */
  218. isl_size isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap)
  219. {
  220. if (!bmap)
  221. return isl_size_error;
  222. return bmap->n_eq;
  223. }
  224. /* Return the number of equality constraints in the description of "bset".
  225. * Return isl_size_error on error.
  226. */
  227. isl_size isl_basic_set_n_equality(__isl_keep isl_basic_set *bset)
  228. {
  229. return isl_basic_map_n_equality(bset_to_bmap(bset));
  230. }
  231. /* Return the number of inequality constraints in the description of "bmap".
  232. * Return isl_size_error on error.
  233. */
  234. isl_size isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap)
  235. {
  236. if (!bmap)
  237. return isl_size_error;
  238. return bmap->n_ineq;
  239. }
  240. /* Return the number of inequality constraints in the description of "bset".
  241. * Return isl_size_error on error.
  242. */
  243. isl_size isl_basic_set_n_inequality(__isl_keep isl_basic_set *bset)
  244. {
  245. return isl_basic_map_n_inequality(bset_to_bmap(bset));
  246. }
  247. /* Do "bmap1" and "bmap2" have the same parameters?
  248. */
  249. static isl_bool isl_basic_map_has_equal_params(__isl_keep isl_basic_map *bmap1,
  250. __isl_keep isl_basic_map *bmap2)
  251. {
  252. isl_space *space1, *space2;
  253. space1 = isl_basic_map_peek_space(bmap1);
  254. space2 = isl_basic_map_peek_space(bmap2);
  255. return isl_space_has_equal_params(space1, space2);
  256. }
  257. /* Do "map1" and "map2" have the same parameters?
  258. */
  259. isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1,
  260. __isl_keep isl_map *map2)
  261. {
  262. isl_space *space1, *space2;
  263. space1 = isl_map_peek_space(map1);
  264. space2 = isl_map_peek_space(map2);
  265. return isl_space_has_equal_params(space1, space2);
  266. }
  267. /* Do "map" and "set" have the same parameters?
  268. */
  269. static isl_bool isl_map_set_has_equal_params(__isl_keep isl_map *map,
  270. __isl_keep isl_set *set)
  271. {
  272. return isl_map_has_equal_params(map, set_to_map(set));
  273. }
  274. /* Is the tuple of type "type" of "bmap" the same as the single tuple of "bset"?
  275. */
  276. static isl_bool isl_basic_map_set_tuple_is_equal(__isl_keep isl_basic_map *bmap,
  277. enum isl_dim_type type, __isl_keep isl_basic_set *bset)
  278. {
  279. isl_space *bmap_space, *bset_space;
  280. bmap_space = isl_basic_map_peek_space(bmap);
  281. bset_space = isl_basic_set_peek_space(bset);
  282. return isl_space_tuple_is_equal(bmap_space, type,
  283. bset_space, isl_dim_set);
  284. }
  285. /* Is the tuple of type "type" of "map" the same as the single tuple of "set"?
  286. */
  287. static isl_bool isl_map_set_tuple_is_equal(__isl_keep isl_map *map,
  288. enum isl_dim_type type, __isl_keep isl_set *set)
  289. {
  290. return isl_map_tuple_is_equal(map, type, set_to_map(set), isl_dim_set);
  291. }
  292. isl_bool isl_map_compatible_domain(__isl_keep isl_map *map,
  293. __isl_keep isl_set *set)
  294. {
  295. isl_bool m;
  296. if (!map || !set)
  297. return isl_bool_error;
  298. m = isl_map_has_equal_params(map, set_to_map(set));
  299. if (m < 0 || !m)
  300. return m;
  301. return isl_map_set_tuple_is_equal(map, isl_dim_in, set);
  302. }
  303. isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap,
  304. __isl_keep isl_basic_set *bset)
  305. {
  306. isl_bool m;
  307. if (!bmap || !bset)
  308. return isl_bool_error;
  309. m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
  310. if (m < 0 || !m)
  311. return m;
  312. return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_in, bset);
  313. }
  314. isl_bool isl_map_compatible_range(__isl_keep isl_map *map,
  315. __isl_keep isl_set *set)
  316. {
  317. isl_bool m;
  318. if (!map || !set)
  319. return isl_bool_error;
  320. m = isl_map_has_equal_params(map, set_to_map(set));
  321. if (m < 0 || !m)
  322. return m;
  323. return isl_map_set_tuple_is_equal(map, isl_dim_out, set);
  324. }
  325. isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap,
  326. __isl_keep isl_basic_set *bset)
  327. {
  328. isl_bool m;
  329. if (!bmap || !bset)
  330. return isl_bool_error;
  331. m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
  332. if (m < 0 || !m)
  333. return m;
  334. return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_out, bset);
  335. }
  336. isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
  337. {
  338. return bmap ? bmap->ctx : NULL;
  339. }
  340. isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset)
  341. {
  342. return bset ? bset->ctx : NULL;
  343. }
  344. isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
  345. {
  346. return map ? map->ctx : NULL;
  347. }
  348. isl_ctx *isl_set_get_ctx(__isl_keep isl_set *set)
  349. {
  350. return set ? set->ctx : NULL;
  351. }
  352. /* Return the space of "bmap".
  353. */
  354. __isl_keep isl_space *isl_basic_map_peek_space(
  355. __isl_keep const isl_basic_map *bmap)
  356. {
  357. return bmap ? bmap->dim : NULL;
  358. }
  359. /* Return the space of "bset".
  360. */
  361. __isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_set *bset)
  362. {
  363. return isl_basic_map_peek_space(bset_to_bmap(bset));
  364. }
  365. __isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap)
  366. {
  367. return isl_space_copy(isl_basic_map_peek_space(bmap));
  368. }
  369. __isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_set *bset)
  370. {
  371. return isl_basic_map_get_space(bset_to_bmap(bset));
  372. }
  373. /* Return the space of "bmap".
  374. * This may be either a copy or the space itself
  375. * if there is only one reference to "bmap".
  376. * This allows the space to be modified inplace
  377. * if both the basic map and its space have only a single reference.
  378. * The caller is not allowed to modify "bmap" between this call and
  379. * a subsequent call to isl_basic_map_restore_space.
  380. * The only exception is that isl_basic_map_free can be called instead.
  381. */
  382. static __isl_give isl_space *isl_basic_map_take_space(
  383. __isl_keep isl_basic_map *bmap)
  384. {
  385. isl_space *space;
  386. if (!bmap)
  387. return NULL;
  388. if (bmap->ref != 1)
  389. return isl_basic_map_get_space(bmap);
  390. space = bmap->dim;
  391. bmap->dim = NULL;
  392. return space;
  393. }
  394. /* Set the space of "bmap" to "space", where the space of "bmap" may be missing
  395. * due to a preceding call to isl_basic_map_take_space.
  396. * However, in this case, "bmap" only has a single reference and
  397. * then the call to isl_basic_map_cow has no effect.
  398. */
  399. static __isl_give isl_basic_map *isl_basic_map_restore_space(
  400. __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
  401. {
  402. if (!bmap || !space)
  403. goto error;
  404. if (bmap->dim == space) {
  405. isl_space_free(space);
  406. return bmap;
  407. }
  408. bmap = isl_basic_map_cow(bmap);
  409. if (!bmap)
  410. goto error;
  411. isl_space_free(bmap->dim);
  412. bmap->dim = space;
  413. return bmap;
  414. error:
  415. isl_basic_map_free(bmap);
  416. isl_space_free(space);
  417. return NULL;
  418. }
  419. /* Extract the divs in "bmap" as a matrix.
  420. */
  421. __isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap)
  422. {
  423. int i;
  424. isl_ctx *ctx;
  425. isl_mat *div;
  426. isl_size v_div;
  427. unsigned cols;
  428. v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
  429. if (v_div < 0)
  430. return NULL;
  431. ctx = isl_basic_map_get_ctx(bmap);
  432. cols = 1 + 1 + v_div + bmap->n_div;
  433. div = isl_mat_alloc(ctx, bmap->n_div, cols);
  434. if (!div)
  435. return NULL;
  436. for (i = 0; i < bmap->n_div; ++i)
  437. isl_seq_cpy(div->row[i], bmap->div[i], cols);
  438. return div;
  439. }
  440. /* Extract the divs in "bset" as a matrix.
  441. */
  442. __isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_set *bset)
  443. {
  444. return isl_basic_map_get_divs(bset);
  445. }
  446. __isl_give isl_local_space *isl_basic_map_get_local_space(
  447. __isl_keep isl_basic_map *bmap)
  448. {
  449. isl_mat *div;
  450. if (!bmap)
  451. return NULL;
  452. div = isl_basic_map_get_divs(bmap);
  453. return isl_local_space_alloc_div(isl_space_copy(bmap->dim), div);
  454. }
  455. __isl_give isl_local_space *isl_basic_set_get_local_space(
  456. __isl_keep isl_basic_set *bset)
  457. {
  458. return isl_basic_map_get_local_space(bset);
  459. }
  460. /* For each known div d = floor(f/m), add the constraints
  461. *
  462. * f - m d >= 0
  463. * -(f-(m-1)) + m d >= 0
  464. *
  465. * Do not finalize the result.
  466. */
  467. static __isl_give isl_basic_map *add_known_div_constraints(
  468. __isl_take isl_basic_map *bmap)
  469. {
  470. int i;
  471. isl_size n_div;
  472. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  473. if (n_div < 0)
  474. return isl_basic_map_free(bmap);
  475. if (n_div == 0)
  476. return bmap;
  477. bmap = isl_basic_map_cow(bmap);
  478. bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div);
  479. if (!bmap)
  480. return NULL;
  481. for (i = 0; i < n_div; ++i) {
  482. if (isl_int_is_zero(bmap->div[i][0]))
  483. continue;
  484. bmap = isl_basic_map_add_div_constraints(bmap, i);
  485. }
  486. return bmap;
  487. }
  488. __isl_give isl_basic_map *isl_basic_map_from_local_space(
  489. __isl_take isl_local_space *ls)
  490. {
  491. int i;
  492. isl_size n_div;
  493. isl_basic_map *bmap;
  494. n_div = isl_local_space_dim(ls, isl_dim_div);
  495. if (n_div < 0)
  496. ls = isl_local_space_free(ls);
  497. if (!ls)
  498. return NULL;
  499. bmap = isl_basic_map_alloc_space(isl_local_space_get_space(ls),
  500. n_div, 0, 2 * n_div);
  501. for (i = 0; i < n_div; ++i)
  502. if (isl_basic_map_alloc_div(bmap) < 0)
  503. goto error;
  504. for (i = 0; i < n_div; ++i)
  505. isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
  506. bmap = add_known_div_constraints(bmap);
  507. isl_local_space_free(ls);
  508. return bmap;
  509. error:
  510. isl_local_space_free(ls);
  511. isl_basic_map_free(bmap);
  512. return NULL;
  513. }
  514. __isl_give isl_basic_set *isl_basic_set_from_local_space(
  515. __isl_take isl_local_space *ls)
  516. {
  517. return isl_basic_map_from_local_space(ls);
  518. }
  519. __isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map)
  520. {
  521. return isl_space_copy(isl_map_peek_space(map));
  522. }
  523. __isl_give isl_space *isl_set_get_space(__isl_keep isl_set *set)
  524. {
  525. if (!set)
  526. return NULL;
  527. return isl_space_copy(set->dim);
  528. }
  529. /* Return the space of "map".
  530. * This may be either a copy or the space itself
  531. * if there is only one reference to "map".
  532. * This allows the space to be modified inplace
  533. * if both the map and its space have only a single reference.
  534. * The caller is not allowed to modify "map" between this call and
  535. * a subsequent call to isl_map_restore_space.
  536. * The only exception is that isl_map_free can be called instead.
  537. */
  538. static __isl_give isl_space *isl_map_take_space(__isl_keep isl_map *map)
  539. {
  540. isl_space *space;
  541. if (!map)
  542. return NULL;
  543. if (map->ref != 1)
  544. return isl_map_get_space(map);
  545. space = map->dim;
  546. map->dim = NULL;
  547. return space;
  548. }
  549. /* Set the space of "map" to "space", where the space of "map" may be missing
  550. * due to a preceding call to isl_map_take_space.
  551. * However, in this case, "map" only has a single reference and
  552. * then the call to isl_map_cow has no effect.
  553. */
  554. static __isl_give isl_map *isl_map_restore_space(__isl_take isl_map *map,
  555. __isl_take isl_space *space)
  556. {
  557. if (!map || !space)
  558. goto error;
  559. if (map->dim == space) {
  560. isl_space_free(space);
  561. return map;
  562. }
  563. map = isl_map_cow(map);
  564. if (!map)
  565. goto error;
  566. isl_space_free(map->dim);
  567. map->dim = space;
  568. return map;
  569. error:
  570. isl_map_free(map);
  571. isl_space_free(space);
  572. return NULL;
  573. }
  574. __isl_give isl_basic_map *isl_basic_map_set_tuple_name(
  575. __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
  576. {
  577. isl_space *space;
  578. space = isl_basic_map_take_space(bmap);
  579. space = isl_space_set_tuple_name(space, type, s);
  580. bmap = isl_basic_map_restore_space(bmap, space);
  581. bmap = isl_basic_map_finalize(bmap);
  582. return bmap;
  583. }
  584. __isl_give isl_basic_set *isl_basic_set_set_tuple_name(
  585. __isl_take isl_basic_set *bset, const char *s)
  586. {
  587. return isl_basic_map_set_tuple_name(bset, isl_dim_set, s);
  588. }
  589. const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap,
  590. enum isl_dim_type type)
  591. {
  592. return bmap ? isl_space_get_tuple_name(bmap->dim, type) : NULL;
  593. }
  594. __isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
  595. enum isl_dim_type type, const char *s)
  596. {
  597. int i;
  598. isl_space *space;
  599. map = isl_map_cow(map);
  600. if (!map)
  601. return NULL;
  602. for (i = 0; i < map->n; ++i) {
  603. map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
  604. if (!map->p[i])
  605. goto error;
  606. }
  607. space = isl_map_take_space(map);
  608. space = isl_space_set_tuple_name(space, type, s);
  609. map = isl_map_restore_space(map, space);
  610. return map;
  611. error:
  612. isl_map_free(map);
  613. return NULL;
  614. }
  615. /* Replace the identifier of the tuple of type "type" by "id".
  616. */
  617. __isl_give isl_basic_map *isl_basic_map_set_tuple_id(
  618. __isl_take isl_basic_map *bmap,
  619. enum isl_dim_type type, __isl_take isl_id *id)
  620. {
  621. isl_space *space;
  622. space = isl_basic_map_take_space(bmap);
  623. space = isl_space_set_tuple_id(space, type, id);
  624. bmap = isl_basic_map_restore_space(bmap, space);
  625. bmap = isl_basic_map_finalize(bmap);
  626. return bmap;
  627. }
  628. /* Replace the identifier of the tuple by "id".
  629. */
  630. __isl_give isl_basic_set *isl_basic_set_set_tuple_id(
  631. __isl_take isl_basic_set *bset, __isl_take isl_id *id)
  632. {
  633. return isl_basic_map_set_tuple_id(bset, isl_dim_set, id);
  634. }
  635. /* Does the input or output tuple have a name?
  636. */
  637. isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type)
  638. {
  639. return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error;
  640. }
  641. const char *isl_map_get_tuple_name(__isl_keep isl_map *map,
  642. enum isl_dim_type type)
  643. {
  644. return map ? isl_space_get_tuple_name(map->dim, type) : NULL;
  645. }
  646. __isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set,
  647. const char *s)
  648. {
  649. return set_from_map(isl_map_set_tuple_name(set_to_map(set),
  650. isl_dim_set, s));
  651. }
  652. __isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
  653. enum isl_dim_type type, __isl_take isl_id *id)
  654. {
  655. isl_space *space;
  656. space = isl_map_take_space(map);
  657. space = isl_space_set_tuple_id(space, type, id);
  658. map = isl_map_restore_space(map, space);
  659. return isl_map_reset_space(map, isl_map_get_space(map));
  660. }
  661. /* Replace the identifier of the domain tuple of "map" by "id".
  662. */
  663. __isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map,
  664. __isl_take isl_id *id)
  665. {
  666. return isl_map_set_tuple_id(map, isl_dim_in, id);
  667. }
  668. /* Replace the identifier of the range tuple of "map" by "id".
  669. */
  670. __isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map,
  671. __isl_take isl_id *id)
  672. {
  673. return isl_map_set_tuple_id(map, isl_dim_out, id);
  674. }
  675. __isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set,
  676. __isl_take isl_id *id)
  677. {
  678. return isl_map_set_tuple_id(set, isl_dim_set, id);
  679. }
  680. __isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map,
  681. enum isl_dim_type type)
  682. {
  683. isl_space *space;
  684. space = isl_map_take_space(map);
  685. space = isl_space_reset_tuple_id(space, type);
  686. map = isl_map_restore_space(map, space);
  687. return isl_map_reset_space(map, isl_map_get_space(map));
  688. }
  689. __isl_give isl_set *isl_set_reset_tuple_id(__isl_take isl_set *set)
  690. {
  691. return isl_map_reset_tuple_id(set, isl_dim_set);
  692. }
  693. isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type)
  694. {
  695. return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error;
  696. }
  697. /* Does the domain tuple of "map" have an identifier?
  698. */
  699. isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map)
  700. {
  701. return isl_map_has_tuple_id(map, isl_dim_in);
  702. }
  703. /* Does the range tuple of "map" have an identifier?
  704. */
  705. isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map)
  706. {
  707. return isl_map_has_tuple_id(map, isl_dim_out);
  708. }
  709. __isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
  710. enum isl_dim_type type)
  711. {
  712. return map ? isl_space_get_tuple_id(map->dim, type) : NULL;
  713. }
  714. /* Return the identifier of the domain tuple of "map", assuming it has one.
  715. */
  716. __isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map)
  717. {
  718. return isl_map_get_tuple_id(map, isl_dim_in);
  719. }
  720. /* Return the identifier of the range tuple of "map", assuming it has one.
  721. */
  722. __isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map)
  723. {
  724. return isl_map_get_tuple_id(map, isl_dim_out);
  725. }
  726. isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set)
  727. {
  728. return isl_map_has_tuple_id(set, isl_dim_set);
  729. }
  730. __isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set)
  731. {
  732. return isl_map_get_tuple_id(set, isl_dim_set);
  733. }
  734. /* Does the set tuple have a name?
  735. */
  736. isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set)
  737. {
  738. if (!set)
  739. return isl_bool_error;
  740. return isl_space_has_tuple_name(set->dim, isl_dim_set);
  741. }
  742. const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset)
  743. {
  744. return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL;
  745. }
  746. const char *isl_set_get_tuple_name(__isl_keep isl_set *set)
  747. {
  748. return set ? isl_space_get_tuple_name(set->dim, isl_dim_set) : NULL;
  749. }
  750. const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap,
  751. enum isl_dim_type type, unsigned pos)
  752. {
  753. return bmap ? isl_space_get_dim_name(bmap->dim, type, pos) : NULL;
  754. }
  755. const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set *bset,
  756. enum isl_dim_type type, unsigned pos)
  757. {
  758. return bset ? isl_space_get_dim_name(bset->dim, type, pos) : NULL;
  759. }
  760. /* Does the given dimension have a name?
  761. */
  762. isl_bool isl_map_has_dim_name(__isl_keep isl_map *map,
  763. enum isl_dim_type type, unsigned pos)
  764. {
  765. if (!map)
  766. return isl_bool_error;
  767. return isl_space_has_dim_name(map->dim, type, pos);
  768. }
  769. const char *isl_map_get_dim_name(__isl_keep isl_map *map,
  770. enum isl_dim_type type, unsigned pos)
  771. {
  772. return map ? isl_space_get_dim_name(map->dim, type, pos) : NULL;
  773. }
  774. const char *isl_set_get_dim_name(__isl_keep isl_set *set,
  775. enum isl_dim_type type, unsigned pos)
  776. {
  777. return set ? isl_space_get_dim_name(set->dim, type, pos) : NULL;
  778. }
  779. /* Does the given dimension have a name?
  780. */
  781. isl_bool isl_set_has_dim_name(__isl_keep isl_set *set,
  782. enum isl_dim_type type, unsigned pos)
  783. {
  784. if (!set)
  785. return isl_bool_error;
  786. return isl_space_has_dim_name(set->dim, type, pos);
  787. }
  788. __isl_give isl_basic_map *isl_basic_map_set_dim_name(
  789. __isl_take isl_basic_map *bmap,
  790. enum isl_dim_type type, unsigned pos, const char *s)
  791. {
  792. isl_space *space;
  793. space = isl_basic_map_take_space(bmap);
  794. space = isl_space_set_dim_name(space, type, pos, s);
  795. bmap = isl_basic_map_restore_space(bmap, space);
  796. return isl_basic_map_finalize(bmap);
  797. }
  798. __isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
  799. enum isl_dim_type type, unsigned pos, const char *s)
  800. {
  801. int i;
  802. isl_space *space;
  803. map = isl_map_cow(map);
  804. if (!map)
  805. return NULL;
  806. for (i = 0; i < map->n; ++i) {
  807. map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
  808. if (!map->p[i])
  809. goto error;
  810. }
  811. space = isl_map_take_space(map);
  812. space = isl_space_set_dim_name(space, type, pos, s);
  813. map = isl_map_restore_space(map, space);
  814. return map;
  815. error:
  816. isl_map_free(map);
  817. return NULL;
  818. }
  819. __isl_give isl_basic_set *isl_basic_set_set_dim_name(
  820. __isl_take isl_basic_set *bset,
  821. enum isl_dim_type type, unsigned pos, const char *s)
  822. {
  823. return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset),
  824. type, pos, s));
  825. }
  826. __isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set,
  827. enum isl_dim_type type, unsigned pos, const char *s)
  828. {
  829. return set_from_map(isl_map_set_dim_name(set_to_map(set),
  830. type, pos, s));
  831. }
  832. isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
  833. enum isl_dim_type type, unsigned pos)
  834. {
  835. if (!bmap)
  836. return isl_bool_error;
  837. return isl_space_has_dim_id(bmap->dim, type, pos);
  838. }
  839. __isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset,
  840. enum isl_dim_type type, unsigned pos)
  841. {
  842. return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL;
  843. }
  844. isl_bool isl_map_has_dim_id(__isl_keep isl_map *map,
  845. enum isl_dim_type type, unsigned pos)
  846. {
  847. return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error;
  848. }
  849. __isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map,
  850. enum isl_dim_type type, unsigned pos)
  851. {
  852. return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL;
  853. }
  854. isl_bool isl_set_has_dim_id(__isl_keep isl_set *set,
  855. enum isl_dim_type type, unsigned pos)
  856. {
  857. return isl_map_has_dim_id(set, type, pos);
  858. }
  859. __isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_set *set,
  860. enum isl_dim_type type, unsigned pos)
  861. {
  862. return isl_map_get_dim_id(set, type, pos);
  863. }
  864. __isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map,
  865. enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
  866. {
  867. isl_space *space;
  868. space = isl_map_take_space(map);
  869. space = isl_space_set_dim_id(space, type, pos, id);
  870. map = isl_map_restore_space(map, space);
  871. return isl_map_reset_space(map, isl_map_get_space(map));
  872. }
  873. __isl_give isl_set *isl_set_set_dim_id(__isl_take isl_set *set,
  874. enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
  875. {
  876. return isl_map_set_dim_id(set, type, pos, id);
  877. }
  878. int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type,
  879. __isl_keep isl_id *id)
  880. {
  881. if (!map)
  882. return -1;
  883. return isl_space_find_dim_by_id(map->dim, type, id);
  884. }
  885. int isl_set_find_dim_by_id(__isl_keep isl_set *set, enum isl_dim_type type,
  886. __isl_keep isl_id *id)
  887. {
  888. return isl_map_find_dim_by_id(set, type, id);
  889. }
  890. /* Return the position of the dimension of the given type and name
  891. * in "bmap".
  892. * Return -1 if no such dimension can be found.
  893. */
  894. int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap,
  895. enum isl_dim_type type, const char *name)
  896. {
  897. if (!bmap)
  898. return -1;
  899. return isl_space_find_dim_by_name(bmap->dim, type, name);
  900. }
  901. int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type,
  902. const char *name)
  903. {
  904. if (!map)
  905. return -1;
  906. return isl_space_find_dim_by_name(map->dim, type, name);
  907. }
  908. int isl_set_find_dim_by_name(__isl_keep isl_set *set, enum isl_dim_type type,
  909. const char *name)
  910. {
  911. return isl_map_find_dim_by_name(set, type, name);
  912. }
  913. /* Check whether equality i of bset is a pure stride constraint
  914. * on a single dimension, i.e., of the form
  915. *
  916. * v = k e
  917. *
  918. * with k a constant and e an existentially quantified variable.
  919. */
  920. isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_set *bset, int i)
  921. {
  922. isl_size nparam;
  923. isl_size d;
  924. isl_size n_div;
  925. int pos1;
  926. int pos2;
  927. nparam = isl_basic_set_dim(bset, isl_dim_param);
  928. d = isl_basic_set_dim(bset, isl_dim_set);
  929. n_div = isl_basic_set_dim(bset, isl_dim_div);
  930. if (nparam < 0 || d < 0 || n_div < 0)
  931. return isl_bool_error;
  932. if (!isl_int_is_zero(bset->eq[i][0]))
  933. return isl_bool_false;
  934. if (isl_seq_first_non_zero(bset->eq[i] + 1, nparam) != -1)
  935. return isl_bool_false;
  936. pos1 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam, d);
  937. if (pos1 == -1)
  938. return isl_bool_false;
  939. if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + pos1 + 1,
  940. d - pos1 - 1) != -1)
  941. return isl_bool_false;
  942. pos2 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d, n_div);
  943. if (pos2 == -1)
  944. return isl_bool_false;
  945. if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d + pos2 + 1,
  946. n_div - pos2 - 1) != -1)
  947. return isl_bool_false;
  948. if (!isl_int_is_one(bset->eq[i][1 + nparam + pos1]) &&
  949. !isl_int_is_negone(bset->eq[i][1 + nparam + pos1]))
  950. return isl_bool_false;
  951. return isl_bool_true;
  952. }
  953. /* Reset the user pointer on all identifiers of parameters and tuples
  954. * of the space of "map".
  955. */
  956. __isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map)
  957. {
  958. isl_space *space;
  959. space = isl_map_get_space(map);
  960. space = isl_space_reset_user(space);
  961. map = isl_map_reset_space(map, space);
  962. return map;
  963. }
  964. /* Reset the user pointer on all identifiers of parameters and tuples
  965. * of the space of "set".
  966. */
  967. __isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set)
  968. {
  969. return isl_map_reset_user(set);
  970. }
  971. isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
  972. {
  973. if (!bmap)
  974. return isl_bool_error;
  975. return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
  976. }
  977. /* Has "map" been marked as a rational map?
  978. * In particular, have all basic maps in "map" been marked this way?
  979. * An empty map is not considered to be rational.
  980. * Maps where only some of the basic maps are marked rational
  981. * are not allowed.
  982. */
  983. isl_bool isl_map_is_rational(__isl_keep isl_map *map)
  984. {
  985. int i;
  986. isl_bool rational;
  987. if (!map)
  988. return isl_bool_error;
  989. if (map->n == 0)
  990. return isl_bool_false;
  991. rational = isl_basic_map_is_rational(map->p[0]);
  992. if (rational < 0)
  993. return rational;
  994. for (i = 1; i < map->n; ++i) {
  995. isl_bool rational_i;
  996. rational_i = isl_basic_map_is_rational(map->p[i]);
  997. if (rational_i < 0)
  998. return rational_i;
  999. if (rational != rational_i)
  1000. isl_die(isl_map_get_ctx(map), isl_error_unsupported,
  1001. "mixed rational and integer basic maps "
  1002. "not supported", return isl_bool_error);
  1003. }
  1004. return rational;
  1005. }
  1006. /* Has "set" been marked as a rational set?
  1007. * In particular, have all basic set in "set" been marked this way?
  1008. * An empty set is not considered to be rational.
  1009. * Sets where only some of the basic sets are marked rational
  1010. * are not allowed.
  1011. */
  1012. isl_bool isl_set_is_rational(__isl_keep isl_set *set)
  1013. {
  1014. return isl_map_is_rational(set);
  1015. }
  1016. int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset)
  1017. {
  1018. return isl_basic_map_is_rational(bset);
  1019. }
  1020. /* Does "bmap" contain any rational points?
  1021. *
  1022. * If "bmap" has an equality for each dimension, equating the dimension
  1023. * to an integer constant, then it has no rational points, even if it
  1024. * is marked as rational.
  1025. */
  1026. isl_bool isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap)
  1027. {
  1028. isl_bool has_rational = isl_bool_true;
  1029. isl_size total;
  1030. if (!bmap)
  1031. return isl_bool_error;
  1032. if (isl_basic_map_plain_is_empty(bmap))
  1033. return isl_bool_false;
  1034. if (!isl_basic_map_is_rational(bmap))
  1035. return isl_bool_false;
  1036. bmap = isl_basic_map_copy(bmap);
  1037. bmap = isl_basic_map_implicit_equalities(bmap);
  1038. total = isl_basic_map_dim(bmap, isl_dim_all);
  1039. if (total < 0)
  1040. return isl_bool_error;
  1041. if (bmap->n_eq == total) {
  1042. int i, j;
  1043. for (i = 0; i < bmap->n_eq; ++i) {
  1044. j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
  1045. if (j < 0)
  1046. break;
  1047. if (!isl_int_is_one(bmap->eq[i][1 + j]) &&
  1048. !isl_int_is_negone(bmap->eq[i][1 + j]))
  1049. break;
  1050. j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1,
  1051. total - j - 1);
  1052. if (j >= 0)
  1053. break;
  1054. }
  1055. if (i == bmap->n_eq)
  1056. has_rational = isl_bool_false;
  1057. }
  1058. isl_basic_map_free(bmap);
  1059. return has_rational;
  1060. }
  1061. /* Does "map" contain any rational points?
  1062. */
  1063. isl_bool isl_map_has_rational(__isl_keep isl_map *map)
  1064. {
  1065. int i;
  1066. isl_bool has_rational;
  1067. if (!map)
  1068. return isl_bool_error;
  1069. for (i = 0; i < map->n; ++i) {
  1070. has_rational = isl_basic_map_has_rational(map->p[i]);
  1071. if (has_rational < 0 || has_rational)
  1072. return has_rational;
  1073. }
  1074. return isl_bool_false;
  1075. }
  1076. /* Does "set" contain any rational points?
  1077. */
  1078. isl_bool isl_set_has_rational(__isl_keep isl_set *set)
  1079. {
  1080. return isl_map_has_rational(set);
  1081. }
  1082. /* Is this basic set a parameter domain?
  1083. */
  1084. isl_bool isl_basic_set_is_params(__isl_keep isl_basic_set *bset)
  1085. {
  1086. if (!bset)
  1087. return isl_bool_error;
  1088. return isl_space_is_params(bset->dim);
  1089. }
  1090. /* Is this set a parameter domain?
  1091. */
  1092. isl_bool isl_set_is_params(__isl_keep isl_set *set)
  1093. {
  1094. if (!set)
  1095. return isl_bool_error;
  1096. return isl_space_is_params(set->dim);
  1097. }
  1098. /* Is this map actually a parameter domain?
  1099. * Users should never call this function. Outside of isl,
  1100. * a map can never be a parameter domain.
  1101. */
  1102. isl_bool isl_map_is_params(__isl_keep isl_map *map)
  1103. {
  1104. if (!map)
  1105. return isl_bool_error;
  1106. return isl_space_is_params(map->dim);
  1107. }
  1108. static __isl_give isl_basic_map *basic_map_init(isl_ctx *ctx,
  1109. __isl_take isl_basic_map *bmap, unsigned extra,
  1110. unsigned n_eq, unsigned n_ineq)
  1111. {
  1112. int i;
  1113. isl_space *space = isl_basic_map_peek_space(bmap);
  1114. isl_size n_var = isl_space_dim(space, isl_dim_all);
  1115. size_t row_size = 1 + n_var + extra;
  1116. bmap->ctx = ctx;
  1117. isl_ctx_ref(ctx);
  1118. if (n_var < 0)
  1119. return isl_basic_map_free(bmap);
  1120. bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
  1121. if (isl_blk_is_error(bmap->block))
  1122. goto error;
  1123. bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq);
  1124. if ((n_ineq + n_eq) && !bmap->ineq)
  1125. goto error;
  1126. if (extra == 0) {
  1127. bmap->block2 = isl_blk_empty();
  1128. bmap->div = NULL;
  1129. } else {
  1130. bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
  1131. if (isl_blk_is_error(bmap->block2))
  1132. goto error;
  1133. bmap->div = isl_alloc_array(ctx, isl_int *, extra);
  1134. if (!bmap->div)
  1135. goto error;
  1136. }
  1137. for (i = 0; i < n_ineq + n_eq; ++i)
  1138. bmap->ineq[i] = bmap->block.data + i * row_size;
  1139. for (i = 0; i < extra; ++i)
  1140. bmap->div[i] = bmap->block2.data + i * (1 + row_size);
  1141. bmap->ref = 1;
  1142. bmap->flags = 0;
  1143. bmap->c_size = n_eq + n_ineq;
  1144. bmap->eq = bmap->ineq + n_ineq;
  1145. bmap->extra = extra;
  1146. bmap->n_eq = 0;
  1147. bmap->n_ineq = 0;
  1148. bmap->n_div = 0;
  1149. bmap->sample = NULL;
  1150. return bmap;
  1151. error:
  1152. isl_basic_map_free(bmap);
  1153. return NULL;
  1154. }
  1155. __isl_give isl_basic_set *isl_basic_set_alloc(isl_ctx *ctx,
  1156. unsigned nparam, unsigned dim, unsigned extra,
  1157. unsigned n_eq, unsigned n_ineq)
  1158. {
  1159. struct isl_basic_map *bmap;
  1160. isl_space *space;
  1161. space = isl_space_set_alloc(ctx, nparam, dim);
  1162. if (!space)
  1163. return NULL;
  1164. bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
  1165. return bset_from_bmap(bmap);
  1166. }
  1167. __isl_give isl_basic_set *isl_basic_set_alloc_space(__isl_take isl_space *space,
  1168. unsigned extra, unsigned n_eq, unsigned n_ineq)
  1169. {
  1170. struct isl_basic_map *bmap;
  1171. if (!space)
  1172. return NULL;
  1173. isl_assert(space->ctx, space->n_in == 0, goto error);
  1174. bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
  1175. return bset_from_bmap(bmap);
  1176. error:
  1177. isl_space_free(space);
  1178. return NULL;
  1179. }
  1180. __isl_give isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *space,
  1181. unsigned extra, unsigned n_eq, unsigned n_ineq)
  1182. {
  1183. struct isl_basic_map *bmap;
  1184. if (!space)
  1185. return NULL;
  1186. bmap = isl_calloc_type(space->ctx, struct isl_basic_map);
  1187. if (!bmap)
  1188. goto error;
  1189. bmap->dim = space;
  1190. return basic_map_init(space->ctx, bmap, extra, n_eq, n_ineq);
  1191. error:
  1192. isl_space_free(space);
  1193. return NULL;
  1194. }
  1195. __isl_give isl_basic_map *isl_basic_map_alloc(isl_ctx *ctx,
  1196. unsigned nparam, unsigned in, unsigned out, unsigned extra,
  1197. unsigned n_eq, unsigned n_ineq)
  1198. {
  1199. struct isl_basic_map *bmap;
  1200. isl_space *space;
  1201. space = isl_space_alloc(ctx, nparam, in, out);
  1202. if (!space)
  1203. return NULL;
  1204. bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
  1205. return bmap;
  1206. }
  1207. static __isl_give isl_basic_map *dup_constraints(__isl_take isl_basic_map *dst,
  1208. __isl_keep isl_basic_map *src)
  1209. {
  1210. int i;
  1211. isl_size total = isl_basic_map_dim(src, isl_dim_all);
  1212. if (!dst || total < 0)
  1213. return isl_basic_map_free(dst);
  1214. for (i = 0; i < src->n_eq; ++i) {
  1215. int j = isl_basic_map_alloc_equality(dst);
  1216. if (j < 0)
  1217. return isl_basic_map_free(dst);
  1218. isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
  1219. }
  1220. for (i = 0; i < src->n_ineq; ++i) {
  1221. int j = isl_basic_map_alloc_inequality(dst);
  1222. if (j < 0)
  1223. return isl_basic_map_free(dst);
  1224. isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
  1225. }
  1226. for (i = 0; i < src->n_div; ++i) {
  1227. int j = isl_basic_map_alloc_div(dst);
  1228. if (j < 0)
  1229. return isl_basic_map_free(dst);
  1230. isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
  1231. }
  1232. ISL_F_SET(dst, ISL_BASIC_SET_FINAL);
  1233. return dst;
  1234. }
  1235. __isl_give isl_basic_map *isl_basic_map_dup(__isl_keep isl_basic_map *bmap)
  1236. {
  1237. struct isl_basic_map *dup;
  1238. if (!bmap)
  1239. return NULL;
  1240. dup = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
  1241. bmap->n_div, bmap->n_eq, bmap->n_ineq);
  1242. dup = dup_constraints(dup, bmap);
  1243. if (!dup)
  1244. return NULL;
  1245. dup->flags = bmap->flags;
  1246. dup->sample = isl_vec_copy(bmap->sample);
  1247. return dup;
  1248. }
  1249. __isl_give isl_basic_set *isl_basic_set_dup(__isl_keep isl_basic_set *bset)
  1250. {
  1251. struct isl_basic_map *dup;
  1252. dup = isl_basic_map_dup(bset_to_bmap(bset));
  1253. return bset_from_bmap(dup);
  1254. }
  1255. __isl_give isl_basic_set *isl_basic_set_copy(__isl_keep isl_basic_set *bset)
  1256. {
  1257. if (!bset)
  1258. return NULL;
  1259. if (ISL_F_ISSET(bset, ISL_BASIC_SET_FINAL)) {
  1260. bset->ref++;
  1261. return bset;
  1262. }
  1263. return isl_basic_set_dup(bset);
  1264. }
  1265. __isl_give isl_set *isl_set_copy(__isl_keep isl_set *set)
  1266. {
  1267. if (!set)
  1268. return NULL;
  1269. set->ref++;
  1270. return set;
  1271. }
  1272. __isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
  1273. {
  1274. if (!bmap)
  1275. return NULL;
  1276. if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
  1277. bmap->ref++;
  1278. return bmap;
  1279. }
  1280. bmap = isl_basic_map_dup(bmap);
  1281. if (bmap)
  1282. ISL_F_SET(bmap, ISL_BASIC_SET_FINAL);
  1283. return bmap;
  1284. }
  1285. __isl_give isl_map *isl_map_copy(__isl_keep isl_map *map)
  1286. {
  1287. if (!map)
  1288. return NULL;
  1289. map->ref++;
  1290. return map;
  1291. }
  1292. __isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap)
  1293. {
  1294. if (!bmap)
  1295. return NULL;
  1296. if (--bmap->ref > 0)
  1297. return NULL;
  1298. isl_ctx_deref(bmap->ctx);
  1299. free(bmap->div);
  1300. isl_blk_free(bmap->ctx, bmap->block2);
  1301. free(bmap->ineq);
  1302. isl_blk_free(bmap->ctx, bmap->block);
  1303. isl_vec_free(bmap->sample);
  1304. isl_space_free(bmap->dim);
  1305. free(bmap);
  1306. return NULL;
  1307. }
  1308. __isl_null isl_basic_set *isl_basic_set_free(__isl_take isl_basic_set *bset)
  1309. {
  1310. return isl_basic_map_free(bset_to_bmap(bset));
  1311. }
  1312. static int room_for_con(__isl_keep isl_basic_map *bmap, unsigned n)
  1313. {
  1314. return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
  1315. }
  1316. /* Check that "bset" does not involve any parameters.
  1317. */
  1318. isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_set *bset)
  1319. {
  1320. isl_size nparam;
  1321. nparam = isl_basic_set_dim(bset, isl_dim_param);
  1322. if (nparam < 0)
  1323. return isl_stat_error;
  1324. if (nparam != 0)
  1325. isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
  1326. "basic set should not have any parameters",
  1327. return isl_stat_error);
  1328. return isl_stat_ok;
  1329. }
  1330. /* Check that "bset" does not involve any local variables.
  1331. */
  1332. isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_set *bset)
  1333. {
  1334. isl_size n_div;
  1335. n_div = isl_basic_set_dim(bset, isl_dim_div);
  1336. if (n_div < 0)
  1337. return isl_stat_error;
  1338. if (n_div != 0)
  1339. isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
  1340. "basic set should not have any local variables",
  1341. return isl_stat_error);
  1342. return isl_stat_ok;
  1343. }
  1344. #undef TYPE
  1345. #define TYPE isl_map
  1346. #include "isl_check_named_params_templ.c"
  1347. #undef TYPE
  1348. #define TYPE isl_basic_map
  1349. static
  1350. #include "isl_check_named_params_templ.c"
  1351. /* Check that "bmap1" and "bmap2" have the same parameters,
  1352. * reporting an error if they do not.
  1353. */
  1354. static isl_stat isl_basic_map_check_equal_params(
  1355. __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
  1356. {
  1357. isl_bool match;
  1358. match = isl_basic_map_has_equal_params(bmap1, bmap2);
  1359. if (match < 0)
  1360. return isl_stat_error;
  1361. if (!match)
  1362. isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
  1363. "parameters don't match", return isl_stat_error);
  1364. return isl_stat_ok;
  1365. }
  1366. #undef TYPE
  1367. #define TYPE isl_map
  1368. #include "isl_align_params_bin_templ.c"
  1369. #undef SUFFIX
  1370. #define SUFFIX set
  1371. #undef ARG1
  1372. #define ARG1 isl_map
  1373. #undef ARG2
  1374. #define ARG2 isl_set
  1375. #include "isl_align_params_templ.c"
  1376. isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
  1377. __isl_keep isl_map *map2,
  1378. isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2))
  1379. {
  1380. isl_bool r;
  1381. if (!map1 || !map2)
  1382. return isl_bool_error;
  1383. if (isl_map_has_equal_params(map1, map2))
  1384. return fn(map1, map2);
  1385. if (isl_map_check_named_params(map1) < 0)
  1386. return isl_bool_error;
  1387. if (isl_map_check_named_params(map2) < 0)
  1388. return isl_bool_error;
  1389. map1 = isl_map_copy(map1);
  1390. map2 = isl_map_copy(map2);
  1391. map1 = isl_map_align_params(map1, isl_map_get_space(map2));
  1392. map2 = isl_map_align_params(map2, isl_map_get_space(map1));
  1393. r = fn(map1, map2);
  1394. isl_map_free(map1);
  1395. isl_map_free(map2);
  1396. return r;
  1397. }
  1398. int isl_basic_map_alloc_equality(__isl_keep isl_basic_map *bmap)
  1399. {
  1400. isl_size total;
  1401. struct isl_ctx *ctx;
  1402. total = isl_basic_map_dim(bmap, isl_dim_all);
  1403. if (total < 0)
  1404. return -1;
  1405. ctx = bmap->ctx;
  1406. isl_assert(ctx, room_for_con(bmap, 1), return -1);
  1407. isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,
  1408. return -1);
  1409. ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
  1410. ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
  1411. ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
  1412. ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
  1413. if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
  1414. isl_int *t;
  1415. int j = isl_basic_map_alloc_inequality(bmap);
  1416. if (j < 0)
  1417. return -1;
  1418. t = bmap->ineq[j];
  1419. bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
  1420. bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
  1421. bmap->eq[-1] = t;
  1422. bmap->n_eq++;
  1423. bmap->n_ineq--;
  1424. bmap->eq--;
  1425. return 0;
  1426. }
  1427. isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + total,
  1428. bmap->extra - bmap->n_div);
  1429. return bmap->n_eq++;
  1430. }
  1431. int isl_basic_set_alloc_equality(__isl_keep isl_basic_set *bset)
  1432. {
  1433. return isl_basic_map_alloc_equality(bset_to_bmap(bset));
  1434. }
  1435. __isl_give isl_basic_map *isl_basic_map_free_equality(
  1436. __isl_take isl_basic_map *bmap, unsigned n)
  1437. {
  1438. if (!bmap)
  1439. return NULL;
  1440. if (n > bmap->n_eq)
  1441. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  1442. "invalid number of equalities",
  1443. isl_basic_map_free(bmap));
  1444. bmap->n_eq -= n;
  1445. return bmap;
  1446. }
  1447. __isl_give isl_basic_set *isl_basic_set_free_equality(
  1448. __isl_take isl_basic_set *bset, unsigned n)
  1449. {
  1450. return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset),
  1451. n));
  1452. }
  1453. /* Drop the equality constraint at position "pos",
  1454. * preserving the order of the other equality constraints.
  1455. */
  1456. int isl_basic_map_drop_equality(__isl_keep isl_basic_map *bmap, unsigned pos)
  1457. {
  1458. isl_int *t;
  1459. int r;
  1460. if (!bmap)
  1461. return -1;
  1462. isl_assert(bmap->ctx, pos < bmap->n_eq, return -1);
  1463. t = bmap->eq[pos];
  1464. bmap->n_eq--;
  1465. for (r = pos; r < bmap->n_eq; ++r)
  1466. bmap->eq[r] = bmap->eq[r + 1];
  1467. bmap->eq[bmap->n_eq] = t;
  1468. return 0;
  1469. }
  1470. /* Turn inequality "pos" of "bmap" into an equality.
  1471. *
  1472. * In particular, we move the inequality in front of the equalities
  1473. * and move the last inequality in the position of the moved inequality.
  1474. * Note that isl_tab_make_equalities_explicit depends on this particular
  1475. * change in the ordering of the constraints.
  1476. */
  1477. void isl_basic_map_inequality_to_equality(
  1478. __isl_keep isl_basic_map *bmap, unsigned pos)
  1479. {
  1480. isl_int *t;
  1481. t = bmap->ineq[pos];
  1482. bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
  1483. bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
  1484. bmap->eq[-1] = t;
  1485. bmap->n_eq++;
  1486. bmap->n_ineq--;
  1487. bmap->eq--;
  1488. ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
  1489. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  1490. ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
  1491. ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
  1492. }
  1493. static int room_for_ineq(__isl_keep isl_basic_map *bmap, unsigned n)
  1494. {
  1495. return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
  1496. }
  1497. int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap)
  1498. {
  1499. isl_size total;
  1500. struct isl_ctx *ctx;
  1501. total = isl_basic_map_dim(bmap, isl_dim_all);
  1502. if (total < 0)
  1503. return -1;
  1504. ctx = bmap->ctx;
  1505. isl_assert(ctx, room_for_ineq(bmap, 1), return -1);
  1506. ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
  1507. ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
  1508. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  1509. ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
  1510. isl_seq_clr(bmap->ineq[bmap->n_ineq] + 1 + total,
  1511. bmap->extra - bmap->n_div);
  1512. return bmap->n_ineq++;
  1513. }
  1514. int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set *bset)
  1515. {
  1516. return isl_basic_map_alloc_inequality(bset_to_bmap(bset));
  1517. }
  1518. __isl_give isl_basic_map *isl_basic_map_free_inequality(
  1519. __isl_take isl_basic_map *bmap, unsigned n)
  1520. {
  1521. if (!bmap)
  1522. return NULL;
  1523. if (n > bmap->n_ineq)
  1524. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  1525. "invalid number of inequalities",
  1526. return isl_basic_map_free(bmap));
  1527. bmap->n_ineq -= n;
  1528. return bmap;
  1529. }
  1530. __isl_give isl_basic_set *isl_basic_set_free_inequality(
  1531. __isl_take isl_basic_set *bset, unsigned n)
  1532. {
  1533. return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset),
  1534. n));
  1535. }
  1536. int isl_basic_map_drop_inequality(__isl_keep isl_basic_map *bmap, unsigned pos)
  1537. {
  1538. isl_int *t;
  1539. if (!bmap)
  1540. return -1;
  1541. isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
  1542. if (pos != bmap->n_ineq - 1) {
  1543. t = bmap->ineq[pos];
  1544. bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
  1545. bmap->ineq[bmap->n_ineq - 1] = t;
  1546. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  1547. }
  1548. bmap->n_ineq--;
  1549. return 0;
  1550. }
  1551. int isl_basic_set_drop_inequality(__isl_keep isl_basic_set *bset, unsigned pos)
  1552. {
  1553. return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos);
  1554. }
  1555. __isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
  1556. isl_int *eq)
  1557. {
  1558. isl_bool empty;
  1559. isl_size total;
  1560. int k;
  1561. empty = isl_basic_map_plain_is_empty(bmap);
  1562. if (empty < 0)
  1563. return isl_basic_map_free(bmap);
  1564. if (empty)
  1565. return bmap;
  1566. bmap = isl_basic_map_cow(bmap);
  1567. bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
  1568. total = isl_basic_map_dim(bmap, isl_dim_all);
  1569. if (total < 0)
  1570. return isl_basic_map_free(bmap);
  1571. k = isl_basic_map_alloc_equality(bmap);
  1572. if (k < 0)
  1573. goto error;
  1574. isl_seq_cpy(bmap->eq[k], eq, 1 + total);
  1575. return bmap;
  1576. error:
  1577. isl_basic_map_free(bmap);
  1578. return NULL;
  1579. }
  1580. __isl_give isl_basic_set *isl_basic_set_add_eq(__isl_take isl_basic_set *bset,
  1581. isl_int *eq)
  1582. {
  1583. return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq));
  1584. }
  1585. __isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
  1586. isl_int *ineq)
  1587. {
  1588. isl_size total;
  1589. int k;
  1590. bmap = isl_basic_map_cow(bmap);
  1591. bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
  1592. total = isl_basic_map_dim(bmap, isl_dim_all);
  1593. if (total < 0)
  1594. return isl_basic_map_free(bmap);
  1595. k = isl_basic_map_alloc_inequality(bmap);
  1596. if (k < 0)
  1597. goto error;
  1598. isl_seq_cpy(bmap->ineq[k], ineq, 1 + total);
  1599. return bmap;
  1600. error:
  1601. isl_basic_map_free(bmap);
  1602. return NULL;
  1603. }
  1604. __isl_give isl_basic_set *isl_basic_set_add_ineq(__isl_take isl_basic_set *bset,
  1605. isl_int *ineq)
  1606. {
  1607. return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq));
  1608. }
  1609. int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap)
  1610. {
  1611. isl_size total;
  1612. total = isl_basic_map_dim(bmap, isl_dim_all);
  1613. if (total < 0)
  1614. return -1;
  1615. isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1);
  1616. isl_seq_clr(bmap->div[bmap->n_div] + 1 + 1 + total,
  1617. bmap->extra - bmap->n_div);
  1618. ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
  1619. return bmap->n_div++;
  1620. }
  1621. int isl_basic_set_alloc_div(__isl_keep isl_basic_set *bset)
  1622. {
  1623. return isl_basic_map_alloc_div(bset_to_bmap(bset));
  1624. }
  1625. #undef TYPE
  1626. #define TYPE isl_basic_map
  1627. #include "check_type_range_templ.c"
  1628. /* Check that there are "n" dimensions of type "type" starting at "first"
  1629. * in "bset".
  1630. */
  1631. isl_stat isl_basic_set_check_range(__isl_keep isl_basic_set *bset,
  1632. enum isl_dim_type type, unsigned first, unsigned n)
  1633. {
  1634. return isl_basic_map_check_range(bset_to_bmap(bset),
  1635. type, first, n);
  1636. }
  1637. /* Insert an extra integer division, prescribed by "div", to "bmap"
  1638. * at (integer division) position "pos".
  1639. *
  1640. * The integer division is first added at the end and then moved
  1641. * into the right position.
  1642. */
  1643. __isl_give isl_basic_map *isl_basic_map_insert_div(
  1644. __isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
  1645. {
  1646. int i, k;
  1647. isl_size total;
  1648. bmap = isl_basic_map_cow(bmap);
  1649. total = isl_basic_map_dim(bmap, isl_dim_all);
  1650. if (total < 0 || !div)
  1651. return isl_basic_map_free(bmap);
  1652. if (div->size != 1 + 1 + total)
  1653. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  1654. "unexpected size", return isl_basic_map_free(bmap));
  1655. if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0)
  1656. return isl_basic_map_free(bmap);
  1657. bmap = isl_basic_map_extend(bmap, 1, 0, 2);
  1658. k = isl_basic_map_alloc_div(bmap);
  1659. if (k < 0)
  1660. return isl_basic_map_free(bmap);
  1661. isl_seq_cpy(bmap->div[k], div->el, div->size);
  1662. isl_int_set_si(bmap->div[k][div->size], 0);
  1663. for (i = k; i > pos; --i)
  1664. bmap = isl_basic_map_swap_div(bmap, i, i - 1);
  1665. return bmap;
  1666. }
  1667. isl_stat isl_basic_map_free_div(__isl_keep isl_basic_map *bmap, unsigned n)
  1668. {
  1669. if (!bmap)
  1670. return isl_stat_error;
  1671. isl_assert(bmap->ctx, n <= bmap->n_div, return isl_stat_error);
  1672. bmap->n_div -= n;
  1673. return isl_stat_ok;
  1674. }
  1675. static __isl_give isl_basic_map *add_constraints(
  1676. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2,
  1677. unsigned i_pos, unsigned o_pos)
  1678. {
  1679. isl_size total, n_param, n_in, n_out, n_div;
  1680. unsigned o_in, o_out;
  1681. isl_ctx *ctx;
  1682. isl_space *space;
  1683. struct isl_dim_map *dim_map;
  1684. space = isl_basic_map_peek_space(bmap2);
  1685. if (!bmap1 || !space)
  1686. goto error;
  1687. total = isl_basic_map_dim(bmap1, isl_dim_all);
  1688. n_param = isl_basic_map_dim(bmap2, isl_dim_param);
  1689. n_in = isl_basic_map_dim(bmap2, isl_dim_in);
  1690. o_in = isl_basic_map_offset(bmap1, isl_dim_in) - 1 + i_pos;
  1691. n_out = isl_basic_map_dim(bmap2, isl_dim_out);
  1692. o_out = isl_basic_map_offset(bmap1, isl_dim_out) - 1 + o_pos;
  1693. n_div = isl_basic_map_dim(bmap2, isl_dim_div);
  1694. if (total < 0 || n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0)
  1695. goto error;
  1696. ctx = isl_basic_map_get_ctx(bmap1);
  1697. dim_map = isl_dim_map_alloc(ctx, total + n_div);
  1698. isl_dim_map_dim_range(dim_map, space, isl_dim_param, 0, n_param, 0);
  1699. isl_dim_map_dim_range(dim_map, space, isl_dim_in, 0, n_in, o_in);
  1700. isl_dim_map_dim_range(dim_map, space, isl_dim_out, 0, n_out, o_out);
  1701. isl_dim_map_div(dim_map, bmap2, total);
  1702. return isl_basic_map_add_constraints_dim_map(bmap1, bmap2, dim_map);
  1703. error:
  1704. isl_basic_map_free(bmap1);
  1705. isl_basic_map_free(bmap2);
  1706. return NULL;
  1707. }
  1708. __isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base,
  1709. unsigned extra, unsigned n_eq, unsigned n_ineq)
  1710. {
  1711. isl_space *space;
  1712. struct isl_basic_map *ext;
  1713. unsigned flags;
  1714. int dims_ok;
  1715. if (!base)
  1716. goto error;
  1717. dims_ok = base->extra >= base->n_div + extra;
  1718. if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
  1719. room_for_ineq(base, n_ineq))
  1720. return base;
  1721. extra += base->extra;
  1722. n_eq += base->n_eq;
  1723. n_ineq += base->n_ineq;
  1724. space = isl_basic_map_get_space(base);
  1725. ext = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
  1726. if (!ext)
  1727. goto error;
  1728. if (dims_ok)
  1729. ext->sample = isl_vec_copy(base->sample);
  1730. flags = base->flags;
  1731. ext = add_constraints(ext, base, 0, 0);
  1732. if (ext) {
  1733. ext->flags = flags;
  1734. ISL_F_CLR(ext, ISL_BASIC_SET_FINAL);
  1735. }
  1736. return ext;
  1737. error:
  1738. isl_basic_map_free(base);
  1739. return NULL;
  1740. }
  1741. __isl_give isl_basic_set *isl_basic_set_extend(__isl_take isl_basic_set *base,
  1742. unsigned extra, unsigned n_eq, unsigned n_ineq)
  1743. {
  1744. return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base),
  1745. extra, n_eq, n_ineq));
  1746. }
  1747. __isl_give isl_basic_map *isl_basic_map_extend_constraints(
  1748. __isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
  1749. {
  1750. return isl_basic_map_extend(base, 0, n_eq, n_ineq);
  1751. }
  1752. __isl_give isl_basic_set *isl_basic_set_extend_constraints(
  1753. __isl_take isl_basic_set *base, unsigned n_eq, unsigned n_ineq)
  1754. {
  1755. isl_basic_map *bmap = bset_to_bmap(base);
  1756. bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq);
  1757. return bset_from_bmap(bmap);
  1758. }
  1759. __isl_give isl_basic_set *isl_basic_set_cow(__isl_take isl_basic_set *bset)
  1760. {
  1761. return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset)));
  1762. }
  1763. __isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap)
  1764. {
  1765. if (!bmap)
  1766. return NULL;
  1767. if (bmap->ref > 1) {
  1768. bmap->ref--;
  1769. bmap = isl_basic_map_dup(bmap);
  1770. }
  1771. if (bmap) {
  1772. ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL);
  1773. ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS);
  1774. }
  1775. return bmap;
  1776. }
  1777. /* Clear all cached information in "map", either because it is about
  1778. * to be modified or because it is being freed.
  1779. * Always return the same pointer that is passed in.
  1780. * This is needed for the use in isl_map_free.
  1781. */
  1782. static __isl_give isl_map *clear_caches(__isl_take isl_map *map)
  1783. {
  1784. isl_basic_map_free(map->cached_simple_hull[0]);
  1785. isl_basic_map_free(map->cached_simple_hull[1]);
  1786. map->cached_simple_hull[0] = NULL;
  1787. map->cached_simple_hull[1] = NULL;
  1788. return map;
  1789. }
  1790. __isl_give isl_set *isl_set_cow(__isl_take isl_set *set)
  1791. {
  1792. return isl_map_cow(set);
  1793. }
  1794. /* Return an isl_map that is equal to "map" and that has only
  1795. * a single reference.
  1796. *
  1797. * If the original input already has only one reference, then
  1798. * simply return it, but clear all cached information, since
  1799. * it may be rendered invalid by the operations that will be
  1800. * performed on the result.
  1801. *
  1802. * Otherwise, create a duplicate (without any cached information).
  1803. */
  1804. __isl_give isl_map *isl_map_cow(__isl_take isl_map *map)
  1805. {
  1806. if (!map)
  1807. return NULL;
  1808. if (map->ref == 1)
  1809. return clear_caches(map);
  1810. map->ref--;
  1811. return isl_map_dup(map);
  1812. }
  1813. static void swap_vars(struct isl_blk blk, isl_int *a,
  1814. unsigned a_len, unsigned b_len)
  1815. {
  1816. isl_seq_cpy(blk.data, a+a_len, b_len);
  1817. isl_seq_cpy(blk.data+b_len, a, a_len);
  1818. isl_seq_cpy(a, blk.data, b_len+a_len);
  1819. }
  1820. static __isl_give isl_basic_map *isl_basic_map_swap_vars(
  1821. __isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2)
  1822. {
  1823. int i;
  1824. struct isl_blk blk;
  1825. if (isl_basic_map_check_range(bmap, isl_dim_all, pos - 1, n1 + n2) < 0)
  1826. goto error;
  1827. if (n1 == 0 || n2 == 0)
  1828. return bmap;
  1829. bmap = isl_basic_map_cow(bmap);
  1830. if (!bmap)
  1831. return NULL;
  1832. blk = isl_blk_alloc(bmap->ctx, n1 + n2);
  1833. if (isl_blk_is_error(blk))
  1834. goto error;
  1835. for (i = 0; i < bmap->n_eq; ++i)
  1836. swap_vars(blk,
  1837. bmap->eq[i] + pos, n1, n2);
  1838. for (i = 0; i < bmap->n_ineq; ++i)
  1839. swap_vars(blk,
  1840. bmap->ineq[i] + pos, n1, n2);
  1841. for (i = 0; i < bmap->n_div; ++i)
  1842. swap_vars(blk,
  1843. bmap->div[i]+1 + pos, n1, n2);
  1844. isl_blk_free(bmap->ctx, blk);
  1845. ISL_F_CLR(bmap, ISL_BASIC_SET_SORTED);
  1846. bmap = isl_basic_map_gauss(bmap, NULL);
  1847. return isl_basic_map_finalize(bmap);
  1848. error:
  1849. isl_basic_map_free(bmap);
  1850. return NULL;
  1851. }
  1852. /* The given basic map has turned out to be empty.
  1853. * Explicitly mark it as such and change the representation
  1854. * to a canonical representation of the empty basic map.
  1855. * Since the basic map has conflicting constraints,
  1856. * it must have at least one constraint, except perhaps
  1857. * if it was already explicitly marked as being empty.
  1858. * Do nothing in the latter case, i.e., if it has been marked empty and
  1859. * has no constraints.
  1860. */
  1861. __isl_give isl_basic_map *isl_basic_map_set_to_empty(
  1862. __isl_take isl_basic_map *bmap)
  1863. {
  1864. int i = 0;
  1865. isl_bool empty;
  1866. isl_size n;
  1867. isl_size total;
  1868. n = isl_basic_map_n_constraint(bmap);
  1869. empty = isl_basic_map_plain_is_empty(bmap);
  1870. if (n < 0 || empty < 0)
  1871. return isl_basic_map_free(bmap);
  1872. if (n == 0 && empty)
  1873. return bmap;
  1874. total = isl_basic_map_dim(bmap, isl_dim_all);
  1875. if (total < 0)
  1876. return isl_basic_map_free(bmap);
  1877. if (isl_basic_map_free_div(bmap, bmap->n_div) < 0)
  1878. return isl_basic_map_free(bmap);
  1879. bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);
  1880. if (!bmap)
  1881. return NULL;
  1882. if (bmap->n_eq > 0) {
  1883. bmap = isl_basic_map_free_equality(bmap, bmap->n_eq - 1);
  1884. if (!bmap)
  1885. return NULL;
  1886. } else {
  1887. i = isl_basic_map_alloc_equality(bmap);
  1888. if (i < 0)
  1889. goto error;
  1890. }
  1891. isl_int_set_si(bmap->eq[i][0], 1);
  1892. isl_seq_clr(bmap->eq[i]+1, total);
  1893. ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
  1894. isl_vec_free(bmap->sample);
  1895. bmap->sample = NULL;
  1896. return isl_basic_map_finalize(bmap);
  1897. error:
  1898. isl_basic_map_free(bmap);
  1899. return NULL;
  1900. }
  1901. __isl_give isl_basic_set *isl_basic_set_set_to_empty(
  1902. __isl_take isl_basic_set *bset)
  1903. {
  1904. return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset)));
  1905. }
  1906. __isl_give isl_basic_map *isl_basic_map_set_rational(
  1907. __isl_take isl_basic_map *bmap)
  1908. {
  1909. if (!bmap)
  1910. return NULL;
  1911. if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
  1912. return bmap;
  1913. bmap = isl_basic_map_cow(bmap);
  1914. if (!bmap)
  1915. return NULL;
  1916. ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL);
  1917. return isl_basic_map_finalize(bmap);
  1918. }
  1919. __isl_give isl_basic_set *isl_basic_set_set_rational(
  1920. __isl_take isl_basic_set *bset)
  1921. {
  1922. return isl_basic_map_set_rational(bset);
  1923. }
  1924. __isl_give isl_basic_set *isl_basic_set_set_integral(
  1925. __isl_take isl_basic_set *bset)
  1926. {
  1927. if (!bset)
  1928. return NULL;
  1929. if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL))
  1930. return bset;
  1931. bset = isl_basic_set_cow(bset);
  1932. if (!bset)
  1933. return NULL;
  1934. ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL);
  1935. return isl_basic_set_finalize(bset);
  1936. }
  1937. __isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map)
  1938. {
  1939. int i;
  1940. map = isl_map_cow(map);
  1941. if (!map)
  1942. return NULL;
  1943. for (i = 0; i < map->n; ++i) {
  1944. map->p[i] = isl_basic_map_set_rational(map->p[i]);
  1945. if (!map->p[i])
  1946. goto error;
  1947. }
  1948. return map;
  1949. error:
  1950. isl_map_free(map);
  1951. return NULL;
  1952. }
  1953. __isl_give isl_set *isl_set_set_rational(__isl_take isl_set *set)
  1954. {
  1955. return isl_map_set_rational(set);
  1956. }
  1957. /* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
  1958. * of "bmap").
  1959. */
  1960. static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b)
  1961. {
  1962. isl_int *t = bmap->div[a];
  1963. bmap->div[a] = bmap->div[b];
  1964. bmap->div[b] = t;
  1965. }
  1966. /* Swap divs "a" and "b" in "bmap" and adjust the constraints and
  1967. * div definitions accordingly.
  1968. */
  1969. __isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap,
  1970. int a, int b)
  1971. {
  1972. int i;
  1973. isl_size off;
  1974. off = isl_basic_map_var_offset(bmap, isl_dim_div);
  1975. if (off < 0)
  1976. return isl_basic_map_free(bmap);
  1977. swap_div(bmap, a, b);
  1978. for (i = 0; i < bmap->n_eq; ++i)
  1979. isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
  1980. for (i = 0; i < bmap->n_ineq; ++i)
  1981. isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
  1982. for (i = 0; i < bmap->n_div; ++i)
  1983. isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
  1984. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  1985. return bmap;
  1986. }
  1987. static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
  1988. {
  1989. isl_seq_cpy(c, c + n, rem);
  1990. isl_seq_clr(c + rem, n);
  1991. }
  1992. /* Drop n dimensions starting at first.
  1993. *
  1994. * In principle, this frees up some extra variables as the number
  1995. * of columns remains constant, but we would have to extend
  1996. * the div array too as the number of rows in this array is assumed
  1997. * to be equal to extra.
  1998. */
  1999. __isl_give isl_basic_set *isl_basic_set_drop_dims(
  2000. __isl_take isl_basic_set *bset, unsigned first, unsigned n)
  2001. {
  2002. return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n);
  2003. }
  2004. /* Move "n" divs starting at "first" to the end of the list of divs.
  2005. */
  2006. static __isl_give isl_basic_map *move_divs_last(__isl_take isl_basic_map *bmap,
  2007. unsigned first, unsigned n)
  2008. {
  2009. isl_int **div;
  2010. int i;
  2011. if (first + n == bmap->n_div)
  2012. return bmap;
  2013. div = isl_alloc_array(bmap->ctx, isl_int *, n);
  2014. if (!div)
  2015. goto error;
  2016. for (i = 0; i < n; ++i)
  2017. div[i] = bmap->div[first + i];
  2018. for (i = 0; i < bmap->n_div - first - n; ++i)
  2019. bmap->div[first + i] = bmap->div[first + n + i];
  2020. for (i = 0; i < n; ++i)
  2021. bmap->div[bmap->n_div - n + i] = div[i];
  2022. free(div);
  2023. return bmap;
  2024. error:
  2025. isl_basic_map_free(bmap);
  2026. return NULL;
  2027. }
  2028. #undef TYPE
  2029. #define TYPE isl_map
  2030. static
  2031. #include "check_type_range_templ.c"
  2032. /* Check that there are "n" dimensions of type "type" starting at "first"
  2033. * in "set".
  2034. */
  2035. isl_stat isl_set_check_range(__isl_keep isl_set *set,
  2036. enum isl_dim_type type, unsigned first, unsigned n)
  2037. {
  2038. return isl_map_check_range(set_to_map(set), type, first, n);
  2039. }
  2040. /* Drop "n" dimensions of type "type" starting at "first".
  2041. * Perform the core computation, without cowing or
  2042. * simplifying and finalizing the result.
  2043. *
  2044. * In principle, this frees up some extra variables as the number
  2045. * of columns remains constant, but we would have to extend
  2046. * the div array too as the number of rows in this array is assumed
  2047. * to be equal to extra.
  2048. */
  2049. __isl_give isl_basic_map *isl_basic_map_drop_core(
  2050. __isl_take isl_basic_map *bmap, enum isl_dim_type type,
  2051. unsigned first, unsigned n)
  2052. {
  2053. int i;
  2054. unsigned offset;
  2055. unsigned left;
  2056. isl_size total;
  2057. if (isl_basic_map_check_range(bmap, type, first, n) < 0)
  2058. return isl_basic_map_free(bmap);
  2059. total = isl_basic_map_dim(bmap, isl_dim_all);
  2060. if (total < 0)
  2061. return isl_basic_map_free(bmap);
  2062. offset = isl_basic_map_offset(bmap, type) + first;
  2063. left = total - (offset - 1) - n;
  2064. for (i = 0; i < bmap->n_eq; ++i)
  2065. constraint_drop_vars(bmap->eq[i]+offset, n, left);
  2066. for (i = 0; i < bmap->n_ineq; ++i)
  2067. constraint_drop_vars(bmap->ineq[i]+offset, n, left);
  2068. for (i = 0; i < bmap->n_div; ++i)
  2069. constraint_drop_vars(bmap->div[i]+1+offset, n, left);
  2070. if (type == isl_dim_div) {
  2071. bmap = move_divs_last(bmap, first, n);
  2072. if (!bmap)
  2073. return NULL;
  2074. if (isl_basic_map_free_div(bmap, n) < 0)
  2075. return isl_basic_map_free(bmap);
  2076. } else
  2077. bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
  2078. if (!bmap->dim)
  2079. return isl_basic_map_free(bmap);
  2080. ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
  2081. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  2082. return bmap;
  2083. }
  2084. /* Drop "n" dimensions of type "type" starting at "first".
  2085. *
  2086. * In principle, this frees up some extra variables as the number
  2087. * of columns remains constant, but we would have to extend
  2088. * the div array too as the number of rows in this array is assumed
  2089. * to be equal to extra.
  2090. */
  2091. __isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap,
  2092. enum isl_dim_type type, unsigned first, unsigned n)
  2093. {
  2094. if (!bmap)
  2095. return NULL;
  2096. if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
  2097. return bmap;
  2098. bmap = isl_basic_map_cow(bmap);
  2099. if (!bmap)
  2100. return NULL;
  2101. bmap = isl_basic_map_drop_core(bmap, type, first, n);
  2102. bmap = isl_basic_map_simplify(bmap);
  2103. return isl_basic_map_finalize(bmap);
  2104. }
  2105. __isl_give isl_basic_set *isl_basic_set_drop(__isl_take isl_basic_set *bset,
  2106. enum isl_dim_type type, unsigned first, unsigned n)
  2107. {
  2108. return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset),
  2109. type, first, n));
  2110. }
  2111. /* No longer consider "map" to be normalized.
  2112. */
  2113. static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map)
  2114. {
  2115. if (!map)
  2116. return NULL;
  2117. ISL_F_CLR(map, ISL_MAP_NORMALIZED);
  2118. return map;
  2119. }
  2120. __isl_give isl_map *isl_map_drop(__isl_take isl_map *map,
  2121. enum isl_dim_type type, unsigned first, unsigned n)
  2122. {
  2123. int i;
  2124. isl_space *space;
  2125. if (isl_map_check_range(map, type, first, n) < 0)
  2126. return isl_map_free(map);
  2127. if (n == 0 && !isl_space_is_named_or_nested(map->dim, type))
  2128. return map;
  2129. map = isl_map_cow(map);
  2130. if (!map)
  2131. goto error;
  2132. for (i = 0; i < map->n; ++i) {
  2133. map->p[i] = isl_basic_map_drop(map->p[i], type, first, n);
  2134. if (!map->p[i])
  2135. goto error;
  2136. }
  2137. map = isl_map_unmark_normalized(map);
  2138. space = isl_map_take_space(map);
  2139. space = isl_space_drop_dims(space, type, first, n);
  2140. map = isl_map_restore_space(map, space);
  2141. return map;
  2142. error:
  2143. isl_map_free(map);
  2144. return NULL;
  2145. }
  2146. __isl_give isl_set *isl_set_drop(__isl_take isl_set *set,
  2147. enum isl_dim_type type, unsigned first, unsigned n)
  2148. {
  2149. return set_from_map(isl_map_drop(set_to_map(set), type, first, n));
  2150. }
  2151. /* Drop the integer division at position "div", which is assumed
  2152. * not to appear in any of the constraints or
  2153. * in any of the other integer divisions.
  2154. *
  2155. * Since the integer division is redundant, there is no need to cow.
  2156. */
  2157. __isl_give isl_basic_map *isl_basic_map_drop_div(
  2158. __isl_take isl_basic_map *bmap, unsigned div)
  2159. {
  2160. return isl_basic_map_drop_core(bmap, isl_dim_div, div, 1);
  2161. }
  2162. /* Eliminate the specified n dimensions starting at first from the
  2163. * constraints, without removing the dimensions from the space.
  2164. * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
  2165. */
  2166. __isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
  2167. enum isl_dim_type type, unsigned first, unsigned n)
  2168. {
  2169. int i;
  2170. if (n == 0)
  2171. return map;
  2172. if (isl_map_check_range(map, type, first, n) < 0)
  2173. return isl_map_free(map);
  2174. map = isl_map_cow(map);
  2175. if (!map)
  2176. return NULL;
  2177. for (i = 0; i < map->n; ++i) {
  2178. map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n);
  2179. if (!map->p[i])
  2180. goto error;
  2181. }
  2182. return map;
  2183. error:
  2184. isl_map_free(map);
  2185. return NULL;
  2186. }
  2187. /* Eliminate the specified n dimensions starting at first from the
  2188. * constraints, without removing the dimensions from the space.
  2189. * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
  2190. */
  2191. __isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set,
  2192. enum isl_dim_type type, unsigned first, unsigned n)
  2193. {
  2194. return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n));
  2195. }
  2196. /* Eliminate the specified n dimensions starting at first from the
  2197. * constraints, without removing the dimensions from the space.
  2198. * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
  2199. */
  2200. __isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set,
  2201. unsigned first, unsigned n)
  2202. {
  2203. return isl_set_eliminate(set, isl_dim_set, first, n);
  2204. }
  2205. __isl_give isl_basic_map *isl_basic_map_remove_divs(
  2206. __isl_take isl_basic_map *bmap)
  2207. {
  2208. isl_size v_div;
  2209. v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
  2210. if (v_div < 0)
  2211. return isl_basic_map_free(bmap);
  2212. bmap = isl_basic_map_eliminate_vars(bmap, v_div, bmap->n_div);
  2213. if (!bmap)
  2214. return NULL;
  2215. bmap->n_div = 0;
  2216. return isl_basic_map_finalize(bmap);
  2217. }
  2218. __isl_give isl_basic_set *isl_basic_set_remove_divs(
  2219. __isl_take isl_basic_set *bset)
  2220. {
  2221. return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset)));
  2222. }
  2223. __isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map)
  2224. {
  2225. int i;
  2226. if (!map)
  2227. return NULL;
  2228. if (map->n == 0)
  2229. return map;
  2230. map = isl_map_cow(map);
  2231. if (!map)
  2232. return NULL;
  2233. for (i = 0; i < map->n; ++i) {
  2234. map->p[i] = isl_basic_map_remove_divs(map->p[i]);
  2235. if (!map->p[i])
  2236. goto error;
  2237. }
  2238. return map;
  2239. error:
  2240. isl_map_free(map);
  2241. return NULL;
  2242. }
  2243. __isl_give isl_set *isl_set_remove_divs(__isl_take isl_set *set)
  2244. {
  2245. return isl_map_remove_divs(set);
  2246. }
  2247. __isl_give isl_basic_map *isl_basic_map_remove_dims(
  2248. __isl_take isl_basic_map *bmap, enum isl_dim_type type,
  2249. unsigned first, unsigned n)
  2250. {
  2251. if (isl_basic_map_check_range(bmap, type, first, n) < 0)
  2252. return isl_basic_map_free(bmap);
  2253. if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
  2254. return bmap;
  2255. bmap = isl_basic_map_eliminate_vars(bmap,
  2256. isl_basic_map_offset(bmap, type) - 1 + first, n);
  2257. if (!bmap)
  2258. return bmap;
  2259. if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY) && type == isl_dim_div)
  2260. return bmap;
  2261. bmap = isl_basic_map_drop(bmap, type, first, n);
  2262. return bmap;
  2263. }
  2264. /* Return true if the definition of the given div (recursively) involves
  2265. * any of the given variables.
  2266. */
  2267. static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
  2268. unsigned first, unsigned n)
  2269. {
  2270. int i;
  2271. unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
  2272. if (isl_int_is_zero(bmap->div[div][0]))
  2273. return isl_bool_false;
  2274. if (isl_seq_first_non_zero(bmap->div[div] + 1 + first, n) >= 0)
  2275. return isl_bool_true;
  2276. for (i = bmap->n_div - 1; i >= 0; --i) {
  2277. isl_bool involves;
  2278. if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
  2279. continue;
  2280. involves = div_involves_vars(bmap, i, first, n);
  2281. if (involves < 0 || involves)
  2282. return involves;
  2283. }
  2284. return isl_bool_false;
  2285. }
  2286. /* Try and add a lower and/or upper bound on "div" to "bmap"
  2287. * based on inequality "i".
  2288. * "total" is the total number of variables (excluding the divs).
  2289. * "v" is a temporary object that can be used during the calculations.
  2290. * If "lb" is set, then a lower bound should be constructed.
  2291. * If "ub" is set, then an upper bound should be constructed.
  2292. *
  2293. * The calling function has already checked that the inequality does not
  2294. * reference "div", but we still need to check that the inequality is
  2295. * of the right form. We'll consider the case where we want to construct
  2296. * a lower bound. The construction of upper bounds is similar.
  2297. *
  2298. * Let "div" be of the form
  2299. *
  2300. * q = floor((a + f(x))/d)
  2301. *
  2302. * We essentially check if constraint "i" is of the form
  2303. *
  2304. * b + f(x) >= 0
  2305. *
  2306. * so that we can use it to derive a lower bound on "div".
  2307. * However, we allow a slightly more general form
  2308. *
  2309. * b + g(x) >= 0
  2310. *
  2311. * with the condition that the coefficients of g(x) - f(x) are all
  2312. * divisible by d.
  2313. * Rewriting this constraint as
  2314. *
  2315. * 0 >= -b - g(x)
  2316. *
  2317. * adding a + f(x) to both sides and dividing by d, we obtain
  2318. *
  2319. * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
  2320. *
  2321. * Taking the floor on both sides, we obtain
  2322. *
  2323. * q >= floor((a-b)/d) + (f(x)-g(x))/d
  2324. *
  2325. * or
  2326. *
  2327. * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
  2328. *
  2329. * In the case of an upper bound, we construct the constraint
  2330. *
  2331. * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0
  2332. *
  2333. */
  2334. static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq(
  2335. __isl_take isl_basic_map *bmap, int div, int i,
  2336. unsigned total, isl_int v, int lb, int ub)
  2337. {
  2338. int j;
  2339. for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) {
  2340. if (lb) {
  2341. isl_int_sub(v, bmap->ineq[i][1 + j],
  2342. bmap->div[div][1 + 1 + j]);
  2343. lb = isl_int_is_divisible_by(v, bmap->div[div][0]);
  2344. }
  2345. if (ub) {
  2346. isl_int_add(v, bmap->ineq[i][1 + j],
  2347. bmap->div[div][1 + 1 + j]);
  2348. ub = isl_int_is_divisible_by(v, bmap->div[div][0]);
  2349. }
  2350. }
  2351. if (!lb && !ub)
  2352. return bmap;
  2353. bmap = isl_basic_map_cow(bmap);
  2354. bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub);
  2355. if (lb) {
  2356. int k = isl_basic_map_alloc_inequality(bmap);
  2357. if (k < 0)
  2358. goto error;
  2359. for (j = 0; j < 1 + total + bmap->n_div; ++j) {
  2360. isl_int_sub(bmap->ineq[k][j], bmap->ineq[i][j],
  2361. bmap->div[div][1 + j]);
  2362. isl_int_cdiv_q(bmap->ineq[k][j],
  2363. bmap->ineq[k][j], bmap->div[div][0]);
  2364. }
  2365. isl_int_set_si(bmap->ineq[k][1 + total + div], 1);
  2366. }
  2367. if (ub) {
  2368. int k = isl_basic_map_alloc_inequality(bmap);
  2369. if (k < 0)
  2370. goto error;
  2371. for (j = 0; j < 1 + total + bmap->n_div; ++j) {
  2372. isl_int_add(bmap->ineq[k][j], bmap->ineq[i][j],
  2373. bmap->div[div][1 + j]);
  2374. isl_int_fdiv_q(bmap->ineq[k][j],
  2375. bmap->ineq[k][j], bmap->div[div][0]);
  2376. }
  2377. isl_int_set_si(bmap->ineq[k][1 + total + div], -1);
  2378. }
  2379. return bmap;
  2380. error:
  2381. isl_basic_map_free(bmap);
  2382. return NULL;
  2383. }
  2384. /* This function is called right before "div" is eliminated from "bmap"
  2385. * using Fourier-Motzkin.
  2386. * Look through the constraints of "bmap" for constraints on the argument
  2387. * of the integer division and use them to construct constraints on the
  2388. * integer division itself. These constraints can then be combined
  2389. * during the Fourier-Motzkin elimination.
  2390. * Note that it is only useful to introduce lower bounds on "div"
  2391. * if "bmap" already contains upper bounds on "div" as the newly
  2392. * introduce lower bounds can then be combined with the pre-existing
  2393. * upper bounds. Similarly for upper bounds.
  2394. * We therefore first check if "bmap" contains any lower and/or upper bounds
  2395. * on "div".
  2396. *
  2397. * It is interesting to note that the introduction of these constraints
  2398. * can indeed lead to more accurate results, even when compared to
  2399. * deriving constraints on the argument of "div" from constraints on "div".
  2400. * Consider, for example, the set
  2401. *
  2402. * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
  2403. *
  2404. * The second constraint can be rewritten as
  2405. *
  2406. * 2 * [(-i-2j+3)/4] + k >= 0
  2407. *
  2408. * from which we can derive
  2409. *
  2410. * -i - 2j + 3 >= -2k
  2411. *
  2412. * or
  2413. *
  2414. * i + 2j <= 3 + 2k
  2415. *
  2416. * Combined with the first constraint, we obtain
  2417. *
  2418. * -3 <= 3 + 2k or k >= -3
  2419. *
  2420. * If, on the other hand we derive a constraint on [(i+2j)/4] from
  2421. * the first constraint, we obtain
  2422. *
  2423. * [(i + 2j)/4] >= [-3/4] = -1
  2424. *
  2425. * Combining this constraint with the second constraint, we obtain
  2426. *
  2427. * k >= -2
  2428. */
  2429. static __isl_give isl_basic_map *insert_bounds_on_div(
  2430. __isl_take isl_basic_map *bmap, int div)
  2431. {
  2432. int i;
  2433. int check_lb, check_ub;
  2434. isl_int v;
  2435. isl_size v_div;
  2436. if (!bmap)
  2437. return NULL;
  2438. if (isl_int_is_zero(bmap->div[div][0]))
  2439. return bmap;
  2440. v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
  2441. if (v_div < 0)
  2442. return isl_basic_map_free(bmap);
  2443. check_lb = 0;
  2444. check_ub = 0;
  2445. for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) {
  2446. int s = isl_int_sgn(bmap->ineq[i][1 + v_div + div]);
  2447. if (s > 0)
  2448. check_ub = 1;
  2449. if (s < 0)
  2450. check_lb = 1;
  2451. }
  2452. if (!check_lb && !check_ub)
  2453. return bmap;
  2454. isl_int_init(v);
  2455. for (i = 0; bmap && i < bmap->n_ineq; ++i) {
  2456. if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div]))
  2457. continue;
  2458. bmap = insert_bounds_on_div_from_ineq(bmap, div, i, v_div, v,
  2459. check_lb, check_ub);
  2460. }
  2461. isl_int_clear(v);
  2462. return bmap;
  2463. }
  2464. /* Remove all divs (recursively) involving any of the given dimensions
  2465. * in their definitions.
  2466. */
  2467. __isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
  2468. __isl_take isl_basic_map *bmap,
  2469. enum isl_dim_type type, unsigned first, unsigned n)
  2470. {
  2471. int i;
  2472. if (isl_basic_map_check_range(bmap, type, first, n) < 0)
  2473. return isl_basic_map_free(bmap);
  2474. first += isl_basic_map_offset(bmap, type);
  2475. for (i = bmap->n_div - 1; i >= 0; --i) {
  2476. isl_bool involves;
  2477. involves = div_involves_vars(bmap, i, first, n);
  2478. if (involves < 0)
  2479. return isl_basic_map_free(bmap);
  2480. if (!involves)
  2481. continue;
  2482. bmap = insert_bounds_on_div(bmap, i);
  2483. bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
  2484. if (!bmap)
  2485. return NULL;
  2486. i = bmap->n_div;
  2487. }
  2488. return bmap;
  2489. }
  2490. __isl_give isl_basic_set *isl_basic_set_remove_divs_involving_dims(
  2491. __isl_take isl_basic_set *bset,
  2492. enum isl_dim_type type, unsigned first, unsigned n)
  2493. {
  2494. return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
  2495. }
  2496. __isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
  2497. enum isl_dim_type type, unsigned first, unsigned n)
  2498. {
  2499. int i;
  2500. if (!map)
  2501. return NULL;
  2502. if (map->n == 0)
  2503. return map;
  2504. map = isl_map_cow(map);
  2505. if (!map)
  2506. return NULL;
  2507. for (i = 0; i < map->n; ++i) {
  2508. map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
  2509. type, first, n);
  2510. if (!map->p[i])
  2511. goto error;
  2512. }
  2513. return map;
  2514. error:
  2515. isl_map_free(map);
  2516. return NULL;
  2517. }
  2518. __isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set,
  2519. enum isl_dim_type type, unsigned first, unsigned n)
  2520. {
  2521. return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set),
  2522. type, first, n));
  2523. }
  2524. /* Does the description of "bmap" depend on the specified dimensions?
  2525. * We also check whether the dimensions appear in any of the div definitions.
  2526. * In principle there is no need for this check. If the dimensions appear
  2527. * in a div definition, they also appear in the defining constraints of that
  2528. * div.
  2529. */
  2530. isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap,
  2531. enum isl_dim_type type, unsigned first, unsigned n)
  2532. {
  2533. int i;
  2534. if (isl_basic_map_check_range(bmap, type, first, n) < 0)
  2535. return isl_bool_error;
  2536. first += isl_basic_map_offset(bmap, type);
  2537. for (i = 0; i < bmap->n_eq; ++i)
  2538. if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0)
  2539. return isl_bool_true;
  2540. for (i = 0; i < bmap->n_ineq; ++i)
  2541. if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0)
  2542. return isl_bool_true;
  2543. for (i = 0; i < bmap->n_div; ++i) {
  2544. if (isl_int_is_zero(bmap->div[i][0]))
  2545. continue;
  2546. if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0)
  2547. return isl_bool_true;
  2548. }
  2549. return isl_bool_false;
  2550. }
  2551. isl_bool isl_map_involves_dims(__isl_keep isl_map *map,
  2552. enum isl_dim_type type, unsigned first, unsigned n)
  2553. {
  2554. int i;
  2555. if (isl_map_check_range(map, type, first, n) < 0)
  2556. return isl_bool_error;
  2557. for (i = 0; i < map->n; ++i) {
  2558. isl_bool involves = isl_basic_map_involves_dims(map->p[i],
  2559. type, first, n);
  2560. if (involves < 0 || involves)
  2561. return involves;
  2562. }
  2563. return isl_bool_false;
  2564. }
  2565. isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset,
  2566. enum isl_dim_type type, unsigned first, unsigned n)
  2567. {
  2568. return isl_basic_map_involves_dims(bset, type, first, n);
  2569. }
  2570. isl_bool isl_set_involves_dims(__isl_keep isl_set *set,
  2571. enum isl_dim_type type, unsigned first, unsigned n)
  2572. {
  2573. return isl_map_involves_dims(set, type, first, n);
  2574. }
  2575. /* Does "bset" involve any local variables, i.e., integer divisions?
  2576. */
  2577. static isl_bool isl_basic_set_involves_locals(__isl_keep isl_basic_set *bset)
  2578. {
  2579. isl_size n;
  2580. n = isl_basic_set_dim(bset, isl_dim_div);
  2581. if (n < 0)
  2582. return isl_bool_error;
  2583. return isl_bool_ok(n > 0);
  2584. }
  2585. /* isl_set_every_basic_set callback that checks whether "bset"
  2586. * is free of local variables.
  2587. */
  2588. static isl_bool basic_set_no_locals(__isl_keep isl_basic_set *bset, void *user)
  2589. {
  2590. return isl_bool_not(isl_basic_set_involves_locals(bset));
  2591. }
  2592. /* Does "set" involve any local variables, i.e., integer divisions?
  2593. */
  2594. isl_bool isl_set_involves_locals(__isl_keep isl_set *set)
  2595. {
  2596. isl_bool no_locals;
  2597. no_locals = isl_set_every_basic_set(set, &basic_set_no_locals, NULL);
  2598. return isl_bool_not(no_locals);
  2599. }
  2600. /* Drop all constraints in bmap that involve any of the dimensions
  2601. * first to first+n-1.
  2602. * This function only performs the actual removal of constraints.
  2603. *
  2604. * This function should not call finalize since it is used by
  2605. * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
  2606. */
  2607. __isl_give isl_basic_map *isl_basic_map_drop_constraints_involving(
  2608. __isl_take isl_basic_map *bmap, unsigned first, unsigned n)
  2609. {
  2610. int i;
  2611. if (n == 0)
  2612. return bmap;
  2613. bmap = isl_basic_map_cow(bmap);
  2614. if (!bmap)
  2615. return NULL;
  2616. for (i = bmap->n_eq - 1; i >= 0; --i) {
  2617. if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1)
  2618. continue;
  2619. if (isl_basic_map_drop_equality(bmap, i) < 0)
  2620. return isl_basic_map_free(bmap);
  2621. }
  2622. for (i = bmap->n_ineq - 1; i >= 0; --i) {
  2623. if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1)
  2624. continue;
  2625. if (isl_basic_map_drop_inequality(bmap, i) < 0)
  2626. return isl_basic_map_free(bmap);
  2627. }
  2628. return bmap;
  2629. }
  2630. /* Drop all constraints in bset that involve any of the dimensions
  2631. * first to first+n-1.
  2632. * This function only performs the actual removal of constraints.
  2633. */
  2634. __isl_give isl_basic_set *isl_basic_set_drop_constraints_involving(
  2635. __isl_take isl_basic_set *bset, unsigned first, unsigned n)
  2636. {
  2637. return isl_basic_map_drop_constraints_involving(bset, first, n);
  2638. }
  2639. /* Drop all constraints in bmap that do not involve any of the dimensions
  2640. * first to first + n - 1 of the given type.
  2641. */
  2642. __isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims(
  2643. __isl_take isl_basic_map *bmap,
  2644. enum isl_dim_type type, unsigned first, unsigned n)
  2645. {
  2646. int i;
  2647. if (n == 0) {
  2648. isl_space *space = isl_basic_map_get_space(bmap);
  2649. isl_basic_map_free(bmap);
  2650. return isl_basic_map_universe(space);
  2651. }
  2652. bmap = isl_basic_map_cow(bmap);
  2653. if (!bmap)
  2654. return NULL;
  2655. if (isl_basic_map_check_range(bmap, type, first, n) < 0)
  2656. return isl_basic_map_free(bmap);
  2657. first += isl_basic_map_offset(bmap, type) - 1;
  2658. for (i = bmap->n_eq - 1; i >= 0; --i) {
  2659. if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1)
  2660. continue;
  2661. if (isl_basic_map_drop_equality(bmap, i) < 0)
  2662. return isl_basic_map_free(bmap);
  2663. }
  2664. for (i = bmap->n_ineq - 1; i >= 0; --i) {
  2665. if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1)
  2666. continue;
  2667. if (isl_basic_map_drop_inequality(bmap, i) < 0)
  2668. return isl_basic_map_free(bmap);
  2669. }
  2670. bmap = isl_basic_map_add_known_div_constraints(bmap);
  2671. return bmap;
  2672. }
  2673. /* Drop all constraints in bset that do not involve any of the dimensions
  2674. * first to first + n - 1 of the given type.
  2675. */
  2676. __isl_give isl_basic_set *isl_basic_set_drop_constraints_not_involving_dims(
  2677. __isl_take isl_basic_set *bset,
  2678. enum isl_dim_type type, unsigned first, unsigned n)
  2679. {
  2680. return isl_basic_map_drop_constraints_not_involving_dims(bset,
  2681. type, first, n);
  2682. }
  2683. /* Drop all constraints in bmap that involve any of the dimensions
  2684. * first to first + n - 1 of the given type.
  2685. */
  2686. __isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims(
  2687. __isl_take isl_basic_map *bmap,
  2688. enum isl_dim_type type, unsigned first, unsigned n)
  2689. {
  2690. if (!bmap)
  2691. return NULL;
  2692. if (n == 0)
  2693. return bmap;
  2694. if (isl_basic_map_check_range(bmap, type, first, n) < 0)
  2695. return isl_basic_map_free(bmap);
  2696. bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n);
  2697. first += isl_basic_map_offset(bmap, type) - 1;
  2698. bmap = isl_basic_map_drop_constraints_involving(bmap, first, n);
  2699. bmap = isl_basic_map_add_known_div_constraints(bmap);
  2700. return bmap;
  2701. }
  2702. /* Drop all constraints in bset that involve any of the dimensions
  2703. * first to first + n - 1 of the given type.
  2704. */
  2705. __isl_give isl_basic_set *isl_basic_set_drop_constraints_involving_dims(
  2706. __isl_take isl_basic_set *bset,
  2707. enum isl_dim_type type, unsigned first, unsigned n)
  2708. {
  2709. return isl_basic_map_drop_constraints_involving_dims(bset,
  2710. type, first, n);
  2711. }
  2712. /* Drop constraints from "map" by applying "drop" to each basic map.
  2713. */
  2714. static __isl_give isl_map *drop_constraints(__isl_take isl_map *map,
  2715. enum isl_dim_type type, unsigned first, unsigned n,
  2716. __isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap,
  2717. enum isl_dim_type type, unsigned first, unsigned n))
  2718. {
  2719. int i;
  2720. if (isl_map_check_range(map, type, first, n) < 0)
  2721. return isl_map_free(map);
  2722. map = isl_map_cow(map);
  2723. if (!map)
  2724. return NULL;
  2725. for (i = 0; i < map->n; ++i) {
  2726. map->p[i] = drop(map->p[i], type, first, n);
  2727. if (!map->p[i])
  2728. return isl_map_free(map);
  2729. }
  2730. if (map->n > 1)
  2731. ISL_F_CLR(map, ISL_MAP_DISJOINT);
  2732. return map;
  2733. }
  2734. /* Drop all constraints in map that involve any of the dimensions
  2735. * first to first + n - 1 of the given type.
  2736. */
  2737. __isl_give isl_map *isl_map_drop_constraints_involving_dims(
  2738. __isl_take isl_map *map,
  2739. enum isl_dim_type type, unsigned first, unsigned n)
  2740. {
  2741. if (n == 0)
  2742. return map;
  2743. return drop_constraints(map, type, first, n,
  2744. &isl_basic_map_drop_constraints_involving_dims);
  2745. }
  2746. /* Drop all constraints in "map" that do not involve any of the dimensions
  2747. * first to first + n - 1 of the given type.
  2748. */
  2749. __isl_give isl_map *isl_map_drop_constraints_not_involving_dims(
  2750. __isl_take isl_map *map,
  2751. enum isl_dim_type type, unsigned first, unsigned n)
  2752. {
  2753. if (n == 0) {
  2754. isl_space *space = isl_map_get_space(map);
  2755. isl_map_free(map);
  2756. return isl_map_universe(space);
  2757. }
  2758. return drop_constraints(map, type, first, n,
  2759. &isl_basic_map_drop_constraints_not_involving_dims);
  2760. }
  2761. /* Drop all constraints in set that involve any of the dimensions
  2762. * first to first + n - 1 of the given type.
  2763. */
  2764. __isl_give isl_set *isl_set_drop_constraints_involving_dims(
  2765. __isl_take isl_set *set,
  2766. enum isl_dim_type type, unsigned first, unsigned n)
  2767. {
  2768. return isl_map_drop_constraints_involving_dims(set, type, first, n);
  2769. }
  2770. /* Drop all constraints in "set" that do not involve any of the dimensions
  2771. * first to first + n - 1 of the given type.
  2772. */
  2773. __isl_give isl_set *isl_set_drop_constraints_not_involving_dims(
  2774. __isl_take isl_set *set,
  2775. enum isl_dim_type type, unsigned first, unsigned n)
  2776. {
  2777. return isl_map_drop_constraints_not_involving_dims(set, type, first, n);
  2778. }
  2779. /* Does local variable "div" of "bmap" have a complete explicit representation?
  2780. * Having a complete explicit representation requires not only
  2781. * an explicit representation, but also that all local variables
  2782. * that appear in this explicit representation in turn have
  2783. * a complete explicit representation.
  2784. */
  2785. isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
  2786. {
  2787. int i;
  2788. unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
  2789. isl_bool marked;
  2790. marked = isl_basic_map_div_is_marked_unknown(bmap, div);
  2791. if (marked < 0 || marked)
  2792. return isl_bool_not(marked);
  2793. for (i = bmap->n_div - 1; i >= 0; --i) {
  2794. isl_bool known;
  2795. if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
  2796. continue;
  2797. known = isl_basic_map_div_is_known(bmap, i);
  2798. if (known < 0 || !known)
  2799. return known;
  2800. }
  2801. return isl_bool_true;
  2802. }
  2803. /* Remove all divs that are unknown or defined in terms of unknown divs.
  2804. */
  2805. __isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
  2806. __isl_take isl_basic_map *bmap)
  2807. {
  2808. int i;
  2809. if (!bmap)
  2810. return NULL;
  2811. for (i = bmap->n_div - 1; i >= 0; --i) {
  2812. if (isl_basic_map_div_is_known(bmap, i))
  2813. continue;
  2814. bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
  2815. if (!bmap)
  2816. return NULL;
  2817. i = bmap->n_div;
  2818. }
  2819. return bmap;
  2820. }
  2821. /* Remove all divs that are unknown or defined in terms of unknown divs.
  2822. */
  2823. __isl_give isl_basic_set *isl_basic_set_remove_unknown_divs(
  2824. __isl_take isl_basic_set *bset)
  2825. {
  2826. return isl_basic_map_remove_unknown_divs(bset);
  2827. }
  2828. __isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
  2829. {
  2830. int i;
  2831. if (!map)
  2832. return NULL;
  2833. if (map->n == 0)
  2834. return map;
  2835. map = isl_map_cow(map);
  2836. if (!map)
  2837. return NULL;
  2838. for (i = 0; i < map->n; ++i) {
  2839. map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
  2840. if (!map->p[i])
  2841. goto error;
  2842. }
  2843. return map;
  2844. error:
  2845. isl_map_free(map);
  2846. return NULL;
  2847. }
  2848. __isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set)
  2849. {
  2850. return set_from_map(isl_map_remove_unknown_divs(set_to_map(set)));
  2851. }
  2852. __isl_give isl_basic_set *isl_basic_set_remove_dims(
  2853. __isl_take isl_basic_set *bset,
  2854. enum isl_dim_type type, unsigned first, unsigned n)
  2855. {
  2856. isl_basic_map *bmap = bset_to_bmap(bset);
  2857. bmap = isl_basic_map_remove_dims(bmap, type, first, n);
  2858. return bset_from_bmap(bmap);
  2859. }
  2860. __isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map,
  2861. enum isl_dim_type type, unsigned first, unsigned n)
  2862. {
  2863. int i;
  2864. if (n == 0)
  2865. return map;
  2866. map = isl_map_cow(map);
  2867. if (isl_map_check_range(map, type, first, n) < 0)
  2868. return isl_map_free(map);
  2869. for (i = 0; i < map->n; ++i) {
  2870. map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
  2871. isl_basic_map_offset(map->p[i], type) - 1 + first, n);
  2872. if (!map->p[i])
  2873. goto error;
  2874. }
  2875. map = isl_map_drop(map, type, first, n);
  2876. return map;
  2877. error:
  2878. isl_map_free(map);
  2879. return NULL;
  2880. }
  2881. __isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset,
  2882. enum isl_dim_type type, unsigned first, unsigned n)
  2883. {
  2884. return set_from_map(isl_map_remove_dims(set_to_map(bset),
  2885. type, first, n));
  2886. }
  2887. /* Project out n inputs starting at first using Fourier-Motzkin */
  2888. __isl_give isl_map *isl_map_remove_inputs(__isl_take isl_map *map,
  2889. unsigned first, unsigned n)
  2890. {
  2891. return isl_map_remove_dims(map, isl_dim_in, first, n);
  2892. }
  2893. void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset,
  2894. FILE *out, int indent)
  2895. {
  2896. isl_printer *p;
  2897. if (!bset) {
  2898. fprintf(out, "null basic set\n");
  2899. return;
  2900. }
  2901. fprintf(out, "%*s", indent, "");
  2902. fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
  2903. bset->ref, bset->dim->nparam, bset->dim->n_out,
  2904. bset->extra, bset->flags);
  2905. p = isl_printer_to_file(isl_basic_set_get_ctx(bset), out);
  2906. p = isl_printer_set_dump(p, 1);
  2907. p = isl_printer_set_indent(p, indent);
  2908. p = isl_printer_start_line(p);
  2909. p = isl_printer_print_basic_set(p, bset);
  2910. p = isl_printer_end_line(p);
  2911. isl_printer_free(p);
  2912. }
  2913. void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap,
  2914. FILE *out, int indent)
  2915. {
  2916. isl_printer *p;
  2917. if (!bmap) {
  2918. fprintf(out, "null basic map\n");
  2919. return;
  2920. }
  2921. fprintf(out, "%*s", indent, "");
  2922. fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
  2923. "flags: %x, n_name: %d\n",
  2924. bmap->ref,
  2925. bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
  2926. bmap->extra, bmap->flags, bmap->dim->n_id);
  2927. p = isl_printer_to_file(isl_basic_map_get_ctx(bmap), out);
  2928. p = isl_printer_set_dump(p, 1);
  2929. p = isl_printer_set_indent(p, indent);
  2930. p = isl_printer_start_line(p);
  2931. p = isl_printer_print_basic_map(p, bmap);
  2932. p = isl_printer_end_line(p);
  2933. isl_printer_free(p);
  2934. }
  2935. __isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap,
  2936. unsigned pos)
  2937. {
  2938. isl_size total;
  2939. total = isl_basic_map_dim(bmap, isl_dim_all);
  2940. if (total < 0)
  2941. return isl_basic_map_free(bmap);
  2942. if (pos >= bmap->n_ineq)
  2943. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  2944. "invalid position", return isl_basic_map_free(bmap));
  2945. isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
  2946. isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
  2947. ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
  2948. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  2949. return bmap;
  2950. }
  2951. __isl_give isl_set *isl_set_alloc_space(__isl_take isl_space *space, int n,
  2952. unsigned flags)
  2953. {
  2954. if (isl_space_check_is_set(space) < 0)
  2955. goto error;
  2956. return isl_map_alloc_space(space, n, flags);
  2957. error:
  2958. isl_space_free(space);
  2959. return NULL;
  2960. }
  2961. /* Make sure "map" has room for at least "n" more basic maps.
  2962. */
  2963. __isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n)
  2964. {
  2965. int i;
  2966. struct isl_map *grown = NULL;
  2967. if (!map)
  2968. return NULL;
  2969. isl_assert(map->ctx, n >= 0, goto error);
  2970. if (map->n + n <= map->size)
  2971. return map;
  2972. grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags);
  2973. if (!grown)
  2974. goto error;
  2975. for (i = 0; i < map->n; ++i) {
  2976. grown->p[i] = isl_basic_map_copy(map->p[i]);
  2977. if (!grown->p[i])
  2978. goto error;
  2979. grown->n++;
  2980. }
  2981. isl_map_free(map);
  2982. return grown;
  2983. error:
  2984. isl_map_free(grown);
  2985. isl_map_free(map);
  2986. return NULL;
  2987. }
  2988. /* Make sure "set" has room for at least "n" more basic sets.
  2989. */
  2990. __isl_give isl_set *isl_set_grow(__isl_take isl_set *set, int n)
  2991. {
  2992. return set_from_map(isl_map_grow(set_to_map(set), n));
  2993. }
  2994. __isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset)
  2995. {
  2996. return isl_map_from_basic_map(bset);
  2997. }
  2998. /* This function performs the same operation as isl_set_from_basic_set,
  2999. * but is considered as a function on an isl_basic_set when exported.
  3000. */
  3001. __isl_give isl_set *isl_basic_set_to_set(__isl_take isl_basic_set *bset)
  3002. {
  3003. return isl_set_from_basic_set(bset);
  3004. }
  3005. __isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
  3006. {
  3007. struct isl_map *map;
  3008. if (!bmap)
  3009. return NULL;
  3010. map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
  3011. return isl_map_add_basic_map(map, bmap);
  3012. }
  3013. __isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set,
  3014. __isl_take isl_basic_set *bset)
  3015. {
  3016. return set_from_map(isl_map_add_basic_map(set_to_map(set),
  3017. bset_to_bmap(bset)));
  3018. }
  3019. __isl_null isl_set *isl_set_free(__isl_take isl_set *set)
  3020. {
  3021. return isl_map_free(set);
  3022. }
  3023. void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent)
  3024. {
  3025. int i;
  3026. if (!set) {
  3027. fprintf(out, "null set\n");
  3028. return;
  3029. }
  3030. fprintf(out, "%*s", indent, "");
  3031. fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
  3032. set->ref, set->n, set->dim->nparam, set->dim->n_out,
  3033. set->flags);
  3034. for (i = 0; i < set->n; ++i) {
  3035. fprintf(out, "%*s", indent, "");
  3036. fprintf(out, "basic set %d:\n", i);
  3037. isl_basic_set_print_internal(set->p[i], out, indent+4);
  3038. }
  3039. }
  3040. void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent)
  3041. {
  3042. int i;
  3043. if (!map) {
  3044. fprintf(out, "null map\n");
  3045. return;
  3046. }
  3047. fprintf(out, "%*s", indent, "");
  3048. fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
  3049. "flags: %x, n_name: %d\n",
  3050. map->ref, map->n, map->dim->nparam, map->dim->n_in,
  3051. map->dim->n_out, map->flags, map->dim->n_id);
  3052. for (i = 0; i < map->n; ++i) {
  3053. fprintf(out, "%*s", indent, "");
  3054. fprintf(out, "basic map %d:\n", i);
  3055. isl_basic_map_print_internal(map->p[i], out, indent+4);
  3056. }
  3057. }
  3058. /* Check that the space of "bset" is the same as that of the domain of "bmap".
  3059. */
  3060. static isl_stat isl_basic_map_check_compatible_domain(
  3061. __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset)
  3062. {
  3063. isl_bool ok;
  3064. ok = isl_basic_map_compatible_domain(bmap, bset);
  3065. if (ok < 0)
  3066. return isl_stat_error;
  3067. if (!ok)
  3068. isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
  3069. "incompatible spaces", return isl_stat_error);
  3070. return isl_stat_ok;
  3071. }
  3072. __isl_give isl_basic_map *isl_basic_map_intersect_domain(
  3073. __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset)
  3074. {
  3075. struct isl_basic_map *bmap_domain;
  3076. isl_size dim;
  3077. if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
  3078. goto error;
  3079. dim = isl_basic_set_dim(bset, isl_dim_set);
  3080. if (dim < 0)
  3081. goto error;
  3082. if (dim != 0 &&
  3083. isl_basic_map_check_compatible_domain(bmap, bset) < 0)
  3084. goto error;
  3085. bmap = isl_basic_map_cow(bmap);
  3086. if (!bmap)
  3087. goto error;
  3088. bmap = isl_basic_map_extend(bmap,
  3089. bset->n_div, bset->n_eq, bset->n_ineq);
  3090. bmap_domain = isl_basic_map_from_domain(bset);
  3091. bmap = add_constraints(bmap, bmap_domain, 0, 0);
  3092. bmap = isl_basic_map_simplify(bmap);
  3093. return isl_basic_map_finalize(bmap);
  3094. error:
  3095. isl_basic_map_free(bmap);
  3096. isl_basic_set_free(bset);
  3097. return NULL;
  3098. }
  3099. /* Check that the space of "bset" is the same as that of the range of "bmap".
  3100. */
  3101. static isl_stat isl_basic_map_check_compatible_range(
  3102. __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset)
  3103. {
  3104. isl_bool ok;
  3105. ok = isl_basic_map_compatible_range(bmap, bset);
  3106. if (ok < 0)
  3107. return isl_stat_error;
  3108. if (!ok)
  3109. isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
  3110. "incompatible spaces", return isl_stat_error);
  3111. return isl_stat_ok;
  3112. }
  3113. __isl_give isl_basic_map *isl_basic_map_intersect_range(
  3114. __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset)
  3115. {
  3116. struct isl_basic_map *bmap_range;
  3117. isl_size dim;
  3118. if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
  3119. goto error;
  3120. dim = isl_basic_set_dim(bset, isl_dim_set);
  3121. if (dim < 0)
  3122. goto error;
  3123. if (dim != 0 && isl_basic_map_check_compatible_range(bmap, bset) < 0)
  3124. goto error;
  3125. if (isl_basic_set_plain_is_universe(bset)) {
  3126. isl_basic_set_free(bset);
  3127. return bmap;
  3128. }
  3129. bmap = isl_basic_map_cow(bmap);
  3130. if (!bmap)
  3131. goto error;
  3132. bmap = isl_basic_map_extend(bmap,
  3133. bset->n_div, bset->n_eq, bset->n_ineq);
  3134. bmap_range = bset_to_bmap(bset);
  3135. bmap = add_constraints(bmap, bmap_range, 0, 0);
  3136. bmap = isl_basic_map_simplify(bmap);
  3137. return isl_basic_map_finalize(bmap);
  3138. error:
  3139. isl_basic_map_free(bmap);
  3140. isl_basic_set_free(bset);
  3141. return NULL;
  3142. }
  3143. isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap,
  3144. __isl_keep isl_vec *vec)
  3145. {
  3146. int i;
  3147. isl_size total;
  3148. isl_int s;
  3149. total = isl_basic_map_dim(bmap, isl_dim_all);
  3150. if (total < 0 || !vec)
  3151. return isl_bool_error;
  3152. if (1 + total != vec->size)
  3153. return isl_bool_false;
  3154. isl_int_init(s);
  3155. for (i = 0; i < bmap->n_eq; ++i) {
  3156. isl_seq_inner_product(vec->el, bmap->eq[i], 1 + total, &s);
  3157. if (!isl_int_is_zero(s)) {
  3158. isl_int_clear(s);
  3159. return isl_bool_false;
  3160. }
  3161. }
  3162. for (i = 0; i < bmap->n_ineq; ++i) {
  3163. isl_seq_inner_product(vec->el, bmap->ineq[i], 1 + total, &s);
  3164. if (isl_int_is_neg(s)) {
  3165. isl_int_clear(s);
  3166. return isl_bool_false;
  3167. }
  3168. }
  3169. isl_int_clear(s);
  3170. return isl_bool_true;
  3171. }
  3172. isl_bool isl_basic_set_contains(__isl_keep isl_basic_set *bset,
  3173. __isl_keep isl_vec *vec)
  3174. {
  3175. return isl_basic_map_contains(bset_to_bmap(bset), vec);
  3176. }
  3177. __isl_give isl_basic_map *isl_basic_map_intersect(
  3178. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  3179. {
  3180. struct isl_vec *sample = NULL;
  3181. isl_space *space1, *space2;
  3182. isl_size dim1, dim2, nparam1, nparam2;
  3183. if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
  3184. goto error;
  3185. space1 = isl_basic_map_peek_space(bmap1);
  3186. space2 = isl_basic_map_peek_space(bmap2);
  3187. dim1 = isl_space_dim(space1, isl_dim_all);
  3188. dim2 = isl_space_dim(space2, isl_dim_all);
  3189. nparam1 = isl_space_dim(space1, isl_dim_param);
  3190. nparam2 = isl_space_dim(space2, isl_dim_param);
  3191. if (dim1 < 0 || dim2 < 0 || nparam1 < 0 || nparam2 < 0)
  3192. goto error;
  3193. if (dim1 == nparam1 && dim2 != nparam2)
  3194. return isl_basic_map_intersect(bmap2, bmap1);
  3195. if (dim2 != nparam2 &&
  3196. isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
  3197. goto error;
  3198. if (isl_basic_map_plain_is_empty(bmap1)) {
  3199. isl_basic_map_free(bmap2);
  3200. return bmap1;
  3201. }
  3202. if (isl_basic_map_plain_is_empty(bmap2)) {
  3203. isl_basic_map_free(bmap1);
  3204. return bmap2;
  3205. }
  3206. if (bmap1->sample &&
  3207. isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
  3208. isl_basic_map_contains(bmap2, bmap1->sample) > 0)
  3209. sample = isl_vec_copy(bmap1->sample);
  3210. else if (bmap2->sample &&
  3211. isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
  3212. isl_basic_map_contains(bmap2, bmap2->sample) > 0)
  3213. sample = isl_vec_copy(bmap2->sample);
  3214. bmap1 = isl_basic_map_cow(bmap1);
  3215. if (!bmap1)
  3216. goto error;
  3217. bmap1 = isl_basic_map_extend(bmap1,
  3218. bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
  3219. bmap1 = add_constraints(bmap1, bmap2, 0, 0);
  3220. if (!bmap1)
  3221. isl_vec_free(sample);
  3222. else if (sample) {
  3223. isl_vec_free(bmap1->sample);
  3224. bmap1->sample = sample;
  3225. }
  3226. bmap1 = isl_basic_map_simplify(bmap1);
  3227. return isl_basic_map_finalize(bmap1);
  3228. error:
  3229. if (sample)
  3230. isl_vec_free(sample);
  3231. isl_basic_map_free(bmap1);
  3232. isl_basic_map_free(bmap2);
  3233. return NULL;
  3234. }
  3235. __isl_give isl_basic_set *isl_basic_set_intersect(
  3236. __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
  3237. {
  3238. return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1),
  3239. bset_to_bmap(bset2)));
  3240. }
  3241. __isl_give isl_basic_set *isl_basic_set_intersect_params(
  3242. __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
  3243. {
  3244. return isl_basic_set_intersect(bset1, bset2);
  3245. }
  3246. /* Does "map" consist of a single disjunct, without any local variables?
  3247. */
  3248. static isl_bool is_convex_no_locals(__isl_keep isl_map *map)
  3249. {
  3250. isl_size n_div;
  3251. if (!map)
  3252. return isl_bool_error;
  3253. if (map->n != 1)
  3254. return isl_bool_false;
  3255. n_div = isl_basic_map_dim(map->p[0], isl_dim_div);
  3256. if (n_div < 0)
  3257. return isl_bool_error;
  3258. if (n_div != 0)
  3259. return isl_bool_false;
  3260. return isl_bool_true;
  3261. }
  3262. /* Check that "map" consists of a single disjunct, without any local variables.
  3263. */
  3264. static isl_stat check_convex_no_locals(__isl_keep isl_map *map)
  3265. {
  3266. isl_bool ok;
  3267. ok = is_convex_no_locals(map);
  3268. if (ok < 0)
  3269. return isl_stat_error;
  3270. if (ok)
  3271. return isl_stat_ok;
  3272. isl_die(isl_map_get_ctx(map), isl_error_internal,
  3273. "unexpectedly not convex or involving local variables",
  3274. return isl_stat_error);
  3275. }
  3276. /* Special case of isl_map_intersect, where both map1 and map2
  3277. * are convex, without any divs and such that either map1 or map2
  3278. * contains a single constraint. This constraint is then simply
  3279. * added to the other map.
  3280. */
  3281. static __isl_give isl_map *map_intersect_add_constraint(
  3282. __isl_take isl_map *map1, __isl_take isl_map *map2)
  3283. {
  3284. if (check_convex_no_locals(map1) < 0 ||
  3285. check_convex_no_locals(map2) < 0)
  3286. goto error;
  3287. if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
  3288. return isl_map_intersect(map2, map1);
  3289. map1 = isl_map_cow(map1);
  3290. if (!map1)
  3291. goto error;
  3292. if (isl_map_plain_is_empty(map1)) {
  3293. isl_map_free(map2);
  3294. return map1;
  3295. }
  3296. if (map2->p[0]->n_eq == 1)
  3297. map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
  3298. else
  3299. map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
  3300. map2->p[0]->ineq[0]);
  3301. map1->p[0] = isl_basic_map_simplify(map1->p[0]);
  3302. map1->p[0] = isl_basic_map_finalize(map1->p[0]);
  3303. if (!map1->p[0])
  3304. goto error;
  3305. if (isl_basic_map_plain_is_empty(map1->p[0])) {
  3306. isl_basic_map_free(map1->p[0]);
  3307. map1->n = 0;
  3308. }
  3309. isl_map_free(map2);
  3310. map1 = isl_map_unmark_normalized(map1);
  3311. return map1;
  3312. error:
  3313. isl_map_free(map1);
  3314. isl_map_free(map2);
  3315. return NULL;
  3316. }
  3317. /* map2 may be either a parameter domain or a map living in the same
  3318. * space as map1.
  3319. */
  3320. static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
  3321. __isl_take isl_map *map2)
  3322. {
  3323. unsigned flags = 0;
  3324. isl_bool equal;
  3325. isl_map *result;
  3326. int i, j;
  3327. isl_size dim2, nparam2;
  3328. if (!map1 || !map2)
  3329. goto error;
  3330. if ((isl_map_plain_is_empty(map1) ||
  3331. isl_map_plain_is_universe(map2)) &&
  3332. isl_space_is_equal(map1->dim, map2->dim)) {
  3333. isl_map_free(map2);
  3334. return map1;
  3335. }
  3336. if ((isl_map_plain_is_empty(map2) ||
  3337. isl_map_plain_is_universe(map1)) &&
  3338. isl_space_is_equal(map1->dim, map2->dim)) {
  3339. isl_map_free(map1);
  3340. return map2;
  3341. }
  3342. if (is_convex_no_locals(map1) == isl_bool_true &&
  3343. is_convex_no_locals(map2) == isl_bool_true &&
  3344. isl_space_is_equal(map1->dim, map2->dim) &&
  3345. (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
  3346. map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
  3347. return map_intersect_add_constraint(map1, map2);
  3348. equal = isl_map_plain_is_equal(map1, map2);
  3349. if (equal < 0)
  3350. goto error;
  3351. if (equal) {
  3352. isl_map_free(map2);
  3353. return map1;
  3354. }
  3355. dim2 = isl_map_dim(map2, isl_dim_all);
  3356. nparam2 = isl_map_dim(map2, isl_dim_param);
  3357. if (dim2 < 0 || nparam2 < 0)
  3358. goto error;
  3359. if (dim2 != nparam2)
  3360. isl_assert(map1->ctx,
  3361. isl_space_is_equal(map1->dim, map2->dim), goto error);
  3362. if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
  3363. ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
  3364. ISL_FL_SET(flags, ISL_MAP_DISJOINT);
  3365. result = isl_map_alloc_space(isl_space_copy(map1->dim),
  3366. map1->n * map2->n, flags);
  3367. if (!result)
  3368. goto error;
  3369. for (i = 0; i < map1->n; ++i)
  3370. for (j = 0; j < map2->n; ++j) {
  3371. struct isl_basic_map *part;
  3372. part = isl_basic_map_intersect(
  3373. isl_basic_map_copy(map1->p[i]),
  3374. isl_basic_map_copy(map2->p[j]));
  3375. if (isl_basic_map_is_empty(part) < 0)
  3376. part = isl_basic_map_free(part);
  3377. result = isl_map_add_basic_map(result, part);
  3378. if (!result)
  3379. goto error;
  3380. }
  3381. isl_map_free(map1);
  3382. isl_map_free(map2);
  3383. return result;
  3384. error:
  3385. isl_map_free(map1);
  3386. isl_map_free(map2);
  3387. return NULL;
  3388. }
  3389. static __isl_give isl_map *map_intersect(__isl_take isl_map *map1,
  3390. __isl_take isl_map *map2)
  3391. {
  3392. if (isl_map_check_equal_space(map1, map2) < 0)
  3393. goto error;
  3394. return map_intersect_internal(map1, map2);
  3395. error:
  3396. isl_map_free(map1);
  3397. isl_map_free(map2);
  3398. return NULL;
  3399. }
  3400. __isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
  3401. __isl_take isl_map *map2)
  3402. {
  3403. isl_map_align_params_bin(&map1, &map2);
  3404. return map_intersect(map1, map2);
  3405. }
  3406. __isl_give isl_set *isl_set_intersect(__isl_take isl_set *set1,
  3407. __isl_take isl_set *set2)
  3408. {
  3409. return set_from_map(isl_map_intersect(set_to_map(set1),
  3410. set_to_map(set2)));
  3411. }
  3412. /* map_intersect_internal accepts intersections
  3413. * with parameter domains, so we can just call that function.
  3414. */
  3415. __isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map,
  3416. __isl_take isl_set *params)
  3417. {
  3418. isl_map_align_params_set(&map, &params);
  3419. return map_intersect_internal(map, params);
  3420. }
  3421. __isl_give isl_set *isl_set_intersect_params(__isl_take isl_set *set,
  3422. __isl_take isl_set *params)
  3423. {
  3424. return isl_map_intersect_params(set, params);
  3425. }
  3426. __isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap)
  3427. {
  3428. isl_space *space;
  3429. unsigned pos;
  3430. isl_size n1, n2;
  3431. if (!bmap)
  3432. return NULL;
  3433. bmap = isl_basic_map_cow(bmap);
  3434. if (!bmap)
  3435. return NULL;
  3436. space = isl_space_reverse(isl_space_copy(bmap->dim));
  3437. pos = isl_basic_map_offset(bmap, isl_dim_in);
  3438. n1 = isl_basic_map_dim(bmap, isl_dim_in);
  3439. n2 = isl_basic_map_dim(bmap, isl_dim_out);
  3440. if (n1 < 0 || n2 < 0)
  3441. bmap = isl_basic_map_free(bmap);
  3442. bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
  3443. return isl_basic_map_reset_space(bmap, space);
  3444. }
  3445. /* Given a basic map A -> (B -> C), return the corresponding basic map
  3446. * A -> (C -> B).
  3447. */
  3448. static __isl_give isl_basic_map *isl_basic_map_range_reverse(
  3449. __isl_take isl_basic_map *bmap)
  3450. {
  3451. isl_space *space;
  3452. isl_size offset, n1, n2;
  3453. space = isl_basic_map_peek_space(bmap);
  3454. if (isl_space_check_range_is_wrapping(space) < 0)
  3455. return isl_basic_map_free(bmap);
  3456. offset = isl_basic_map_var_offset(bmap, isl_dim_out);
  3457. n1 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_in);
  3458. n2 = isl_space_wrapped_dim(space, isl_dim_out, isl_dim_out);
  3459. if (offset < 0 || n1 < 0 || n2 < 0)
  3460. return isl_basic_map_free(bmap);
  3461. bmap = isl_basic_map_swap_vars(bmap, 1 + offset, n1, n2);
  3462. space = isl_basic_map_take_space(bmap);
  3463. space = isl_space_range_reverse(space);
  3464. bmap = isl_basic_map_restore_space(bmap, space);
  3465. return bmap;
  3466. }
  3467. static __isl_give isl_basic_map *basic_map_space_reset(
  3468. __isl_take isl_basic_map *bmap, enum isl_dim_type type)
  3469. {
  3470. isl_space *space;
  3471. if (!bmap)
  3472. return NULL;
  3473. if (!isl_space_is_named_or_nested(bmap->dim, type))
  3474. return bmap;
  3475. space = isl_basic_map_get_space(bmap);
  3476. space = isl_space_reset(space, type);
  3477. bmap = isl_basic_map_reset_space(bmap, space);
  3478. return bmap;
  3479. }
  3480. __isl_give isl_basic_map *isl_basic_map_insert_dims(
  3481. __isl_take isl_basic_map *bmap, enum isl_dim_type type,
  3482. unsigned pos, unsigned n)
  3483. {
  3484. isl_bool rational, is_empty;
  3485. isl_space *res_space;
  3486. struct isl_basic_map *res;
  3487. struct isl_dim_map *dim_map;
  3488. isl_size total;
  3489. unsigned off;
  3490. enum isl_dim_type t;
  3491. if (n == 0)
  3492. return basic_map_space_reset(bmap, type);
  3493. is_empty = isl_basic_map_plain_is_empty(bmap);
  3494. total = isl_basic_map_dim(bmap, isl_dim_all);
  3495. if (is_empty < 0 || total < 0)
  3496. return isl_basic_map_free(bmap);
  3497. res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
  3498. type, pos, n);
  3499. if (!res_space)
  3500. return isl_basic_map_free(bmap);
  3501. if (is_empty) {
  3502. isl_basic_map_free(bmap);
  3503. return isl_basic_map_empty(res_space);
  3504. }
  3505. dim_map = isl_dim_map_alloc(bmap->ctx, total + n);
  3506. off = 0;
  3507. for (t = isl_dim_param; t <= isl_dim_out; ++t) {
  3508. isl_size dim;
  3509. if (t != type) {
  3510. isl_dim_map_dim(dim_map, bmap->dim, t, off);
  3511. } else {
  3512. isl_size size = isl_basic_map_dim(bmap, t);
  3513. if (size < 0)
  3514. dim_map = isl_dim_map_free(dim_map);
  3515. isl_dim_map_dim_range(dim_map, bmap->dim, t,
  3516. 0, pos, off);
  3517. isl_dim_map_dim_range(dim_map, bmap->dim, t,
  3518. pos, size - pos, off + pos + n);
  3519. }
  3520. dim = isl_space_dim(res_space, t);
  3521. if (dim < 0)
  3522. dim_map = isl_dim_map_free(dim_map);
  3523. off += dim;
  3524. }
  3525. isl_dim_map_div(dim_map, bmap, off);
  3526. res = isl_basic_map_alloc_space(res_space,
  3527. bmap->n_div, bmap->n_eq, bmap->n_ineq);
  3528. rational = isl_basic_map_is_rational(bmap);
  3529. if (rational < 0)
  3530. res = isl_basic_map_free(res);
  3531. if (rational)
  3532. res = isl_basic_map_set_rational(res);
  3533. res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
  3534. return isl_basic_map_finalize(res);
  3535. }
  3536. __isl_give isl_basic_set *isl_basic_set_insert_dims(
  3537. __isl_take isl_basic_set *bset,
  3538. enum isl_dim_type type, unsigned pos, unsigned n)
  3539. {
  3540. return isl_basic_map_insert_dims(bset, type, pos, n);
  3541. }
  3542. __isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap,
  3543. enum isl_dim_type type, unsigned n)
  3544. {
  3545. isl_size dim;
  3546. dim = isl_basic_map_dim(bmap, type);
  3547. if (dim < 0)
  3548. return isl_basic_map_free(bmap);
  3549. return isl_basic_map_insert_dims(bmap, type, dim, n);
  3550. }
  3551. __isl_give isl_basic_set *isl_basic_set_add_dims(__isl_take isl_basic_set *bset,
  3552. enum isl_dim_type type, unsigned n)
  3553. {
  3554. if (!bset)
  3555. return NULL;
  3556. isl_assert(bset->ctx, type != isl_dim_in, goto error);
  3557. return isl_basic_map_add_dims(bset, type, n);
  3558. error:
  3559. isl_basic_set_free(bset);
  3560. return NULL;
  3561. }
  3562. static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
  3563. enum isl_dim_type type)
  3564. {
  3565. isl_space *space;
  3566. if (!map || !isl_space_is_named_or_nested(map->dim, type))
  3567. return map;
  3568. space = isl_map_get_space(map);
  3569. space = isl_space_reset(space, type);
  3570. map = isl_map_reset_space(map, space);
  3571. return map;
  3572. }
  3573. __isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
  3574. enum isl_dim_type type, unsigned pos, unsigned n)
  3575. {
  3576. int i;
  3577. isl_space *space;
  3578. if (n == 0)
  3579. return map_space_reset(map, type);
  3580. map = isl_map_cow(map);
  3581. if (!map)
  3582. return NULL;
  3583. for (i = 0; i < map->n; ++i) {
  3584. map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
  3585. if (!map->p[i])
  3586. goto error;
  3587. }
  3588. space = isl_map_take_space(map);
  3589. space = isl_space_insert_dims(space, type, pos, n);
  3590. map = isl_map_restore_space(map, space);
  3591. return map;
  3592. error:
  3593. isl_map_free(map);
  3594. return NULL;
  3595. }
  3596. __isl_give isl_set *isl_set_insert_dims(__isl_take isl_set *set,
  3597. enum isl_dim_type type, unsigned pos, unsigned n)
  3598. {
  3599. return isl_map_insert_dims(set, type, pos, n);
  3600. }
  3601. __isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
  3602. enum isl_dim_type type, unsigned n)
  3603. {
  3604. isl_size dim;
  3605. dim = isl_map_dim(map, type);
  3606. if (dim < 0)
  3607. return isl_map_free(map);
  3608. return isl_map_insert_dims(map, type, dim, n);
  3609. }
  3610. __isl_give isl_set *isl_set_add_dims(__isl_take isl_set *set,
  3611. enum isl_dim_type type, unsigned n)
  3612. {
  3613. if (!set)
  3614. return NULL;
  3615. isl_assert(set->ctx, type != isl_dim_in, goto error);
  3616. return set_from_map(isl_map_add_dims(set_to_map(set), type, n));
  3617. error:
  3618. isl_set_free(set);
  3619. return NULL;
  3620. }
  3621. __isl_give isl_basic_map *isl_basic_map_move_dims(
  3622. __isl_take isl_basic_map *bmap,
  3623. enum isl_dim_type dst_type, unsigned dst_pos,
  3624. enum isl_dim_type src_type, unsigned src_pos, unsigned n)
  3625. {
  3626. isl_space *space;
  3627. struct isl_dim_map *dim_map;
  3628. struct isl_basic_map *res;
  3629. enum isl_dim_type t;
  3630. isl_size total;
  3631. unsigned off;
  3632. if (!bmap)
  3633. return NULL;
  3634. if (n == 0) {
  3635. bmap = isl_basic_map_reset(bmap, src_type);
  3636. bmap = isl_basic_map_reset(bmap, dst_type);
  3637. return bmap;
  3638. }
  3639. if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0)
  3640. return isl_basic_map_free(bmap);
  3641. if (dst_type == src_type && dst_pos == src_pos)
  3642. return bmap;
  3643. isl_assert(bmap->ctx, dst_type != src_type, goto error);
  3644. if (pos(bmap->dim, dst_type) + dst_pos ==
  3645. pos(bmap->dim, src_type) + src_pos +
  3646. ((src_type < dst_type) ? n : 0)) {
  3647. space = isl_basic_map_take_space(bmap);
  3648. space = isl_space_move_dims(space, dst_type, dst_pos,
  3649. src_type, src_pos, n);
  3650. bmap = isl_basic_map_restore_space(bmap, space);
  3651. bmap = isl_basic_map_finalize(bmap);
  3652. return bmap;
  3653. }
  3654. total = isl_basic_map_dim(bmap, isl_dim_all);
  3655. if (total < 0)
  3656. return isl_basic_map_free(bmap);
  3657. dim_map = isl_dim_map_alloc(bmap->ctx, total);
  3658. off = 0;
  3659. space = isl_basic_map_peek_space(bmap);
  3660. for (t = isl_dim_param; t <= isl_dim_out; ++t) {
  3661. isl_size size = isl_space_dim(space, t);
  3662. if (size < 0)
  3663. dim_map = isl_dim_map_free(dim_map);
  3664. if (t == dst_type) {
  3665. isl_dim_map_dim_range(dim_map, space, t,
  3666. 0, dst_pos, off);
  3667. off += dst_pos;
  3668. isl_dim_map_dim_range(dim_map, space, src_type,
  3669. src_pos, n, off);
  3670. off += n;
  3671. isl_dim_map_dim_range(dim_map, space, t,
  3672. dst_pos, size - dst_pos, off);
  3673. off += size - dst_pos;
  3674. } else if (t == src_type) {
  3675. isl_dim_map_dim_range(dim_map, space, t,
  3676. 0, src_pos, off);
  3677. off += src_pos;
  3678. isl_dim_map_dim_range(dim_map, space, t,
  3679. src_pos + n, size - src_pos - n, off);
  3680. off += size - src_pos - n;
  3681. } else {
  3682. isl_dim_map_dim(dim_map, space, t, off);
  3683. off += size;
  3684. }
  3685. }
  3686. isl_dim_map_div(dim_map, bmap, off);
  3687. res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
  3688. bmap->n_div, bmap->n_eq, bmap->n_ineq);
  3689. bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
  3690. space = isl_basic_map_take_space(bmap);
  3691. space = isl_space_move_dims(space, dst_type, dst_pos,
  3692. src_type, src_pos, n);
  3693. bmap = isl_basic_map_restore_space(bmap, space);
  3694. if (!bmap)
  3695. goto error;
  3696. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  3697. bmap = isl_basic_map_gauss(bmap, NULL);
  3698. bmap = isl_basic_map_finalize(bmap);
  3699. return bmap;
  3700. error:
  3701. isl_basic_map_free(bmap);
  3702. return NULL;
  3703. }
  3704. __isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset,
  3705. enum isl_dim_type dst_type, unsigned dst_pos,
  3706. enum isl_dim_type src_type, unsigned src_pos, unsigned n)
  3707. {
  3708. isl_basic_map *bmap = bset_to_bmap(bset);
  3709. bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos,
  3710. src_type, src_pos, n);
  3711. return bset_from_bmap(bmap);
  3712. }
  3713. __isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set,
  3714. enum isl_dim_type dst_type, unsigned dst_pos,
  3715. enum isl_dim_type src_type, unsigned src_pos, unsigned n)
  3716. {
  3717. if (!set)
  3718. return NULL;
  3719. isl_assert(set->ctx, dst_type != isl_dim_in, goto error);
  3720. return set_from_map(isl_map_move_dims(set_to_map(set),
  3721. dst_type, dst_pos, src_type, src_pos, n));
  3722. error:
  3723. isl_set_free(set);
  3724. return NULL;
  3725. }
  3726. __isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
  3727. enum isl_dim_type dst_type, unsigned dst_pos,
  3728. enum isl_dim_type src_type, unsigned src_pos, unsigned n)
  3729. {
  3730. int i;
  3731. isl_space *space;
  3732. if (n == 0) {
  3733. map = isl_map_reset(map, src_type);
  3734. map = isl_map_reset(map, dst_type);
  3735. return map;
  3736. }
  3737. if (isl_map_check_range(map, src_type, src_pos, n))
  3738. return isl_map_free(map);
  3739. if (dst_type == src_type && dst_pos == src_pos)
  3740. return map;
  3741. isl_assert(map->ctx, dst_type != src_type, goto error);
  3742. map = isl_map_cow(map);
  3743. if (!map)
  3744. return NULL;
  3745. for (i = 0; i < map->n; ++i) {
  3746. map->p[i] = isl_basic_map_move_dims(map->p[i],
  3747. dst_type, dst_pos,
  3748. src_type, src_pos, n);
  3749. if (!map->p[i])
  3750. goto error;
  3751. }
  3752. space = isl_map_take_space(map);
  3753. space = isl_space_move_dims(space, dst_type, dst_pos,
  3754. src_type, src_pos, n);
  3755. map = isl_map_restore_space(map, space);
  3756. return map;
  3757. error:
  3758. isl_map_free(map);
  3759. return NULL;
  3760. }
  3761. /* Move the specified dimensions to the last columns right before
  3762. * the divs. Don't change the dimension specification of bmap.
  3763. * That's the responsibility of the caller.
  3764. */
  3765. static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
  3766. enum isl_dim_type type, unsigned first, unsigned n)
  3767. {
  3768. isl_space *space;
  3769. struct isl_dim_map *dim_map;
  3770. struct isl_basic_map *res;
  3771. enum isl_dim_type t;
  3772. isl_size total;
  3773. unsigned off;
  3774. if (!bmap)
  3775. return NULL;
  3776. if (isl_basic_map_offset(bmap, type) + first + n ==
  3777. isl_basic_map_offset(bmap, isl_dim_div))
  3778. return bmap;
  3779. total = isl_basic_map_dim(bmap, isl_dim_all);
  3780. if (total < 0)
  3781. return isl_basic_map_free(bmap);
  3782. dim_map = isl_dim_map_alloc(bmap->ctx, total);
  3783. off = 0;
  3784. space = isl_basic_map_peek_space(bmap);
  3785. for (t = isl_dim_param; t <= isl_dim_out; ++t) {
  3786. isl_size size = isl_space_dim(space, t);
  3787. if (size < 0)
  3788. dim_map = isl_dim_map_free(dim_map);
  3789. if (t == type) {
  3790. isl_dim_map_dim_range(dim_map, space, t,
  3791. 0, first, off);
  3792. off += first;
  3793. isl_dim_map_dim_range(dim_map, space, t,
  3794. first, n, total - bmap->n_div - n);
  3795. isl_dim_map_dim_range(dim_map, space, t,
  3796. first + n, size - (first + n), off);
  3797. off += size - (first + n);
  3798. } else {
  3799. isl_dim_map_dim(dim_map, space, t, off);
  3800. off += size;
  3801. }
  3802. }
  3803. isl_dim_map_div(dim_map, bmap, off + n);
  3804. res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
  3805. bmap->n_div, bmap->n_eq, bmap->n_ineq);
  3806. res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
  3807. return res;
  3808. }
  3809. /* Insert "n" rows in the divs of "bmap".
  3810. *
  3811. * The number of columns is not changed, which means that the last
  3812. * dimensions of "bmap" are being reintepreted as the new divs.
  3813. * The space of "bmap" is not adjusted, however, which means
  3814. * that "bmap" is left in an inconsistent state. Removing "n" dimensions
  3815. * from the space of "bmap" is the responsibility of the caller.
  3816. */
  3817. static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap,
  3818. int n)
  3819. {
  3820. int i;
  3821. size_t row_size;
  3822. isl_int **new_div;
  3823. isl_int *old;
  3824. bmap = isl_basic_map_cow(bmap);
  3825. if (!bmap)
  3826. return NULL;
  3827. row_size = isl_basic_map_offset(bmap, isl_dim_div) + bmap->extra;
  3828. old = bmap->block2.data;
  3829. bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
  3830. (bmap->extra + n) * (1 + row_size));
  3831. if (!bmap->block2.data)
  3832. return isl_basic_map_free(bmap);
  3833. new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n);
  3834. if (!new_div)
  3835. return isl_basic_map_free(bmap);
  3836. for (i = 0; i < n; ++i) {
  3837. new_div[i] = bmap->block2.data +
  3838. (bmap->extra + i) * (1 + row_size);
  3839. isl_seq_clr(new_div[i], 1 + row_size);
  3840. }
  3841. for (i = 0; i < bmap->extra; ++i)
  3842. new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
  3843. free(bmap->div);
  3844. bmap->div = new_div;
  3845. bmap->n_div += n;
  3846. bmap->extra += n;
  3847. return bmap;
  3848. }
  3849. /* Drop constraints from "bmap" that only involve the variables
  3850. * of "type" in the range [first, first + n] that are not related
  3851. * to any of the variables outside that interval.
  3852. * These constraints cannot influence the values for the variables
  3853. * outside the interval, except in case they cause "bmap" to be empty.
  3854. * Only drop the constraints if "bmap" is known to be non-empty.
  3855. */
  3856. static __isl_give isl_basic_map *drop_irrelevant_constraints(
  3857. __isl_take isl_basic_map *bmap, enum isl_dim_type type,
  3858. unsigned first, unsigned n)
  3859. {
  3860. int i;
  3861. int *groups;
  3862. isl_size dim, n_div;
  3863. isl_bool non_empty;
  3864. non_empty = isl_basic_map_plain_is_non_empty(bmap);
  3865. if (non_empty < 0)
  3866. return isl_basic_map_free(bmap);
  3867. if (!non_empty)
  3868. return bmap;
  3869. dim = isl_basic_map_dim(bmap, isl_dim_all);
  3870. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  3871. if (dim < 0 || n_div < 0)
  3872. return isl_basic_map_free(bmap);
  3873. groups = isl_calloc_array(isl_basic_map_get_ctx(bmap), int, dim);
  3874. if (!groups)
  3875. return isl_basic_map_free(bmap);
  3876. first += isl_basic_map_offset(bmap, type) - 1;
  3877. for (i = 0; i < first; ++i)
  3878. groups[i] = -1;
  3879. for (i = first + n; i < dim - n_div; ++i)
  3880. groups[i] = -1;
  3881. bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups);
  3882. return bmap;
  3883. }
  3884. /* Turn the n dimensions of type type, starting at first
  3885. * into existentially quantified variables.
  3886. *
  3887. * If a subset of the projected out variables are unrelated
  3888. * to any of the variables that remain, then the constraints
  3889. * involving this subset are simply dropped first.
  3890. */
  3891. __isl_give isl_basic_map *isl_basic_map_project_out(
  3892. __isl_take isl_basic_map *bmap,
  3893. enum isl_dim_type type, unsigned first, unsigned n)
  3894. {
  3895. isl_bool empty;
  3896. isl_space *space;
  3897. if (n == 0)
  3898. return basic_map_space_reset(bmap, type);
  3899. if (type == isl_dim_div)
  3900. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  3901. "cannot project out existentially quantified variables",
  3902. return isl_basic_map_free(bmap));
  3903. empty = isl_basic_map_plain_is_empty(bmap);
  3904. if (empty < 0)
  3905. return isl_basic_map_free(bmap);
  3906. if (empty)
  3907. bmap = isl_basic_map_set_to_empty(bmap);
  3908. bmap = drop_irrelevant_constraints(bmap, type, first, n);
  3909. if (!bmap)
  3910. return NULL;
  3911. if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
  3912. return isl_basic_map_remove_dims(bmap, type, first, n);
  3913. if (isl_basic_map_check_range(bmap, type, first, n) < 0)
  3914. return isl_basic_map_free(bmap);
  3915. bmap = move_last(bmap, type, first, n);
  3916. bmap = isl_basic_map_cow(bmap);
  3917. bmap = insert_div_rows(bmap, n);
  3918. space = isl_basic_map_take_space(bmap);
  3919. space = isl_space_drop_dims(space, type, first, n);
  3920. bmap = isl_basic_map_restore_space(bmap, space);
  3921. bmap = isl_basic_map_simplify(bmap);
  3922. bmap = isl_basic_map_drop_redundant_divs(bmap);
  3923. return isl_basic_map_finalize(bmap);
  3924. }
  3925. /* Turn the n dimensions of type type, starting at first
  3926. * into existentially quantified variables.
  3927. */
  3928. __isl_give isl_basic_set *isl_basic_set_project_out(
  3929. __isl_take isl_basic_set *bset, enum isl_dim_type type,
  3930. unsigned first, unsigned n)
  3931. {
  3932. return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset),
  3933. type, first, n));
  3934. }
  3935. /* Turn the n dimensions of type type, starting at first
  3936. * into existentially quantified variables.
  3937. */
  3938. __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
  3939. enum isl_dim_type type, unsigned first, unsigned n)
  3940. {
  3941. int i;
  3942. isl_space *space;
  3943. if (n == 0)
  3944. return map_space_reset(map, type);
  3945. if (isl_map_check_range(map, type, first, n) < 0)
  3946. return isl_map_free(map);
  3947. map = isl_map_cow(map);
  3948. if (!map)
  3949. return NULL;
  3950. for (i = 0; i < map->n; ++i) {
  3951. map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
  3952. if (!map->p[i])
  3953. goto error;
  3954. }
  3955. if (map->n > 1)
  3956. ISL_F_CLR(map, ISL_MAP_DISJOINT);
  3957. map = isl_map_unmark_normalized(map);
  3958. space = isl_map_take_space(map);
  3959. space = isl_space_drop_dims(space, type, first, n);
  3960. map = isl_map_restore_space(map, space);
  3961. return map;
  3962. error:
  3963. isl_map_free(map);
  3964. return NULL;
  3965. }
  3966. #undef TYPE
  3967. #define TYPE isl_map
  3968. #include "isl_project_out_all_params_templ.c"
  3969. /* Turn all the dimensions of type "type", except the "n" starting at "first"
  3970. * into existentially quantified variables.
  3971. */
  3972. __isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map,
  3973. enum isl_dim_type type, unsigned first, unsigned n)
  3974. {
  3975. isl_size dim;
  3976. dim = isl_map_dim(map, type);
  3977. if (isl_map_check_range(map, type, first, n) < 0 || dim < 0)
  3978. return isl_map_free(map);
  3979. map = isl_map_project_out(map, type, first + n, dim - (first + n));
  3980. map = isl_map_project_out(map, type, 0, first);
  3981. return map;
  3982. }
  3983. /* Turn the n dimensions of type type, starting at first
  3984. * into existentially quantified variables.
  3985. */
  3986. __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set,
  3987. enum isl_dim_type type, unsigned first, unsigned n)
  3988. {
  3989. return set_from_map(isl_map_project_out(set_to_map(set),
  3990. type, first, n));
  3991. }
  3992. /* If "set" involves a parameter with identifier "id",
  3993. * then turn it into an existentially quantified variable.
  3994. */
  3995. __isl_give isl_set *isl_set_project_out_param_id(__isl_take isl_set *set,
  3996. __isl_take isl_id *id)
  3997. {
  3998. int pos;
  3999. if (!set || !id)
  4000. goto error;
  4001. pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
  4002. isl_id_free(id);
  4003. if (pos < 0)
  4004. return set;
  4005. return isl_set_project_out(set, isl_dim_param, pos, 1);
  4006. error:
  4007. isl_set_free(set);
  4008. isl_id_free(id);
  4009. return NULL;
  4010. }
  4011. /* If "set" involves any of the parameters with identifiers in "list",
  4012. * then turn them into existentially quantified variables.
  4013. */
  4014. __isl_give isl_set *isl_set_project_out_param_id_list(__isl_take isl_set *set,
  4015. __isl_take isl_id_list *list)
  4016. {
  4017. int i;
  4018. isl_size n;
  4019. n = isl_id_list_size(list);
  4020. if (n < 0)
  4021. goto error;
  4022. for (i = 0; i < n; ++i) {
  4023. isl_id *id;
  4024. id = isl_id_list_get_at(list, i);
  4025. set = isl_set_project_out_param_id(set, id);
  4026. }
  4027. isl_id_list_free(list);
  4028. return set;
  4029. error:
  4030. isl_id_list_free(list);
  4031. isl_set_free(set);
  4032. return NULL;
  4033. }
  4034. /* Project out all parameters from "set" by existentially quantifying
  4035. * over them.
  4036. */
  4037. __isl_give isl_set *isl_set_project_out_all_params(__isl_take isl_set *set)
  4038. {
  4039. return set_from_map(isl_map_project_out_all_params(set_to_map(set)));
  4040. }
  4041. /* Return a map that projects the elements in "set" onto their
  4042. * "n" set dimensions starting at "first".
  4043. * "type" should be equal to isl_dim_set.
  4044. */
  4045. __isl_give isl_map *isl_set_project_onto_map(__isl_take isl_set *set,
  4046. enum isl_dim_type type, unsigned first, unsigned n)
  4047. {
  4048. int i;
  4049. isl_map *map;
  4050. if (type != isl_dim_set)
  4051. isl_die(isl_set_get_ctx(set), isl_error_invalid,
  4052. "only set dimensions can be projected out", goto error);
  4053. if (isl_set_check_range(set, type, first, n) < 0)
  4054. return isl_set_free(set);
  4055. map = isl_map_from_domain(set);
  4056. map = isl_map_add_dims(map, isl_dim_out, n);
  4057. for (i = 0; i < n; ++i)
  4058. map = isl_map_equate(map, isl_dim_in, first + i,
  4059. isl_dim_out, i);
  4060. return map;
  4061. error:
  4062. isl_set_free(set);
  4063. return NULL;
  4064. }
  4065. static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
  4066. unsigned n)
  4067. {
  4068. int i, j;
  4069. isl_size total;
  4070. total = isl_basic_map_dim(bmap, isl_dim_all);
  4071. if (total < 0)
  4072. return isl_basic_map_free(bmap);
  4073. for (i = 0; i < n; ++i) {
  4074. j = isl_basic_map_alloc_div(bmap);
  4075. if (j < 0)
  4076. goto error;
  4077. isl_seq_clr(bmap->div[j], 1 + 1 + total);
  4078. }
  4079. return bmap;
  4080. error:
  4081. isl_basic_map_free(bmap);
  4082. return NULL;
  4083. }
  4084. /* Does "bmap2" apply to the range of "bmap1" (ignoring parameters)?
  4085. */
  4086. isl_bool isl_basic_map_applies_range(__isl_keep isl_basic_map *bmap1,
  4087. __isl_keep isl_basic_map *bmap2)
  4088. {
  4089. isl_space *space1, *space2;
  4090. space1 = isl_basic_map_peek_space(bmap1);
  4091. space2 = isl_basic_map_peek_space(bmap2);
  4092. return isl_space_tuple_is_equal(space1, isl_dim_out,
  4093. space2, isl_dim_in);
  4094. }
  4095. /* Check that "bmap2" applies to the range of "bmap1" (ignoring parameters).
  4096. */
  4097. static isl_stat isl_basic_map_check_applies_range(
  4098. __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
  4099. {
  4100. isl_bool equal;
  4101. equal = isl_basic_map_applies_range(bmap1, bmap2);
  4102. if (equal < 0)
  4103. return isl_stat_error;
  4104. if (!equal)
  4105. isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
  4106. "spaces don't match", return isl_stat_error);
  4107. return isl_stat_ok;
  4108. }
  4109. __isl_give isl_basic_map *isl_basic_map_apply_range(
  4110. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  4111. {
  4112. isl_space *space_result = NULL;
  4113. struct isl_basic_map *bmap;
  4114. isl_size n_in, n_out, n, nparam;
  4115. unsigned total, pos;
  4116. struct isl_dim_map *dim_map1, *dim_map2;
  4117. if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
  4118. goto error;
  4119. if (isl_basic_map_check_applies_range(bmap1, bmap2) < 0)
  4120. goto error;
  4121. n_in = isl_basic_map_dim(bmap1, isl_dim_in);
  4122. n_out = isl_basic_map_dim(bmap2, isl_dim_out);
  4123. n = isl_basic_map_dim(bmap1, isl_dim_out);
  4124. nparam = isl_basic_map_dim(bmap1, isl_dim_param);
  4125. if (n_in < 0 || n_out < 0 || n < 0 || nparam < 0)
  4126. goto error;
  4127. space_result = isl_space_join(isl_basic_map_get_space(bmap1),
  4128. isl_basic_map_get_space(bmap2));
  4129. total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
  4130. dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
  4131. dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
  4132. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
  4133. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
  4134. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
  4135. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
  4136. isl_dim_map_div(dim_map1, bmap1, pos += n_out);
  4137. isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
  4138. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
  4139. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
  4140. bmap = isl_basic_map_alloc_space(space_result,
  4141. bmap1->n_div + bmap2->n_div + n,
  4142. bmap1->n_eq + bmap2->n_eq,
  4143. bmap1->n_ineq + bmap2->n_ineq);
  4144. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
  4145. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
  4146. bmap = add_divs(bmap, n);
  4147. bmap = isl_basic_map_simplify(bmap);
  4148. bmap = isl_basic_map_drop_redundant_divs(bmap);
  4149. return isl_basic_map_finalize(bmap);
  4150. error:
  4151. isl_basic_map_free(bmap1);
  4152. isl_basic_map_free(bmap2);
  4153. return NULL;
  4154. }
  4155. __isl_give isl_basic_set *isl_basic_set_apply(__isl_take isl_basic_set *bset,
  4156. __isl_take isl_basic_map *bmap)
  4157. {
  4158. if (isl_basic_map_check_compatible_domain(bmap, bset) < 0)
  4159. goto error;
  4160. return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset),
  4161. bmap));
  4162. error:
  4163. isl_basic_set_free(bset);
  4164. isl_basic_map_free(bmap);
  4165. return NULL;
  4166. }
  4167. __isl_give isl_basic_map *isl_basic_map_apply_domain(
  4168. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  4169. {
  4170. if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
  4171. goto error;
  4172. if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in,
  4173. bmap2->dim, isl_dim_in))
  4174. isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
  4175. "spaces don't match", goto error);
  4176. bmap1 = isl_basic_map_reverse(bmap1);
  4177. bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
  4178. return isl_basic_map_reverse(bmap1);
  4179. error:
  4180. isl_basic_map_free(bmap1);
  4181. isl_basic_map_free(bmap2);
  4182. return NULL;
  4183. }
  4184. /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
  4185. * A \cap B -> f(A) + f(B)
  4186. */
  4187. __isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1,
  4188. __isl_take isl_basic_map *bmap2)
  4189. {
  4190. isl_size n_in, n_out, nparam;
  4191. unsigned total, pos;
  4192. struct isl_basic_map *bmap = NULL;
  4193. struct isl_dim_map *dim_map1, *dim_map2;
  4194. int i;
  4195. if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
  4196. goto error;
  4197. nparam = isl_basic_map_dim(bmap1, isl_dim_param);
  4198. n_in = isl_basic_map_dim(bmap1, isl_dim_in);
  4199. n_out = isl_basic_map_dim(bmap1, isl_dim_out);
  4200. if (nparam < 0 || n_in < 0 || n_out < 0)
  4201. goto error;
  4202. total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
  4203. dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
  4204. dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
  4205. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
  4206. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
  4207. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
  4208. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
  4209. isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
  4210. isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
  4211. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
  4212. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
  4213. bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
  4214. bmap1->n_div + bmap2->n_div + 2 * n_out,
  4215. bmap1->n_eq + bmap2->n_eq + n_out,
  4216. bmap1->n_ineq + bmap2->n_ineq);
  4217. for (i = 0; i < n_out; ++i) {
  4218. int j = isl_basic_map_alloc_equality(bmap);
  4219. if (j < 0)
  4220. goto error;
  4221. isl_seq_clr(bmap->eq[j], 1+total);
  4222. isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1);
  4223. isl_int_set_si(bmap->eq[j][1+pos+i], 1);
  4224. isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1);
  4225. }
  4226. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
  4227. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
  4228. bmap = add_divs(bmap, 2 * n_out);
  4229. bmap = isl_basic_map_simplify(bmap);
  4230. return isl_basic_map_finalize(bmap);
  4231. error:
  4232. isl_basic_map_free(bmap);
  4233. isl_basic_map_free(bmap1);
  4234. isl_basic_map_free(bmap2);
  4235. return NULL;
  4236. }
  4237. /* Given two maps A -> f(A) and B -> g(B), construct a map
  4238. * A \cap B -> f(A) + f(B)
  4239. */
  4240. __isl_give isl_map *isl_map_sum(__isl_take isl_map *map1,
  4241. __isl_take isl_map *map2)
  4242. {
  4243. struct isl_map *result;
  4244. int i, j;
  4245. if (isl_map_check_equal_space(map1, map2) < 0)
  4246. goto error;
  4247. result = isl_map_alloc_space(isl_space_copy(map1->dim),
  4248. map1->n * map2->n, 0);
  4249. if (!result)
  4250. goto error;
  4251. for (i = 0; i < map1->n; ++i)
  4252. for (j = 0; j < map2->n; ++j) {
  4253. struct isl_basic_map *part;
  4254. part = isl_basic_map_sum(
  4255. isl_basic_map_copy(map1->p[i]),
  4256. isl_basic_map_copy(map2->p[j]));
  4257. if (isl_basic_map_is_empty(part))
  4258. isl_basic_map_free(part);
  4259. else
  4260. result = isl_map_add_basic_map(result, part);
  4261. if (!result)
  4262. goto error;
  4263. }
  4264. isl_map_free(map1);
  4265. isl_map_free(map2);
  4266. return result;
  4267. error:
  4268. isl_map_free(map1);
  4269. isl_map_free(map2);
  4270. return NULL;
  4271. }
  4272. __isl_give isl_set *isl_set_sum(__isl_take isl_set *set1,
  4273. __isl_take isl_set *set2)
  4274. {
  4275. return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2)));
  4276. }
  4277. /* Given a basic map A -> f(A), construct A -> -f(A).
  4278. */
  4279. __isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap)
  4280. {
  4281. int i, j;
  4282. unsigned off;
  4283. isl_size n;
  4284. bmap = isl_basic_map_cow(bmap);
  4285. n = isl_basic_map_dim(bmap, isl_dim_out);
  4286. if (n < 0)
  4287. return isl_basic_map_free(bmap);
  4288. off = isl_basic_map_offset(bmap, isl_dim_out);
  4289. for (i = 0; i < bmap->n_eq; ++i)
  4290. for (j = 0; j < n; ++j)
  4291. isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]);
  4292. for (i = 0; i < bmap->n_ineq; ++i)
  4293. for (j = 0; j < n; ++j)
  4294. isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]);
  4295. for (i = 0; i < bmap->n_div; ++i)
  4296. for (j = 0; j < n; ++j)
  4297. isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]);
  4298. bmap = isl_basic_map_gauss(bmap, NULL);
  4299. return isl_basic_map_finalize(bmap);
  4300. }
  4301. __isl_give isl_basic_set *isl_basic_set_neg(__isl_take isl_basic_set *bset)
  4302. {
  4303. return isl_basic_map_neg(bset);
  4304. }
  4305. /* Given a map A -> f(A), construct A -> -f(A).
  4306. */
  4307. __isl_give isl_map *isl_map_neg(__isl_take isl_map *map)
  4308. {
  4309. int i;
  4310. map = isl_map_cow(map);
  4311. if (!map)
  4312. return NULL;
  4313. for (i = 0; i < map->n; ++i) {
  4314. map->p[i] = isl_basic_map_neg(map->p[i]);
  4315. if (!map->p[i])
  4316. goto error;
  4317. }
  4318. return map;
  4319. error:
  4320. isl_map_free(map);
  4321. return NULL;
  4322. }
  4323. __isl_give isl_set *isl_set_neg(__isl_take isl_set *set)
  4324. {
  4325. return set_from_map(isl_map_neg(set_to_map(set)));
  4326. }
  4327. /* Given a basic map A -> f(A) and an integer d, construct a basic map
  4328. * A -> floor(f(A)/d).
  4329. */
  4330. __isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap,
  4331. isl_int d)
  4332. {
  4333. isl_size n_in, n_out, nparam;
  4334. unsigned total, pos;
  4335. struct isl_basic_map *result = NULL;
  4336. struct isl_dim_map *dim_map;
  4337. int i;
  4338. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  4339. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  4340. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  4341. if (nparam < 0 || n_in < 0 || n_out < 0)
  4342. return isl_basic_map_free(bmap);
  4343. total = nparam + n_in + n_out + bmap->n_div + n_out;
  4344. dim_map = isl_dim_map_alloc(bmap->ctx, total);
  4345. isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
  4346. isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
  4347. isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
  4348. isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
  4349. result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
  4350. bmap->n_div + n_out,
  4351. bmap->n_eq, bmap->n_ineq + 2 * n_out);
  4352. result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
  4353. result = add_divs(result, n_out);
  4354. for (i = 0; i < n_out; ++i) {
  4355. int j;
  4356. j = isl_basic_map_alloc_inequality(result);
  4357. if (j < 0)
  4358. goto error;
  4359. isl_seq_clr(result->ineq[j], 1+total);
  4360. isl_int_neg(result->ineq[j][1+nparam+n_in+i], d);
  4361. isl_int_set_si(result->ineq[j][1+pos+i], 1);
  4362. j = isl_basic_map_alloc_inequality(result);
  4363. if (j < 0)
  4364. goto error;
  4365. isl_seq_clr(result->ineq[j], 1+total);
  4366. isl_int_set(result->ineq[j][1+nparam+n_in+i], d);
  4367. isl_int_set_si(result->ineq[j][1+pos+i], -1);
  4368. isl_int_sub_ui(result->ineq[j][0], d, 1);
  4369. }
  4370. result = isl_basic_map_simplify(result);
  4371. return isl_basic_map_finalize(result);
  4372. error:
  4373. isl_basic_map_free(result);
  4374. return NULL;
  4375. }
  4376. /* Given a map A -> f(A) and an integer d, construct a map
  4377. * A -> floor(f(A)/d).
  4378. */
  4379. __isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d)
  4380. {
  4381. int i;
  4382. map = isl_map_cow(map);
  4383. if (!map)
  4384. return NULL;
  4385. ISL_F_CLR(map, ISL_MAP_DISJOINT);
  4386. for (i = 0; i < map->n; ++i) {
  4387. map->p[i] = isl_basic_map_floordiv(map->p[i], d);
  4388. if (!map->p[i])
  4389. goto error;
  4390. }
  4391. map = isl_map_unmark_normalized(map);
  4392. return map;
  4393. error:
  4394. isl_map_free(map);
  4395. return NULL;
  4396. }
  4397. /* Given a map A -> f(A) and an integer d, construct a map
  4398. * A -> floor(f(A)/d).
  4399. */
  4400. __isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map,
  4401. __isl_take isl_val *d)
  4402. {
  4403. if (!map || !d)
  4404. goto error;
  4405. if (!isl_val_is_int(d))
  4406. isl_die(isl_val_get_ctx(d), isl_error_invalid,
  4407. "expecting integer denominator", goto error);
  4408. map = isl_map_floordiv(map, d->n);
  4409. isl_val_free(d);
  4410. return map;
  4411. error:
  4412. isl_map_free(map);
  4413. isl_val_free(d);
  4414. return NULL;
  4415. }
  4416. static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap,
  4417. unsigned pos)
  4418. {
  4419. int i;
  4420. isl_size nparam;
  4421. isl_size n_in;
  4422. isl_size total;
  4423. total = isl_basic_map_dim(bmap, isl_dim_all);
  4424. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  4425. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  4426. if (total < 0 || nparam < 0 || n_in < 0)
  4427. return isl_basic_map_free(bmap);
  4428. i = isl_basic_map_alloc_equality(bmap);
  4429. if (i < 0)
  4430. goto error;
  4431. isl_seq_clr(bmap->eq[i], 1 + total);
  4432. isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
  4433. isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
  4434. return isl_basic_map_finalize(bmap);
  4435. error:
  4436. isl_basic_map_free(bmap);
  4437. return NULL;
  4438. }
  4439. /* Add a constraint to "bmap" expressing i_pos < o_pos
  4440. */
  4441. static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap,
  4442. unsigned pos)
  4443. {
  4444. int i;
  4445. isl_size nparam;
  4446. isl_size n_in;
  4447. isl_size total;
  4448. total = isl_basic_map_dim(bmap, isl_dim_all);
  4449. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  4450. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  4451. if (total < 0 || nparam < 0 || n_in < 0)
  4452. return isl_basic_map_free(bmap);
  4453. i = isl_basic_map_alloc_inequality(bmap);
  4454. if (i < 0)
  4455. goto error;
  4456. isl_seq_clr(bmap->ineq[i], 1 + total);
  4457. isl_int_set_si(bmap->ineq[i][0], -1);
  4458. isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
  4459. isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
  4460. return isl_basic_map_finalize(bmap);
  4461. error:
  4462. isl_basic_map_free(bmap);
  4463. return NULL;
  4464. }
  4465. /* Add a constraint to "bmap" expressing i_pos <= o_pos
  4466. */
  4467. static __isl_give isl_basic_map *var_less_or_equal(
  4468. __isl_take isl_basic_map *bmap, unsigned pos)
  4469. {
  4470. int i;
  4471. isl_size nparam;
  4472. isl_size n_in;
  4473. isl_size total;
  4474. total = isl_basic_map_dim(bmap, isl_dim_all);
  4475. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  4476. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  4477. if (total < 0 || nparam < 0 || n_in < 0)
  4478. return isl_basic_map_free(bmap);
  4479. i = isl_basic_map_alloc_inequality(bmap);
  4480. if (i < 0)
  4481. goto error;
  4482. isl_seq_clr(bmap->ineq[i], 1 + total);
  4483. isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
  4484. isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
  4485. return isl_basic_map_finalize(bmap);
  4486. error:
  4487. isl_basic_map_free(bmap);
  4488. return NULL;
  4489. }
  4490. /* Add a constraint to "bmap" expressing i_pos > o_pos
  4491. */
  4492. static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap,
  4493. unsigned pos)
  4494. {
  4495. int i;
  4496. isl_size nparam;
  4497. isl_size n_in;
  4498. isl_size total;
  4499. total = isl_basic_map_dim(bmap, isl_dim_all);
  4500. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  4501. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  4502. if (total < 0 || nparam < 0 || n_in < 0)
  4503. return isl_basic_map_free(bmap);
  4504. i = isl_basic_map_alloc_inequality(bmap);
  4505. if (i < 0)
  4506. goto error;
  4507. isl_seq_clr(bmap->ineq[i], 1 + total);
  4508. isl_int_set_si(bmap->ineq[i][0], -1);
  4509. isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
  4510. isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
  4511. return isl_basic_map_finalize(bmap);
  4512. error:
  4513. isl_basic_map_free(bmap);
  4514. return NULL;
  4515. }
  4516. /* Add a constraint to "bmap" expressing i_pos >= o_pos
  4517. */
  4518. static __isl_give isl_basic_map *var_more_or_equal(
  4519. __isl_take isl_basic_map *bmap, unsigned pos)
  4520. {
  4521. int i;
  4522. isl_size nparam;
  4523. isl_size n_in;
  4524. isl_size total;
  4525. total = isl_basic_map_dim(bmap, isl_dim_all);
  4526. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  4527. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  4528. if (total < 0 || nparam < 0 || n_in < 0)
  4529. return isl_basic_map_free(bmap);
  4530. i = isl_basic_map_alloc_inequality(bmap);
  4531. if (i < 0)
  4532. goto error;
  4533. isl_seq_clr(bmap->ineq[i], 1 + total);
  4534. isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
  4535. isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
  4536. return isl_basic_map_finalize(bmap);
  4537. error:
  4538. isl_basic_map_free(bmap);
  4539. return NULL;
  4540. }
  4541. __isl_give isl_basic_map *isl_basic_map_equal(
  4542. __isl_take isl_space *space, unsigned n_equal)
  4543. {
  4544. int i;
  4545. struct isl_basic_map *bmap;
  4546. bmap = isl_basic_map_alloc_space(space, 0, n_equal, 0);
  4547. if (!bmap)
  4548. return NULL;
  4549. for (i = 0; i < n_equal && bmap; ++i)
  4550. bmap = var_equal(bmap, i);
  4551. return isl_basic_map_finalize(bmap);
  4552. }
  4553. /* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
  4554. */
  4555. __isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *space,
  4556. unsigned pos)
  4557. {
  4558. int i;
  4559. struct isl_basic_map *bmap;
  4560. bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
  4561. if (!bmap)
  4562. return NULL;
  4563. for (i = 0; i < pos && bmap; ++i)
  4564. bmap = var_equal(bmap, i);
  4565. if (bmap)
  4566. bmap = var_less(bmap, pos);
  4567. return isl_basic_map_finalize(bmap);
  4568. }
  4569. /* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos]
  4570. */
  4571. __isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
  4572. __isl_take isl_space *space, unsigned pos)
  4573. {
  4574. int i;
  4575. isl_basic_map *bmap;
  4576. bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
  4577. for (i = 0; i < pos; ++i)
  4578. bmap = var_equal(bmap, i);
  4579. bmap = var_less_or_equal(bmap, pos);
  4580. return isl_basic_map_finalize(bmap);
  4581. }
  4582. /* Return a relation on "space" expressing i_pos > o_pos
  4583. */
  4584. __isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space,
  4585. unsigned pos)
  4586. {
  4587. int i;
  4588. struct isl_basic_map *bmap;
  4589. bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
  4590. if (!bmap)
  4591. return NULL;
  4592. for (i = 0; i < pos && bmap; ++i)
  4593. bmap = var_equal(bmap, i);
  4594. if (bmap)
  4595. bmap = var_more(bmap, pos);
  4596. return isl_basic_map_finalize(bmap);
  4597. }
  4598. /* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
  4599. */
  4600. __isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
  4601. __isl_take isl_space *space, unsigned pos)
  4602. {
  4603. int i;
  4604. isl_basic_map *bmap;
  4605. bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
  4606. for (i = 0; i < pos; ++i)
  4607. bmap = var_equal(bmap, i);
  4608. bmap = var_more_or_equal(bmap, pos);
  4609. return isl_basic_map_finalize(bmap);
  4610. }
  4611. static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *space,
  4612. unsigned n, int equal)
  4613. {
  4614. struct isl_map *map;
  4615. int i;
  4616. if (n == 0 && equal)
  4617. return isl_map_universe(space);
  4618. map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT);
  4619. for (i = 0; i + 1 < n; ++i)
  4620. map = isl_map_add_basic_map(map,
  4621. isl_basic_map_less_at(isl_space_copy(space), i));
  4622. if (n > 0) {
  4623. if (equal)
  4624. map = isl_map_add_basic_map(map,
  4625. isl_basic_map_less_or_equal_at(space, n - 1));
  4626. else
  4627. map = isl_map_add_basic_map(map,
  4628. isl_basic_map_less_at(space, n - 1));
  4629. } else
  4630. isl_space_free(space);
  4631. return map;
  4632. }
  4633. static __isl_give isl_map *map_lex_lte(__isl_take isl_space *space, int equal)
  4634. {
  4635. if (!space)
  4636. return NULL;
  4637. return map_lex_lte_first(space, space->n_out, equal);
  4638. }
  4639. __isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *space,
  4640. unsigned n)
  4641. {
  4642. return map_lex_lte_first(space, n, 0);
  4643. }
  4644. __isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *space,
  4645. unsigned n)
  4646. {
  4647. return map_lex_lte_first(space, n, 1);
  4648. }
  4649. __isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_space)
  4650. {
  4651. return map_lex_lte(isl_space_map_from_set(set_space), 0);
  4652. }
  4653. __isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_space)
  4654. {
  4655. return map_lex_lte(isl_space_map_from_set(set_space), 1);
  4656. }
  4657. static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *space,
  4658. unsigned n, int equal)
  4659. {
  4660. struct isl_map *map;
  4661. int i;
  4662. if (n == 0 && equal)
  4663. return isl_map_universe(space);
  4664. map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT);
  4665. for (i = 0; i + 1 < n; ++i)
  4666. map = isl_map_add_basic_map(map,
  4667. isl_basic_map_more_at(isl_space_copy(space), i));
  4668. if (n > 0) {
  4669. if (equal)
  4670. map = isl_map_add_basic_map(map,
  4671. isl_basic_map_more_or_equal_at(space, n - 1));
  4672. else
  4673. map = isl_map_add_basic_map(map,
  4674. isl_basic_map_more_at(space, n - 1));
  4675. } else
  4676. isl_space_free(space);
  4677. return map;
  4678. }
  4679. static __isl_give isl_map *map_lex_gte(__isl_take isl_space *space, int equal)
  4680. {
  4681. if (!space)
  4682. return NULL;
  4683. return map_lex_gte_first(space, space->n_out, equal);
  4684. }
  4685. __isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *space,
  4686. unsigned n)
  4687. {
  4688. return map_lex_gte_first(space, n, 0);
  4689. }
  4690. __isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *space,
  4691. unsigned n)
  4692. {
  4693. return map_lex_gte_first(space, n, 1);
  4694. }
  4695. __isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_space)
  4696. {
  4697. return map_lex_gte(isl_space_map_from_set(set_space), 0);
  4698. }
  4699. __isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_space)
  4700. {
  4701. return map_lex_gte(isl_space_map_from_set(set_space), 1);
  4702. }
  4703. __isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1,
  4704. __isl_take isl_set *set2)
  4705. {
  4706. isl_map *map;
  4707. map = isl_map_lex_le(isl_set_get_space(set1));
  4708. map = isl_map_intersect_domain(map, set1);
  4709. map = isl_map_intersect_range(map, set2);
  4710. return map;
  4711. }
  4712. __isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1,
  4713. __isl_take isl_set *set2)
  4714. {
  4715. isl_map *map;
  4716. map = isl_map_lex_lt(isl_set_get_space(set1));
  4717. map = isl_map_intersect_domain(map, set1);
  4718. map = isl_map_intersect_range(map, set2);
  4719. return map;
  4720. }
  4721. __isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1,
  4722. __isl_take isl_set *set2)
  4723. {
  4724. isl_map *map;
  4725. map = isl_map_lex_ge(isl_set_get_space(set1));
  4726. map = isl_map_intersect_domain(map, set1);
  4727. map = isl_map_intersect_range(map, set2);
  4728. return map;
  4729. }
  4730. __isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1,
  4731. __isl_take isl_set *set2)
  4732. {
  4733. isl_map *map;
  4734. map = isl_map_lex_gt(isl_set_get_space(set1));
  4735. map = isl_map_intersect_domain(map, set1);
  4736. map = isl_map_intersect_range(map, set2);
  4737. return map;
  4738. }
  4739. __isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
  4740. __isl_take isl_map *map2)
  4741. {
  4742. isl_map *map;
  4743. map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
  4744. map = isl_map_apply_domain(map, isl_map_reverse(map1));
  4745. map = isl_map_apply_range(map, isl_map_reverse(map2));
  4746. return map;
  4747. }
  4748. __isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
  4749. __isl_take isl_map *map2)
  4750. {
  4751. isl_map *map;
  4752. map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
  4753. map = isl_map_apply_domain(map, isl_map_reverse(map1));
  4754. map = isl_map_apply_range(map, isl_map_reverse(map2));
  4755. return map;
  4756. }
  4757. __isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
  4758. __isl_take isl_map *map2)
  4759. {
  4760. isl_map *map;
  4761. map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
  4762. map = isl_map_apply_domain(map, isl_map_reverse(map1));
  4763. map = isl_map_apply_range(map, isl_map_reverse(map2));
  4764. return map;
  4765. }
  4766. __isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
  4767. __isl_take isl_map *map2)
  4768. {
  4769. isl_map *map;
  4770. map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
  4771. map = isl_map_apply_domain(map, isl_map_reverse(map1));
  4772. map = isl_map_apply_range(map, isl_map_reverse(map2));
  4773. return map;
  4774. }
  4775. /* For the div d = floor(f/m) at position "div", add the constraint
  4776. *
  4777. * f - m d >= 0
  4778. */
  4779. static __isl_give isl_basic_map *add_upper_div_constraint(
  4780. __isl_take isl_basic_map *bmap, unsigned div)
  4781. {
  4782. int i;
  4783. isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
  4784. isl_size n_div;
  4785. unsigned pos;
  4786. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  4787. if (v_div < 0 || n_div < 0)
  4788. return isl_basic_map_free(bmap);
  4789. pos = v_div + div;
  4790. i = isl_basic_map_alloc_inequality(bmap);
  4791. if (i < 0)
  4792. return isl_basic_map_free(bmap);
  4793. isl_seq_cpy(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
  4794. isl_int_neg(bmap->ineq[i][1 + pos], bmap->div[div][0]);
  4795. return bmap;
  4796. }
  4797. /* For the div d = floor(f/m) at position "div", add the constraint
  4798. *
  4799. * -(f-(m-1)) + m d >= 0
  4800. */
  4801. static __isl_give isl_basic_map *add_lower_div_constraint(
  4802. __isl_take isl_basic_map *bmap, unsigned div)
  4803. {
  4804. int i;
  4805. isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
  4806. isl_size n_div;
  4807. unsigned pos;
  4808. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  4809. if (v_div < 0 || n_div < 0)
  4810. return isl_basic_map_free(bmap);
  4811. pos = v_div + div;
  4812. i = isl_basic_map_alloc_inequality(bmap);
  4813. if (i < 0)
  4814. return isl_basic_map_free(bmap);
  4815. isl_seq_neg(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
  4816. isl_int_set(bmap->ineq[i][1 + pos], bmap->div[div][0]);
  4817. isl_int_add(bmap->ineq[i][0], bmap->ineq[i][0], bmap->ineq[i][1 + pos]);
  4818. isl_int_sub_ui(bmap->ineq[i][0], bmap->ineq[i][0], 1);
  4819. return bmap;
  4820. }
  4821. /* For the div d = floor(f/m) at position "pos", add the constraints
  4822. *
  4823. * f - m d >= 0
  4824. * -(f-(m-1)) + m d >= 0
  4825. *
  4826. * Note that the second constraint is the negation of
  4827. *
  4828. * f - m d >= m
  4829. */
  4830. __isl_give isl_basic_map *isl_basic_map_add_div_constraints(
  4831. __isl_take isl_basic_map *bmap, unsigned pos)
  4832. {
  4833. bmap = add_upper_div_constraint(bmap, pos);
  4834. bmap = add_lower_div_constraint(bmap, pos);
  4835. return bmap;
  4836. }
  4837. /* For each known div d = floor(f/m), add the constraints
  4838. *
  4839. * f - m d >= 0
  4840. * -(f-(m-1)) + m d >= 0
  4841. *
  4842. * Remove duplicate constraints in case of some these div constraints
  4843. * already appear in "bmap".
  4844. */
  4845. __isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
  4846. __isl_take isl_basic_map *bmap)
  4847. {
  4848. isl_size n_div;
  4849. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  4850. if (n_div < 0)
  4851. return isl_basic_map_free(bmap);
  4852. if (n_div == 0)
  4853. return bmap;
  4854. bmap = add_known_div_constraints(bmap);
  4855. bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL, 0);
  4856. bmap = isl_basic_map_finalize(bmap);
  4857. return bmap;
  4858. }
  4859. /* Add the div constraint of sign "sign" for div "div" of "bmap".
  4860. *
  4861. * In particular, if this div is of the form d = floor(f/m),
  4862. * then add the constraint
  4863. *
  4864. * f - m d >= 0
  4865. *
  4866. * if sign < 0 or the constraint
  4867. *
  4868. * -(f-(m-1)) + m d >= 0
  4869. *
  4870. * if sign > 0.
  4871. */
  4872. __isl_give isl_basic_map *isl_basic_map_add_div_constraint(
  4873. __isl_take isl_basic_map *bmap, unsigned div, int sign)
  4874. {
  4875. if (sign < 0)
  4876. return add_upper_div_constraint(bmap, div);
  4877. else
  4878. return add_lower_div_constraint(bmap, div);
  4879. }
  4880. __isl_give isl_basic_set *isl_basic_map_underlying_set(
  4881. __isl_take isl_basic_map *bmap)
  4882. {
  4883. isl_space *space;
  4884. if (!bmap)
  4885. goto error;
  4886. if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
  4887. bmap->n_div == 0 &&
  4888. !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
  4889. !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
  4890. return bset_from_bmap(bmap);
  4891. bmap = isl_basic_map_cow(bmap);
  4892. if (!bmap)
  4893. return NULL;
  4894. space = isl_basic_map_take_space(bmap);
  4895. space = isl_space_underlying(space, bmap->n_div);
  4896. bmap = isl_basic_map_restore_space(bmap, space);
  4897. if (!bmap)
  4898. return NULL;
  4899. bmap->extra -= bmap->n_div;
  4900. bmap->n_div = 0;
  4901. bmap = isl_basic_map_finalize(bmap);
  4902. return bset_from_bmap(bmap);
  4903. error:
  4904. isl_basic_map_free(bmap);
  4905. return NULL;
  4906. }
  4907. __isl_give isl_basic_set *isl_basic_set_underlying_set(
  4908. __isl_take isl_basic_set *bset)
  4909. {
  4910. return isl_basic_map_underlying_set(bset_to_bmap(bset));
  4911. }
  4912. /* Replace each element in "list" by the result of applying
  4913. * isl_basic_map_underlying_set to the element.
  4914. */
  4915. __isl_give isl_basic_set_list *isl_basic_map_list_underlying_set(
  4916. __isl_take isl_basic_map_list *list)
  4917. {
  4918. int i;
  4919. isl_size n;
  4920. n = isl_basic_map_list_n_basic_map(list);
  4921. if (n < 0)
  4922. goto error;
  4923. for (i = 0; i < n; ++i) {
  4924. isl_basic_map *bmap;
  4925. isl_basic_set *bset;
  4926. bmap = isl_basic_map_list_get_basic_map(list, i);
  4927. bset = isl_basic_set_underlying_set(bmap);
  4928. list = isl_basic_set_list_set_basic_set(list, i, bset);
  4929. }
  4930. return list;
  4931. error:
  4932. isl_basic_map_list_free(list);
  4933. return NULL;
  4934. }
  4935. __isl_give isl_basic_map *isl_basic_map_overlying_set(
  4936. __isl_take isl_basic_set *bset, __isl_take isl_basic_map *like)
  4937. {
  4938. struct isl_basic_map *bmap;
  4939. struct isl_ctx *ctx;
  4940. isl_size dim, bmap_total;
  4941. unsigned total;
  4942. int i;
  4943. if (!bset || !like)
  4944. goto error;
  4945. ctx = bset->ctx;
  4946. if (isl_basic_set_check_no_params(bset) < 0 ||
  4947. isl_basic_set_check_no_locals(bset) < 0)
  4948. goto error;
  4949. dim = isl_basic_set_dim(bset, isl_dim_set);
  4950. bmap_total = isl_basic_map_dim(like, isl_dim_all);
  4951. if (dim < 0 || bmap_total < 0)
  4952. goto error;
  4953. isl_assert(ctx, dim == bmap_total, goto error);
  4954. if (like->n_div == 0) {
  4955. isl_space *space = isl_basic_map_get_space(like);
  4956. isl_basic_map_free(like);
  4957. return isl_basic_map_reset_space(bset, space);
  4958. }
  4959. bset = isl_basic_set_cow(bset);
  4960. if (!bset)
  4961. goto error;
  4962. total = dim + bset->extra;
  4963. bmap = bset_to_bmap(bset);
  4964. isl_space_free(isl_basic_map_take_space(bmap));
  4965. bmap = isl_basic_map_restore_space(bmap, isl_basic_map_get_space(like));
  4966. if (!bmap)
  4967. goto error;
  4968. bmap->n_div = like->n_div;
  4969. bmap->extra += like->n_div;
  4970. if (bmap->extra) {
  4971. unsigned ltotal;
  4972. isl_int **div;
  4973. ltotal = total - bmap->extra + like->extra;
  4974. if (ltotal > total)
  4975. ltotal = total;
  4976. bmap->block2 = isl_blk_extend(ctx, bmap->block2,
  4977. bmap->extra * (1 + 1 + total));
  4978. if (isl_blk_is_error(bmap->block2))
  4979. goto error;
  4980. div = isl_realloc_array(ctx, bmap->div, isl_int *, bmap->extra);
  4981. if (!div)
  4982. goto error;
  4983. bmap->div = div;
  4984. for (i = 0; i < bmap->extra; ++i)
  4985. bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
  4986. for (i = 0; i < like->n_div; ++i) {
  4987. isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
  4988. isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
  4989. }
  4990. bmap = isl_basic_map_add_known_div_constraints(bmap);
  4991. }
  4992. isl_basic_map_free(like);
  4993. bmap = isl_basic_map_simplify(bmap);
  4994. bmap = isl_basic_map_finalize(bmap);
  4995. return bmap;
  4996. error:
  4997. isl_basic_map_free(like);
  4998. isl_basic_set_free(bset);
  4999. return NULL;
  5000. }
  5001. __isl_give isl_basic_set *isl_basic_set_from_underlying_set(
  5002. __isl_take isl_basic_set *bset, __isl_take isl_basic_set *like)
  5003. {
  5004. return bset_from_bmap(isl_basic_map_overlying_set(bset,
  5005. bset_to_bmap(like)));
  5006. }
  5007. __isl_give isl_set *isl_map_underlying_set(__isl_take isl_map *map)
  5008. {
  5009. int i;
  5010. map = isl_map_cow(map);
  5011. if (!map)
  5012. return NULL;
  5013. map->dim = isl_space_cow(map->dim);
  5014. if (!map->dim)
  5015. goto error;
  5016. for (i = 1; i < map->n; ++i)
  5017. isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
  5018. goto error);
  5019. for (i = 0; i < map->n; ++i) {
  5020. map->p[i] = bset_to_bmap(
  5021. isl_basic_map_underlying_set(map->p[i]));
  5022. if (!map->p[i])
  5023. goto error;
  5024. }
  5025. if (map->n == 0)
  5026. map->dim = isl_space_underlying(map->dim, 0);
  5027. else {
  5028. isl_space_free(map->dim);
  5029. map->dim = isl_space_copy(map->p[0]->dim);
  5030. }
  5031. if (!map->dim)
  5032. goto error;
  5033. return set_from_map(map);
  5034. error:
  5035. isl_map_free(map);
  5036. return NULL;
  5037. }
  5038. /* Replace the space of "bmap" by "space".
  5039. *
  5040. * If the space of "bmap" is identical to "space" (including the identifiers
  5041. * of the input and output dimensions), then simply return the original input.
  5042. */
  5043. __isl_give isl_basic_map *isl_basic_map_reset_space(
  5044. __isl_take isl_basic_map *bmap, __isl_take isl_space *space)
  5045. {
  5046. isl_bool equal;
  5047. isl_space *bmap_space;
  5048. bmap_space = isl_basic_map_peek_space(bmap);
  5049. equal = isl_space_is_equal(bmap_space, space);
  5050. if (equal >= 0 && equal)
  5051. equal = isl_space_has_equal_ids(bmap_space, space);
  5052. if (equal < 0)
  5053. goto error;
  5054. if (equal) {
  5055. isl_space_free(space);
  5056. return bmap;
  5057. }
  5058. isl_space_free(isl_basic_map_take_space(bmap));
  5059. bmap = isl_basic_map_restore_space(bmap, space);
  5060. bmap = isl_basic_map_finalize(bmap);
  5061. return bmap;
  5062. error:
  5063. isl_basic_map_free(bmap);
  5064. isl_space_free(space);
  5065. return NULL;
  5066. }
  5067. __isl_give isl_basic_set *isl_basic_set_reset_space(
  5068. __isl_take isl_basic_set *bset, __isl_take isl_space *space)
  5069. {
  5070. return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset),
  5071. space));
  5072. }
  5073. /* Check that the total dimensions of "map" and "space" are the same.
  5074. */
  5075. static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map,
  5076. __isl_keep isl_space *space)
  5077. {
  5078. isl_size dim1, dim2;
  5079. dim1 = isl_map_dim(map, isl_dim_all);
  5080. dim2 = isl_space_dim(space, isl_dim_all);
  5081. if (dim1 < 0 || dim2 < 0)
  5082. return isl_stat_error;
  5083. if (dim1 == dim2)
  5084. return isl_stat_ok;
  5085. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  5086. "total dimensions do not match", return isl_stat_error);
  5087. }
  5088. __isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
  5089. __isl_take isl_space *space)
  5090. {
  5091. int i;
  5092. map = isl_map_cow(map);
  5093. if (!map || !space)
  5094. goto error;
  5095. for (i = 0; i < map->n; ++i) {
  5096. map->p[i] = isl_basic_map_reset_space(map->p[i],
  5097. isl_space_copy(space));
  5098. if (!map->p[i])
  5099. goto error;
  5100. }
  5101. isl_space_free(isl_map_take_space(map));
  5102. map = isl_map_restore_space(map, space);
  5103. return map;
  5104. error:
  5105. isl_map_free(map);
  5106. isl_space_free(space);
  5107. return NULL;
  5108. }
  5109. /* Replace the space of "map" by "space", without modifying
  5110. * the dimension of "map".
  5111. *
  5112. * If the space of "map" is identical to "space" (including the identifiers
  5113. * of the input and output dimensions), then simply return the original input.
  5114. */
  5115. __isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map,
  5116. __isl_take isl_space *space)
  5117. {
  5118. isl_bool equal;
  5119. isl_space *map_space;
  5120. map_space = isl_map_peek_space(map);
  5121. equal = isl_space_is_equal(map_space, space);
  5122. if (equal >= 0 && equal)
  5123. equal = isl_space_has_equal_ids(map_space, space);
  5124. if (equal < 0)
  5125. goto error;
  5126. if (equal) {
  5127. isl_space_free(space);
  5128. return map;
  5129. }
  5130. if (check_map_space_equal_total_dim(map, space) < 0)
  5131. goto error;
  5132. return isl_map_reset_space(map, space);
  5133. error:
  5134. isl_map_free(map);
  5135. isl_space_free(space);
  5136. return NULL;
  5137. }
  5138. __isl_give isl_set *isl_set_reset_space(__isl_take isl_set *set,
  5139. __isl_take isl_space *space)
  5140. {
  5141. return set_from_map(isl_map_reset_space(set_to_map(set), space));
  5142. }
  5143. /* Compute the parameter domain of the given basic set.
  5144. */
  5145. __isl_give isl_basic_set *isl_basic_set_params(__isl_take isl_basic_set *bset)
  5146. {
  5147. isl_bool is_params;
  5148. isl_space *space;
  5149. isl_size n;
  5150. is_params = isl_basic_set_is_params(bset);
  5151. if (is_params < 0)
  5152. return isl_basic_set_free(bset);
  5153. if (is_params)
  5154. return bset;
  5155. n = isl_basic_set_dim(bset, isl_dim_set);
  5156. if (n < 0)
  5157. return isl_basic_set_free(bset);
  5158. bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
  5159. space = isl_basic_set_get_space(bset);
  5160. space = isl_space_params(space);
  5161. bset = isl_basic_set_reset_space(bset, space);
  5162. return bset;
  5163. }
  5164. /* Construct a zero-dimensional basic set with the given parameter domain.
  5165. */
  5166. __isl_give isl_basic_set *isl_basic_set_from_params(
  5167. __isl_take isl_basic_set *bset)
  5168. {
  5169. isl_space *space;
  5170. space = isl_basic_set_get_space(bset);
  5171. space = isl_space_set_from_params(space);
  5172. bset = isl_basic_set_reset_space(bset, space);
  5173. return bset;
  5174. }
  5175. /* Compute the parameter domain of the given set.
  5176. */
  5177. __isl_give isl_set *isl_set_params(__isl_take isl_set *set)
  5178. {
  5179. return isl_map_params(set_to_map(set));
  5180. }
  5181. /* Construct a zero-dimensional set with the given parameter domain.
  5182. */
  5183. __isl_give isl_set *isl_set_from_params(__isl_take isl_set *set)
  5184. {
  5185. isl_space *space;
  5186. space = isl_set_get_space(set);
  5187. space = isl_space_set_from_params(space);
  5188. set = isl_set_reset_space(set, space);
  5189. return set;
  5190. }
  5191. /* Compute the parameter domain of the given map.
  5192. */
  5193. __isl_give isl_set *isl_map_params(__isl_take isl_map *map)
  5194. {
  5195. isl_space *space;
  5196. isl_size n_in, n_out;
  5197. n_in = isl_map_dim(map, isl_dim_in);
  5198. n_out = isl_map_dim(map, isl_dim_out);
  5199. if (n_in < 0 || n_out < 0)
  5200. return isl_map_free(map);
  5201. map = isl_map_project_out(map, isl_dim_in, 0, n_in);
  5202. map = isl_map_project_out(map, isl_dim_out, 0, n_out);
  5203. space = isl_map_get_space(map);
  5204. space = isl_space_params(space);
  5205. map = isl_map_reset_space(map, space);
  5206. return map;
  5207. }
  5208. __isl_give isl_basic_set *isl_basic_map_domain(__isl_take isl_basic_map *bmap)
  5209. {
  5210. isl_space *space;
  5211. isl_size n_out;
  5212. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  5213. if (n_out < 0)
  5214. return isl_basic_map_free(bmap);
  5215. space = isl_space_domain(isl_basic_map_get_space(bmap));
  5216. bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out);
  5217. return isl_basic_map_reset_space(bmap, space);
  5218. }
  5219. isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
  5220. {
  5221. if (!bmap)
  5222. return isl_bool_error;
  5223. return isl_space_may_be_set(bmap->dim);
  5224. }
  5225. /* Is this basic map actually a set?
  5226. * Users should never call this function. Outside of isl,
  5227. * the type should indicate whether something is a set or a map.
  5228. */
  5229. isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
  5230. {
  5231. if (!bmap)
  5232. return isl_bool_error;
  5233. return isl_space_is_set(bmap->dim);
  5234. }
  5235. __isl_give isl_basic_set *isl_basic_map_range(__isl_take isl_basic_map *bmap)
  5236. {
  5237. isl_bool is_set;
  5238. is_set = isl_basic_map_is_set(bmap);
  5239. if (is_set < 0)
  5240. goto error;
  5241. if (is_set)
  5242. return bmap;
  5243. return isl_basic_map_domain(isl_basic_map_reverse(bmap));
  5244. error:
  5245. isl_basic_map_free(bmap);
  5246. return NULL;
  5247. }
  5248. __isl_give isl_basic_map *isl_basic_map_domain_map(
  5249. __isl_take isl_basic_map *bmap)
  5250. {
  5251. int i;
  5252. isl_space *space;
  5253. isl_basic_map *domain;
  5254. isl_size nparam, n_in, n_out;
  5255. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  5256. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  5257. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  5258. if (nparam < 0 || n_in < 0 || n_out < 0)
  5259. return isl_basic_map_free(bmap);
  5260. space = isl_basic_map_get_space(bmap);
  5261. space = isl_space_from_range(isl_space_domain(space));
  5262. domain = isl_basic_map_universe(space);
  5263. bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
  5264. bmap = isl_basic_map_apply_range(bmap, domain);
  5265. bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
  5266. for (i = 0; i < n_in; ++i)
  5267. bmap = isl_basic_map_equate(bmap, isl_dim_in, i,
  5268. isl_dim_out, i);
  5269. bmap = isl_basic_map_gauss(bmap, NULL);
  5270. return isl_basic_map_finalize(bmap);
  5271. }
  5272. __isl_give isl_basic_map *isl_basic_map_range_map(
  5273. __isl_take isl_basic_map *bmap)
  5274. {
  5275. int i;
  5276. isl_space *space;
  5277. isl_basic_map *range;
  5278. isl_size nparam, n_in, n_out;
  5279. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  5280. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  5281. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  5282. if (nparam < 0 || n_in < 0 || n_out < 0)
  5283. return isl_basic_map_free(bmap);
  5284. space = isl_basic_map_get_space(bmap);
  5285. space = isl_space_from_range(isl_space_range(space));
  5286. range = isl_basic_map_universe(space);
  5287. bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
  5288. bmap = isl_basic_map_apply_range(bmap, range);
  5289. bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
  5290. for (i = 0; i < n_out; ++i)
  5291. bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i,
  5292. isl_dim_out, i);
  5293. bmap = isl_basic_map_gauss(bmap, NULL);
  5294. return isl_basic_map_finalize(bmap);
  5295. }
  5296. int isl_map_may_be_set(__isl_keep isl_map *map)
  5297. {
  5298. if (!map)
  5299. return -1;
  5300. return isl_space_may_be_set(map->dim);
  5301. }
  5302. /* Is this map actually a set?
  5303. * Users should never call this function. Outside of isl,
  5304. * the type should indicate whether something is a set or a map.
  5305. */
  5306. isl_bool isl_map_is_set(__isl_keep isl_map *map)
  5307. {
  5308. if (!map)
  5309. return isl_bool_error;
  5310. return isl_space_is_set(map->dim);
  5311. }
  5312. __isl_give isl_set *isl_map_range(__isl_take isl_map *map)
  5313. {
  5314. isl_space *space;
  5315. isl_size n_in;
  5316. n_in = isl_map_dim(map, isl_dim_in);
  5317. if (n_in < 0)
  5318. return set_from_map(isl_map_free(map));
  5319. space = isl_space_range(isl_map_get_space(map));
  5320. map = isl_map_project_out(map, isl_dim_in, 0, n_in);
  5321. return set_from_map(isl_map_reset_space(map, space));
  5322. }
  5323. /* Transform "map" by applying "fn_space" to its space and "fn_bmap"
  5324. * to each of its basic maps.
  5325. */
  5326. static __isl_give isl_map *isl_map_transform(__isl_take isl_map *map,
  5327. __isl_give isl_space *(*fn_space)(__isl_take isl_space *space),
  5328. __isl_give isl_basic_map *(*fn_bmap)(__isl_take isl_basic_map *bmap))
  5329. {
  5330. int i;
  5331. isl_space *space;
  5332. map = isl_map_cow(map);
  5333. if (!map)
  5334. return NULL;
  5335. for (i = 0; i < map->n; ++i) {
  5336. map->p[i] = fn_bmap(map->p[i]);
  5337. if (!map->p[i])
  5338. return isl_map_free(map);
  5339. }
  5340. map = isl_map_unmark_normalized(map);
  5341. space = isl_map_take_space(map);
  5342. space = fn_space(space);
  5343. map = isl_map_restore_space(map, space);
  5344. return map;
  5345. }
  5346. __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
  5347. {
  5348. return isl_map_transform(map, &isl_space_domain_map,
  5349. &isl_basic_map_domain_map);
  5350. }
  5351. __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
  5352. {
  5353. return isl_map_transform(map, &isl_space_range_map,
  5354. &isl_basic_map_range_map);
  5355. }
  5356. /* Given a wrapped map of the form A[B -> C],
  5357. * return the map A[B -> C] -> B.
  5358. */
  5359. __isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_set *set)
  5360. {
  5361. isl_id *id;
  5362. isl_map *map;
  5363. if (!set)
  5364. return NULL;
  5365. if (!isl_set_has_tuple_id(set))
  5366. return isl_map_domain_map(isl_set_unwrap(set));
  5367. id = isl_set_get_tuple_id(set);
  5368. map = isl_map_domain_map(isl_set_unwrap(set));
  5369. map = isl_map_set_tuple_id(map, isl_dim_in, id);
  5370. return map;
  5371. }
  5372. __isl_give isl_basic_map *isl_basic_map_from_domain(
  5373. __isl_take isl_basic_set *bset)
  5374. {
  5375. return isl_basic_map_reverse(isl_basic_map_from_range(bset));
  5376. }
  5377. __isl_give isl_basic_map *isl_basic_map_from_range(
  5378. __isl_take isl_basic_set *bset)
  5379. {
  5380. isl_space *space;
  5381. space = isl_basic_set_get_space(bset);
  5382. space = isl_space_from_range(space);
  5383. bset = isl_basic_set_reset_space(bset, space);
  5384. return bset_to_bmap(bset);
  5385. }
  5386. /* Create a relation with the given set as range.
  5387. * The domain of the created relation is a zero-dimensional
  5388. * flat anonymous space.
  5389. */
  5390. __isl_give isl_map *isl_map_from_range(__isl_take isl_set *set)
  5391. {
  5392. isl_space *space;
  5393. space = isl_set_get_space(set);
  5394. space = isl_space_from_range(space);
  5395. set = isl_set_reset_space(set, space);
  5396. return set_to_map(set);
  5397. }
  5398. /* Create a relation with the given set as domain.
  5399. * The range of the created relation is a zero-dimensional
  5400. * flat anonymous space.
  5401. */
  5402. __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set)
  5403. {
  5404. return isl_map_reverse(isl_map_from_range(set));
  5405. }
  5406. __isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
  5407. __isl_take isl_basic_set *domain, __isl_take isl_basic_set *range)
  5408. {
  5409. return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
  5410. }
  5411. __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain,
  5412. __isl_take isl_set *range)
  5413. {
  5414. return isl_map_apply_range(isl_map_reverse(domain), range);
  5415. }
  5416. /* Return a newly allocated isl_map with given space and flags and
  5417. * room for "n" basic maps.
  5418. * Make sure that all cached information is cleared.
  5419. */
  5420. __isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n,
  5421. unsigned flags)
  5422. {
  5423. struct isl_map *map;
  5424. if (!space)
  5425. return NULL;
  5426. if (n < 0)
  5427. isl_die(space->ctx, isl_error_internal,
  5428. "negative number of basic maps", goto error);
  5429. map = isl_calloc(space->ctx, struct isl_map,
  5430. sizeof(struct isl_map) +
  5431. (n - 1) * sizeof(struct isl_basic_map *));
  5432. if (!map)
  5433. goto error;
  5434. map->ctx = space->ctx;
  5435. isl_ctx_ref(map->ctx);
  5436. map->ref = 1;
  5437. map->size = n;
  5438. map->n = 0;
  5439. map->dim = space;
  5440. map->flags = flags;
  5441. return map;
  5442. error:
  5443. isl_space_free(space);
  5444. return NULL;
  5445. }
  5446. __isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
  5447. {
  5448. struct isl_basic_map *bmap;
  5449. bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
  5450. bmap = isl_basic_map_set_to_empty(bmap);
  5451. return bmap;
  5452. }
  5453. __isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *space)
  5454. {
  5455. struct isl_basic_set *bset;
  5456. bset = isl_basic_set_alloc_space(space, 0, 1, 0);
  5457. bset = isl_basic_set_set_to_empty(bset);
  5458. return bset;
  5459. }
  5460. __isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
  5461. {
  5462. struct isl_basic_map *bmap;
  5463. bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
  5464. bmap = isl_basic_map_finalize(bmap);
  5465. return bmap;
  5466. }
  5467. __isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *space)
  5468. {
  5469. struct isl_basic_set *bset;
  5470. bset = isl_basic_set_alloc_space(space, 0, 0, 0);
  5471. bset = isl_basic_set_finalize(bset);
  5472. return bset;
  5473. }
  5474. __isl_give isl_basic_map *isl_basic_map_nat_universe(
  5475. __isl_take isl_space *space)
  5476. {
  5477. int i;
  5478. isl_size total = isl_space_dim(space, isl_dim_all);
  5479. isl_basic_map *bmap;
  5480. if (total < 0)
  5481. space = isl_space_free(space);
  5482. bmap = isl_basic_map_alloc_space(space, 0, 0, total);
  5483. for (i = 0; i < total; ++i) {
  5484. int k = isl_basic_map_alloc_inequality(bmap);
  5485. if (k < 0)
  5486. goto error;
  5487. isl_seq_clr(bmap->ineq[k], 1 + total);
  5488. isl_int_set_si(bmap->ineq[k][1 + i], 1);
  5489. }
  5490. return bmap;
  5491. error:
  5492. isl_basic_map_free(bmap);
  5493. return NULL;
  5494. }
  5495. __isl_give isl_basic_set *isl_basic_set_nat_universe(
  5496. __isl_take isl_space *space)
  5497. {
  5498. return isl_basic_map_nat_universe(space);
  5499. }
  5500. __isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space)
  5501. {
  5502. return isl_map_from_basic_map(isl_basic_map_nat_universe(space));
  5503. }
  5504. __isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *space)
  5505. {
  5506. return isl_map_nat_universe(space);
  5507. }
  5508. __isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
  5509. {
  5510. return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT);
  5511. }
  5512. __isl_give isl_set *isl_set_empty(__isl_take isl_space *space)
  5513. {
  5514. return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT);
  5515. }
  5516. __isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
  5517. {
  5518. struct isl_map *map;
  5519. if (!space)
  5520. return NULL;
  5521. map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
  5522. map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
  5523. return map;
  5524. }
  5525. /* This function performs the same operation as isl_map_universe,
  5526. * but is considered as a function on an isl_space when exported.
  5527. */
  5528. __isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space)
  5529. {
  5530. return isl_map_universe(space);
  5531. }
  5532. __isl_give isl_set *isl_set_universe(__isl_take isl_space *space)
  5533. {
  5534. struct isl_set *set;
  5535. if (!space)
  5536. return NULL;
  5537. set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
  5538. set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
  5539. return set;
  5540. }
  5541. /* This function performs the same operation as isl_set_universe,
  5542. * but is considered as a function on an isl_space when exported.
  5543. */
  5544. __isl_give isl_set *isl_space_universe_set(__isl_take isl_space *space)
  5545. {
  5546. return isl_set_universe(space);
  5547. }
  5548. __isl_give isl_map *isl_map_dup(__isl_keep isl_map *map)
  5549. {
  5550. int i;
  5551. struct isl_map *dup;
  5552. if (!map)
  5553. return NULL;
  5554. dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
  5555. for (i = 0; i < map->n; ++i)
  5556. dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
  5557. return dup;
  5558. }
  5559. __isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
  5560. __isl_take isl_basic_map *bmap)
  5561. {
  5562. if (!bmap || !map)
  5563. goto error;
  5564. if (isl_basic_map_plain_is_empty(bmap)) {
  5565. isl_basic_map_free(bmap);
  5566. return map;
  5567. }
  5568. if (isl_map_basic_map_check_equal_space(map, bmap) < 0)
  5569. goto error;
  5570. isl_assert(map->ctx, map->n < map->size, goto error);
  5571. map->p[map->n] = bmap;
  5572. map->n++;
  5573. map = isl_map_unmark_normalized(map);
  5574. return map;
  5575. error:
  5576. if (map)
  5577. isl_map_free(map);
  5578. if (bmap)
  5579. isl_basic_map_free(bmap);
  5580. return NULL;
  5581. }
  5582. __isl_null isl_map *isl_map_free(__isl_take isl_map *map)
  5583. {
  5584. int i;
  5585. if (!map)
  5586. return NULL;
  5587. if (--map->ref > 0)
  5588. return NULL;
  5589. clear_caches(map);
  5590. isl_ctx_deref(map->ctx);
  5591. for (i = 0; i < map->n; ++i)
  5592. isl_basic_map_free(map->p[i]);
  5593. isl_space_free(map->dim);
  5594. free(map);
  5595. return NULL;
  5596. }
  5597. static __isl_give isl_basic_map *isl_basic_map_fix_pos_si(
  5598. __isl_take isl_basic_map *bmap, unsigned pos, int value)
  5599. {
  5600. int j;
  5601. isl_size total;
  5602. total = isl_basic_map_dim(bmap, isl_dim_all);
  5603. if (total < 0)
  5604. return isl_basic_map_free(bmap);
  5605. bmap = isl_basic_map_cow(bmap);
  5606. bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
  5607. j = isl_basic_map_alloc_equality(bmap);
  5608. if (j < 0)
  5609. goto error;
  5610. isl_seq_clr(bmap->eq[j] + 1, total);
  5611. isl_int_set_si(bmap->eq[j][pos], -1);
  5612. isl_int_set_si(bmap->eq[j][0], value);
  5613. bmap = isl_basic_map_simplify(bmap);
  5614. return isl_basic_map_finalize(bmap);
  5615. error:
  5616. isl_basic_map_free(bmap);
  5617. return NULL;
  5618. }
  5619. static __isl_give isl_basic_map *isl_basic_map_fix_pos(
  5620. __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
  5621. {
  5622. int j;
  5623. isl_size total;
  5624. total = isl_basic_map_dim(bmap, isl_dim_all);
  5625. if (total < 0)
  5626. return isl_basic_map_free(bmap);
  5627. bmap = isl_basic_map_cow(bmap);
  5628. bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
  5629. j = isl_basic_map_alloc_equality(bmap);
  5630. if (j < 0)
  5631. goto error;
  5632. isl_seq_clr(bmap->eq[j] + 1, total);
  5633. isl_int_set_si(bmap->eq[j][pos], -1);
  5634. isl_int_set(bmap->eq[j][0], value);
  5635. bmap = isl_basic_map_simplify(bmap);
  5636. return isl_basic_map_finalize(bmap);
  5637. error:
  5638. isl_basic_map_free(bmap);
  5639. return NULL;
  5640. }
  5641. __isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap,
  5642. enum isl_dim_type type, unsigned pos, int value)
  5643. {
  5644. if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
  5645. return isl_basic_map_free(bmap);
  5646. return isl_basic_map_fix_pos_si(bmap,
  5647. isl_basic_map_offset(bmap, type) + pos, value);
  5648. }
  5649. __isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
  5650. enum isl_dim_type type, unsigned pos, isl_int value)
  5651. {
  5652. if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
  5653. return isl_basic_map_free(bmap);
  5654. return isl_basic_map_fix_pos(bmap,
  5655. isl_basic_map_offset(bmap, type) + pos, value);
  5656. }
  5657. /* Fix the value of the variable at position "pos" of type "type" of "bmap"
  5658. * to be equal to "v".
  5659. */
  5660. __isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap,
  5661. enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
  5662. {
  5663. if (!bmap || !v)
  5664. goto error;
  5665. if (!isl_val_is_int(v))
  5666. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  5667. "expecting integer value", goto error);
  5668. if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
  5669. goto error;
  5670. pos += isl_basic_map_offset(bmap, type);
  5671. bmap = isl_basic_map_fix_pos(bmap, pos, v->n);
  5672. isl_val_free(v);
  5673. return bmap;
  5674. error:
  5675. isl_basic_map_free(bmap);
  5676. isl_val_free(v);
  5677. return NULL;
  5678. }
  5679. /* Fix the value of the variable at position "pos" of type "type" of "bset"
  5680. * to be equal to "v".
  5681. */
  5682. __isl_give isl_basic_set *isl_basic_set_fix_val(__isl_take isl_basic_set *bset,
  5683. enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
  5684. {
  5685. return isl_basic_map_fix_val(bset, type, pos, v);
  5686. }
  5687. __isl_give isl_basic_set *isl_basic_set_fix_si(__isl_take isl_basic_set *bset,
  5688. enum isl_dim_type type, unsigned pos, int value)
  5689. {
  5690. return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
  5691. type, pos, value));
  5692. }
  5693. __isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset,
  5694. enum isl_dim_type type, unsigned pos, isl_int value)
  5695. {
  5696. return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset),
  5697. type, pos, value));
  5698. }
  5699. /* Remove the basic map at position "i" from "map" if this basic map
  5700. * is (obviously) empty.
  5701. */
  5702. static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i)
  5703. {
  5704. isl_bool empty;
  5705. if (!map)
  5706. return NULL;
  5707. empty = isl_basic_map_plain_is_empty(map->p[i]);
  5708. if (empty < 0)
  5709. return isl_map_free(map);
  5710. if (!empty)
  5711. return map;
  5712. isl_basic_map_free(map->p[i]);
  5713. map->n--;
  5714. if (i != map->n) {
  5715. map->p[i] = map->p[map->n];
  5716. map = isl_map_unmark_normalized(map);
  5717. }
  5718. return map;
  5719. }
  5720. /* Perform "fn" on each basic map of "map", where we may not be holding
  5721. * the only reference to "map".
  5722. * In particular, "fn" should be a semantics preserving operation
  5723. * that we want to apply to all copies of "map". We therefore need
  5724. * to be careful not to modify "map" in a way that breaks "map"
  5725. * in case anything goes wrong.
  5726. */
  5727. __isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
  5728. __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
  5729. {
  5730. struct isl_basic_map *bmap;
  5731. int i;
  5732. if (!map)
  5733. return NULL;
  5734. for (i = map->n - 1; i >= 0; --i) {
  5735. bmap = isl_basic_map_copy(map->p[i]);
  5736. bmap = fn(bmap);
  5737. if (!bmap)
  5738. goto error;
  5739. isl_basic_map_free(map->p[i]);
  5740. map->p[i] = bmap;
  5741. map = remove_if_empty(map, i);
  5742. if (!map)
  5743. return NULL;
  5744. }
  5745. return map;
  5746. error:
  5747. isl_map_free(map);
  5748. return NULL;
  5749. }
  5750. __isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map,
  5751. enum isl_dim_type type, unsigned pos, int value)
  5752. {
  5753. int i;
  5754. map = isl_map_cow(map);
  5755. if (isl_map_check_range(map, type, pos, 1) < 0)
  5756. return isl_map_free(map);
  5757. for (i = map->n - 1; i >= 0; --i) {
  5758. map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
  5759. map = remove_if_empty(map, i);
  5760. if (!map)
  5761. return NULL;
  5762. }
  5763. map = isl_map_unmark_normalized(map);
  5764. return map;
  5765. }
  5766. __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set,
  5767. enum isl_dim_type type, unsigned pos, int value)
  5768. {
  5769. return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value));
  5770. }
  5771. __isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
  5772. enum isl_dim_type type, unsigned pos, isl_int value)
  5773. {
  5774. int i;
  5775. map = isl_map_cow(map);
  5776. if (isl_map_check_range(map, type, pos, 1) < 0)
  5777. return isl_map_free(map);
  5778. for (i = 0; i < map->n; ++i) {
  5779. map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
  5780. if (!map->p[i])
  5781. goto error;
  5782. }
  5783. map = isl_map_unmark_normalized(map);
  5784. return map;
  5785. error:
  5786. isl_map_free(map);
  5787. return NULL;
  5788. }
  5789. __isl_give isl_set *isl_set_fix(__isl_take isl_set *set,
  5790. enum isl_dim_type type, unsigned pos, isl_int value)
  5791. {
  5792. return set_from_map(isl_map_fix(set_to_map(set), type, pos, value));
  5793. }
  5794. /* Fix the value of the variable at position "pos" of type "type" of "map"
  5795. * to be equal to "v".
  5796. */
  5797. __isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map,
  5798. enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
  5799. {
  5800. int i;
  5801. map = isl_map_cow(map);
  5802. if (!map || !v)
  5803. goto error;
  5804. if (!isl_val_is_int(v))
  5805. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  5806. "expecting integer value", goto error);
  5807. if (isl_map_check_range(map, type, pos, 1) < 0)
  5808. goto error;
  5809. for (i = map->n - 1; i >= 0; --i) {
  5810. map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos,
  5811. isl_val_copy(v));
  5812. map = remove_if_empty(map, i);
  5813. if (!map)
  5814. goto error;
  5815. }
  5816. map = isl_map_unmark_normalized(map);
  5817. isl_val_free(v);
  5818. return map;
  5819. error:
  5820. isl_map_free(map);
  5821. isl_val_free(v);
  5822. return NULL;
  5823. }
  5824. /* Fix the value of the variable at position "pos" of type "type" of "set"
  5825. * to be equal to "v".
  5826. */
  5827. __isl_give isl_set *isl_set_fix_val(__isl_take isl_set *set,
  5828. enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
  5829. {
  5830. return isl_map_fix_val(set, type, pos, v);
  5831. }
  5832. __isl_give isl_map *isl_map_fix_input_si(__isl_take isl_map *map,
  5833. unsigned input, int value)
  5834. {
  5835. return isl_map_fix_si(map, isl_dim_in, input, value);
  5836. }
  5837. __isl_give isl_set *isl_set_fix_dim_si(__isl_take isl_set *set, unsigned dim,
  5838. int value)
  5839. {
  5840. return set_from_map(isl_map_fix_si(set_to_map(set),
  5841. isl_dim_set, dim, value));
  5842. }
  5843. static __isl_give isl_basic_map *basic_map_bound_si(
  5844. __isl_take isl_basic_map *bmap,
  5845. enum isl_dim_type type, unsigned pos, int value, int upper)
  5846. {
  5847. int j;
  5848. isl_size total;
  5849. if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
  5850. return isl_basic_map_free(bmap);
  5851. total = isl_basic_map_dim(bmap, isl_dim_all);
  5852. if (total < 0)
  5853. return isl_basic_map_free(bmap);
  5854. pos += isl_basic_map_offset(bmap, type);
  5855. bmap = isl_basic_map_cow(bmap);
  5856. bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
  5857. j = isl_basic_map_alloc_inequality(bmap);
  5858. if (j < 0)
  5859. goto error;
  5860. isl_seq_clr(bmap->ineq[j], 1 + total);
  5861. if (upper) {
  5862. isl_int_set_si(bmap->ineq[j][pos], -1);
  5863. isl_int_set_si(bmap->ineq[j][0], value);
  5864. } else {
  5865. isl_int_set_si(bmap->ineq[j][pos], 1);
  5866. isl_int_set_si(bmap->ineq[j][0], -value);
  5867. }
  5868. bmap = isl_basic_map_simplify(bmap);
  5869. return isl_basic_map_finalize(bmap);
  5870. error:
  5871. isl_basic_map_free(bmap);
  5872. return NULL;
  5873. }
  5874. __isl_give isl_basic_map *isl_basic_map_lower_bound_si(
  5875. __isl_take isl_basic_map *bmap,
  5876. enum isl_dim_type type, unsigned pos, int value)
  5877. {
  5878. return basic_map_bound_si(bmap, type, pos, value, 0);
  5879. }
  5880. /* Constrain the values of the given dimension to be no greater than "value".
  5881. */
  5882. __isl_give isl_basic_map *isl_basic_map_upper_bound_si(
  5883. __isl_take isl_basic_map *bmap,
  5884. enum isl_dim_type type, unsigned pos, int value)
  5885. {
  5886. return basic_map_bound_si(bmap, type, pos, value, 1);
  5887. }
  5888. static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
  5889. enum isl_dim_type type, unsigned pos, int value, int upper)
  5890. {
  5891. int i;
  5892. map = isl_map_cow(map);
  5893. if (isl_map_check_range(map, type, pos, 1) < 0)
  5894. return isl_map_free(map);
  5895. for (i = 0; i < map->n; ++i) {
  5896. map->p[i] = basic_map_bound_si(map->p[i],
  5897. type, pos, value, upper);
  5898. if (!map->p[i])
  5899. goto error;
  5900. }
  5901. map = isl_map_unmark_normalized(map);
  5902. return map;
  5903. error:
  5904. isl_map_free(map);
  5905. return NULL;
  5906. }
  5907. __isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
  5908. enum isl_dim_type type, unsigned pos, int value)
  5909. {
  5910. return map_bound_si(map, type, pos, value, 0);
  5911. }
  5912. __isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
  5913. enum isl_dim_type type, unsigned pos, int value)
  5914. {
  5915. return map_bound_si(map, type, pos, value, 1);
  5916. }
  5917. __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set,
  5918. enum isl_dim_type type, unsigned pos, int value)
  5919. {
  5920. return set_from_map(isl_map_lower_bound_si(set_to_map(set),
  5921. type, pos, value));
  5922. }
  5923. __isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set,
  5924. enum isl_dim_type type, unsigned pos, int value)
  5925. {
  5926. return isl_map_upper_bound_si(set, type, pos, value);
  5927. }
  5928. /* Bound the given variable of "bmap" from below (or above is "upper"
  5929. * is set) to "value".
  5930. */
  5931. static __isl_give isl_basic_map *basic_map_bound(
  5932. __isl_take isl_basic_map *bmap,
  5933. enum isl_dim_type type, unsigned pos, isl_int value, int upper)
  5934. {
  5935. int j;
  5936. isl_size total;
  5937. if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
  5938. return isl_basic_map_free(bmap);
  5939. total = isl_basic_map_dim(bmap, isl_dim_all);
  5940. if (total < 0)
  5941. return isl_basic_map_free(bmap);
  5942. pos += isl_basic_map_offset(bmap, type);
  5943. bmap = isl_basic_map_cow(bmap);
  5944. bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
  5945. j = isl_basic_map_alloc_inequality(bmap);
  5946. if (j < 0)
  5947. goto error;
  5948. isl_seq_clr(bmap->ineq[j], 1 + total);
  5949. if (upper) {
  5950. isl_int_set_si(bmap->ineq[j][pos], -1);
  5951. isl_int_set(bmap->ineq[j][0], value);
  5952. } else {
  5953. isl_int_set_si(bmap->ineq[j][pos], 1);
  5954. isl_int_neg(bmap->ineq[j][0], value);
  5955. }
  5956. bmap = isl_basic_map_simplify(bmap);
  5957. return isl_basic_map_finalize(bmap);
  5958. error:
  5959. isl_basic_map_free(bmap);
  5960. return NULL;
  5961. }
  5962. /* Bound the given variable of "map" from below (or above is "upper"
  5963. * is set) to "value".
  5964. */
  5965. static __isl_give isl_map *map_bound(__isl_take isl_map *map,
  5966. enum isl_dim_type type, unsigned pos, isl_int value, int upper)
  5967. {
  5968. int i;
  5969. map = isl_map_cow(map);
  5970. if (isl_map_check_range(map, type, pos, 1) < 0)
  5971. return isl_map_free(map);
  5972. for (i = map->n - 1; i >= 0; --i) {
  5973. map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper);
  5974. map = remove_if_empty(map, i);
  5975. if (!map)
  5976. return NULL;
  5977. }
  5978. map = isl_map_unmark_normalized(map);
  5979. return map;
  5980. }
  5981. __isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map,
  5982. enum isl_dim_type type, unsigned pos, isl_int value)
  5983. {
  5984. return map_bound(map, type, pos, value, 0);
  5985. }
  5986. __isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map,
  5987. enum isl_dim_type type, unsigned pos, isl_int value)
  5988. {
  5989. return map_bound(map, type, pos, value, 1);
  5990. }
  5991. __isl_give isl_set *isl_set_lower_bound(__isl_take isl_set *set,
  5992. enum isl_dim_type type, unsigned pos, isl_int value)
  5993. {
  5994. return isl_map_lower_bound(set, type, pos, value);
  5995. }
  5996. __isl_give isl_set *isl_set_upper_bound(__isl_take isl_set *set,
  5997. enum isl_dim_type type, unsigned pos, isl_int value)
  5998. {
  5999. return isl_map_upper_bound(set, type, pos, value);
  6000. }
  6001. /* Force the values of the variable at position "pos" of type "type" of "map"
  6002. * to be no smaller than "value".
  6003. */
  6004. __isl_give isl_map *isl_map_lower_bound_val(__isl_take isl_map *map,
  6005. enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
  6006. {
  6007. if (!value)
  6008. goto error;
  6009. if (!isl_val_is_int(value))
  6010. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  6011. "expecting integer value", goto error);
  6012. map = isl_map_lower_bound(map, type, pos, value->n);
  6013. isl_val_free(value);
  6014. return map;
  6015. error:
  6016. isl_val_free(value);
  6017. isl_map_free(map);
  6018. return NULL;
  6019. }
  6020. /* Force the values of the variable at position "pos" of type "type" of "set"
  6021. * to be no smaller than "value".
  6022. */
  6023. __isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set,
  6024. enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
  6025. {
  6026. isl_map *map;
  6027. map = set_to_map(set);
  6028. return set_from_map(isl_map_lower_bound_val(map, type, pos, value));
  6029. }
  6030. /* Force the values of the variable at position "pos" of type "type" of "map"
  6031. * to be no greater than "value".
  6032. */
  6033. __isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map,
  6034. enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
  6035. {
  6036. if (!value)
  6037. goto error;
  6038. if (!isl_val_is_int(value))
  6039. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  6040. "expecting integer value", goto error);
  6041. map = isl_map_upper_bound(map, type, pos, value->n);
  6042. isl_val_free(value);
  6043. return map;
  6044. error:
  6045. isl_val_free(value);
  6046. isl_map_free(map);
  6047. return NULL;
  6048. }
  6049. /* Force the values of the variable at position "pos" of type "type" of "set"
  6050. * to be no greater than "value".
  6051. */
  6052. __isl_give isl_set *isl_set_upper_bound_val(__isl_take isl_set *set,
  6053. enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
  6054. {
  6055. isl_map *map;
  6056. map = set_to_map(set);
  6057. return set_from_map(isl_map_upper_bound_val(map, type, pos, value));
  6058. }
  6059. /* If "mv" has an explicit domain, then intersect the domain of "map"
  6060. * with this explicit domain.
  6061. *
  6062. * An isl_multi_val object never has an explicit domain,
  6063. * so simply return "map".
  6064. */
  6065. static __isl_give isl_map *isl_map_intersect_multi_val_explicit_domain(
  6066. __isl_take isl_map *map, __isl_keep isl_multi_val *mv)
  6067. {
  6068. return map;
  6069. }
  6070. #undef BASE
  6071. #define BASE val
  6072. #include "isl_map_bound_templ.c"
  6073. /* Apply "map_bound" to "set" with the corresponding value in "bound"
  6074. * for each set dimension, by treating the set as a map.
  6075. */
  6076. static __isl_give isl_set *set_bound_multi_val(__isl_take isl_set *set,
  6077. __isl_take isl_multi_val *bound,
  6078. __isl_give isl_map *map_bound(__isl_take isl_map *map,
  6079. unsigned pos, __isl_take isl_val *value))
  6080. {
  6081. isl_map *map;
  6082. map = set_to_map(set);
  6083. return set_from_map(map_bound_multi_val(map, bound, map_bound));
  6084. }
  6085. #undef BASE
  6086. #define BASE pw_aff
  6087. #include "isl_map_bound_templ.c"
  6088. /* Apply "map_bound" to "set" with the corresponding value in "bound"
  6089. * for each set dimension, by converting the set and the bound
  6090. * to objects living in a map space.
  6091. */
  6092. static __isl_give isl_set *set_bound_multi_pw_aff(__isl_take isl_set *set,
  6093. __isl_take isl_multi_pw_aff *bound,
  6094. __isl_give isl_map *set_bound(__isl_take isl_map *map,
  6095. unsigned pos, __isl_take TYPE *value))
  6096. {
  6097. isl_map *map;
  6098. map = isl_map_from_range(set);
  6099. bound = isl_multi_pw_aff_from_range(bound);
  6100. map = map_bound_multi_pw_aff(map, bound, set_bound);
  6101. return isl_map_range(map);
  6102. }
  6103. /* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val,
  6104. * setting a bound on the given output dimension.
  6105. */
  6106. static __isl_give isl_map *map_lower_bound_val(__isl_take isl_map *map,
  6107. unsigned pos, __isl_take isl_val *v)
  6108. {
  6109. return isl_map_lower_bound_val(map, isl_dim_out, pos, v);
  6110. }
  6111. /* Force the values of the set dimensions of "set"
  6112. * to be no smaller than the corresponding values in "lower".
  6113. */
  6114. __isl_give isl_set *isl_set_lower_bound_multi_val(__isl_take isl_set *set,
  6115. __isl_take isl_multi_val *lower)
  6116. {
  6117. return set_bound_multi_val(set, lower, &map_lower_bound_val);
  6118. }
  6119. /* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
  6120. * setting a bound on the given output dimension.
  6121. */
  6122. static __isl_give isl_map *map_upper_bound_val(__isl_take isl_map *map,
  6123. unsigned pos, __isl_take isl_val *v)
  6124. {
  6125. return isl_map_upper_bound_val(map, isl_dim_out, pos, v);
  6126. }
  6127. /* Force the values of the set dimensions of "set"
  6128. * to be no greater than the corresponding values in "upper".
  6129. */
  6130. __isl_give isl_set *isl_set_upper_bound_multi_val(__isl_take isl_set *set,
  6131. __isl_take isl_multi_val *upper)
  6132. {
  6133. return set_bound_multi_val(set, upper, &map_upper_bound_val);
  6134. }
  6135. /* Force the symbolic constant expression "bound"
  6136. * to satisfy the relation "order" with respect to
  6137. * the output variable at position "pos" of "map".
  6138. *
  6139. * Create an affine expression representing the output variable
  6140. * in terms of the range and
  6141. * compare it using "order" to "bound" (defined on the domain).
  6142. * The result is a relation between elements in domain and range that
  6143. * can be intersected with "map".
  6144. */
  6145. static __isl_give isl_map *map_bound_pw_aff(__isl_take isl_map *map,
  6146. unsigned pos, __isl_take isl_pw_aff *bound,
  6147. __isl_give isl_map *(*order)(__isl_take isl_pw_aff *pa1,
  6148. __isl_take isl_pw_aff *pa2))
  6149. {
  6150. isl_space *space;
  6151. isl_local_space *ls;
  6152. isl_pw_aff *var;
  6153. space = isl_space_range(isl_map_get_space(map));
  6154. ls = isl_local_space_from_space(space);
  6155. var = isl_pw_aff_var_on_domain(ls, isl_dim_set, pos);
  6156. map = isl_map_intersect(map, order(bound, var));
  6157. return map;
  6158. }
  6159. /* Force the values of the output variable at position "pos" of "map"
  6160. * to be no smaller than the symbolic constant expression "lower".
  6161. */
  6162. static __isl_give isl_map *map_lower_bound_pw_aff(__isl_take isl_map *map,
  6163. unsigned pos, __isl_take isl_pw_aff *lower)
  6164. {
  6165. return map_bound_pw_aff(map, pos, lower, &isl_pw_aff_le_map);
  6166. }
  6167. /* Force the values of the output variable at position "pos" of "map"
  6168. * to be no greater than the symbolic constant expression "upper".
  6169. */
  6170. static __isl_give isl_map *map_upper_bound_pw_aff(__isl_take isl_map *map,
  6171. unsigned pos, __isl_take isl_pw_aff *upper)
  6172. {
  6173. return map_bound_pw_aff(map, pos, upper, &isl_pw_aff_ge_map);
  6174. }
  6175. /* Force the values of the set dimensions of "set"
  6176. * to be no smaller than the corresponding constant symbolic expressions
  6177. * in "lower".
  6178. */
  6179. __isl_give isl_set *isl_set_lower_bound_multi_pw_aff(__isl_take isl_set *set,
  6180. __isl_take isl_multi_pw_aff *lower)
  6181. {
  6182. return set_bound_multi_pw_aff(set, lower, &map_lower_bound_pw_aff);
  6183. }
  6184. /* Force the values of the set dimensions of "set"
  6185. * to be no greater than the corresponding constant symbolic expressions
  6186. * in "upper".
  6187. */
  6188. __isl_give isl_set *isl_set_upper_bound_multi_pw_aff(__isl_take isl_set *set,
  6189. __isl_take isl_multi_pw_aff *upper)
  6190. {
  6191. return set_bound_multi_pw_aff(set, upper, &map_upper_bound_pw_aff);
  6192. }
  6193. /* Force the values of the output dimensions of "map"
  6194. * to be no smaller than the corresponding constant symbolic expressions
  6195. * in "lower".
  6196. */
  6197. __isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map,
  6198. __isl_take isl_multi_pw_aff *lower)
  6199. {
  6200. return map_bound_multi_pw_aff(map, lower, &map_lower_bound_pw_aff);
  6201. }
  6202. /* Force the values of the output dimensions of "map"
  6203. * to be no greater than the corresponding constant symbolic expressions
  6204. * in "upper".
  6205. */
  6206. __isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map,
  6207. __isl_take isl_multi_pw_aff *upper)
  6208. {
  6209. return map_bound_multi_pw_aff(map, upper, &map_upper_bound_pw_aff);
  6210. }
  6211. /* Bound the given variable of "bset" from below (or above is "upper"
  6212. * is set) to "value".
  6213. */
  6214. static __isl_give isl_basic_set *isl_basic_set_bound(
  6215. __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
  6216. isl_int value, int upper)
  6217. {
  6218. return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
  6219. type, pos, value, upper));
  6220. }
  6221. /* Bound the given variable of "bset" from below (or above is "upper"
  6222. * is set) to "value".
  6223. */
  6224. static __isl_give isl_basic_set *isl_basic_set_bound_val(
  6225. __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
  6226. __isl_take isl_val *value, int upper)
  6227. {
  6228. if (!value)
  6229. goto error;
  6230. if (!isl_val_is_int(value))
  6231. isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
  6232. "expecting integer value", goto error);
  6233. bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
  6234. isl_val_free(value);
  6235. return bset;
  6236. error:
  6237. isl_val_free(value);
  6238. isl_basic_set_free(bset);
  6239. return NULL;
  6240. }
  6241. /* Bound the given variable of "bset" from below to "value".
  6242. */
  6243. __isl_give isl_basic_set *isl_basic_set_lower_bound_val(
  6244. __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
  6245. __isl_take isl_val *value)
  6246. {
  6247. return isl_basic_set_bound_val(bset, type, pos, value, 0);
  6248. }
  6249. /* Bound the given variable of "bset" from above to "value".
  6250. */
  6251. __isl_give isl_basic_set *isl_basic_set_upper_bound_val(
  6252. __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
  6253. __isl_take isl_val *value)
  6254. {
  6255. return isl_basic_set_bound_val(bset, type, pos, value, 1);
  6256. }
  6257. __isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
  6258. {
  6259. return isl_map_transform(map, &isl_space_reverse,
  6260. &isl_basic_map_reverse);
  6261. }
  6262. /* Given a map A -> (B -> C), return the corresponding map A -> (C -> B).
  6263. */
  6264. __isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map)
  6265. {
  6266. return isl_map_transform(map, &isl_space_range_reverse,
  6267. &isl_basic_map_range_reverse);
  6268. }
  6269. #undef TYPE
  6270. #define TYPE isl_pw_multi_aff
  6271. #undef SUFFIX
  6272. #define SUFFIX _pw_multi_aff
  6273. #undef EMPTY
  6274. #define EMPTY isl_pw_multi_aff_empty
  6275. #undef ADD
  6276. #define ADD isl_pw_multi_aff_union_add
  6277. #include "isl_map_lexopt_templ.c"
  6278. /* Given a map "map", compute the lexicographically minimal
  6279. * (or maximal) image element for each domain element in dom,
  6280. * in the form of an isl_pw_multi_aff.
  6281. * If "empty" is not NULL, then set *empty to those elements in dom that
  6282. * do not have an image element.
  6283. * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
  6284. * should be computed over the domain of "map". "empty" is also NULL
  6285. * in this case.
  6286. *
  6287. * We first compute the lexicographically minimal or maximal element
  6288. * in the first basic map. This results in a partial solution "res"
  6289. * and a subset "todo" of dom that still need to be handled.
  6290. * We then consider each of the remaining maps in "map" and successively
  6291. * update both "res" and "todo".
  6292. * If "empty" is NULL, then the todo sets are not needed and therefore
  6293. * also not computed.
  6294. */
  6295. static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
  6296. __isl_take isl_map *map, __isl_take isl_set *dom,
  6297. __isl_give isl_set **empty, unsigned flags)
  6298. {
  6299. int i;
  6300. int full;
  6301. isl_pw_multi_aff *res;
  6302. isl_set *todo;
  6303. full = ISL_FL_ISSET(flags, ISL_OPT_FULL);
  6304. if (!map || (!full && !dom))
  6305. goto error;
  6306. if (isl_map_plain_is_empty(map)) {
  6307. if (empty)
  6308. *empty = dom;
  6309. else
  6310. isl_set_free(dom);
  6311. return isl_pw_multi_aff_from_map(map);
  6312. }
  6313. res = basic_map_partial_lexopt_pw_multi_aff(
  6314. isl_basic_map_copy(map->p[0]),
  6315. isl_set_copy(dom), empty, flags);
  6316. if (empty)
  6317. todo = *empty;
  6318. for (i = 1; i < map->n; ++i) {
  6319. isl_pw_multi_aff *res_i;
  6320. res_i = basic_map_partial_lexopt_pw_multi_aff(
  6321. isl_basic_map_copy(map->p[i]),
  6322. isl_set_copy(dom), empty, flags);
  6323. if (ISL_FL_ISSET(flags, ISL_OPT_MAX))
  6324. res = isl_pw_multi_aff_union_lexmax(res, res_i);
  6325. else
  6326. res = isl_pw_multi_aff_union_lexmin(res, res_i);
  6327. if (empty)
  6328. todo = isl_set_intersect(todo, *empty);
  6329. }
  6330. isl_set_free(dom);
  6331. isl_map_free(map);
  6332. if (empty)
  6333. *empty = todo;
  6334. return res;
  6335. error:
  6336. if (empty)
  6337. *empty = NULL;
  6338. isl_set_free(dom);
  6339. isl_map_free(map);
  6340. return NULL;
  6341. }
  6342. #undef TYPE
  6343. #define TYPE isl_map
  6344. #undef SUFFIX
  6345. #define SUFFIX
  6346. #undef EMPTY
  6347. #define EMPTY isl_map_empty
  6348. #undef ADD
  6349. #define ADD isl_map_union_disjoint
  6350. #include "isl_map_lexopt_templ.c"
  6351. /* Given a map "map", compute the lexicographically minimal
  6352. * (or maximal) image element for each domain element in "dom",
  6353. * in the form of an isl_map.
  6354. * If "empty" is not NULL, then set *empty to those elements in "dom" that
  6355. * do not have an image element.
  6356. * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
  6357. * should be computed over the domain of "map". "empty" is also NULL
  6358. * in this case.
  6359. *
  6360. * If the input consists of more than one disjunct, then first
  6361. * compute the desired result in the form of an isl_pw_multi_aff and
  6362. * then convert that into an isl_map.
  6363. *
  6364. * This function used to have an explicit implementation in terms
  6365. * of isl_maps, but it would continually intersect the domains of
  6366. * partial results with the complement of the domain of the next
  6367. * partial solution, potentially leading to an explosion in the number
  6368. * of disjuncts if there are several disjuncts in the input.
  6369. * An even earlier implementation of this function would look for
  6370. * better results in the domain of the partial result and for extra
  6371. * results in the complement of this domain, which would lead to
  6372. * even more splintering.
  6373. */
  6374. static __isl_give isl_map *isl_map_partial_lexopt_aligned(
  6375. __isl_take isl_map *map, __isl_take isl_set *dom,
  6376. __isl_give isl_set **empty, unsigned flags)
  6377. {
  6378. int full;
  6379. struct isl_map *res;
  6380. isl_pw_multi_aff *pma;
  6381. full = ISL_FL_ISSET(flags, ISL_OPT_FULL);
  6382. if (!map || (!full && !dom))
  6383. goto error;
  6384. if (isl_map_plain_is_empty(map)) {
  6385. if (empty)
  6386. *empty = dom;
  6387. else
  6388. isl_set_free(dom);
  6389. return map;
  6390. }
  6391. if (map->n == 1) {
  6392. res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
  6393. dom, empty, flags);
  6394. isl_map_free(map);
  6395. return res;
  6396. }
  6397. pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty,
  6398. flags);
  6399. return isl_map_from_pw_multi_aff_internal(pma);
  6400. error:
  6401. if (empty)
  6402. *empty = NULL;
  6403. isl_set_free(dom);
  6404. isl_map_free(map);
  6405. return NULL;
  6406. }
  6407. __isl_give isl_map *isl_map_partial_lexmax(
  6408. __isl_take isl_map *map, __isl_take isl_set *dom,
  6409. __isl_give isl_set **empty)
  6410. {
  6411. return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX);
  6412. }
  6413. __isl_give isl_map *isl_map_partial_lexmin(
  6414. __isl_take isl_map *map, __isl_take isl_set *dom,
  6415. __isl_give isl_set **empty)
  6416. {
  6417. return isl_map_partial_lexopt(map, dom, empty, 0);
  6418. }
  6419. __isl_give isl_set *isl_set_partial_lexmin(
  6420. __isl_take isl_set *set, __isl_take isl_set *dom,
  6421. __isl_give isl_set **empty)
  6422. {
  6423. return set_from_map(isl_map_partial_lexmin(set_to_map(set),
  6424. dom, empty));
  6425. }
  6426. __isl_give isl_set *isl_set_partial_lexmax(
  6427. __isl_take isl_set *set, __isl_take isl_set *dom,
  6428. __isl_give isl_set **empty)
  6429. {
  6430. return set_from_map(isl_map_partial_lexmax(set_to_map(set),
  6431. dom, empty));
  6432. }
  6433. /* Compute the lexicographic minimum (or maximum if "flags" includes
  6434. * ISL_OPT_MAX) of "bset" over its parametric domain.
  6435. */
  6436. __isl_give isl_set *isl_basic_set_lexopt(__isl_take isl_basic_set *bset,
  6437. unsigned flags)
  6438. {
  6439. return isl_basic_map_lexopt(bset, flags);
  6440. }
  6441. __isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
  6442. {
  6443. return isl_basic_map_lexopt(bmap, ISL_OPT_MAX);
  6444. }
  6445. __isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset)
  6446. {
  6447. return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset)));
  6448. }
  6449. __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
  6450. {
  6451. return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset)));
  6452. }
  6453. /* Compute the lexicographic minimum of "bset" over its parametric domain
  6454. * for the purpose of quantifier elimination.
  6455. * That is, find an explicit representation for all the existentially
  6456. * quantified variables in "bset" by computing their lexicographic
  6457. * minimum.
  6458. */
  6459. static __isl_give isl_set *isl_basic_set_lexmin_compute_divs(
  6460. __isl_take isl_basic_set *bset)
  6461. {
  6462. return isl_basic_set_lexopt(bset, ISL_OPT_QE);
  6463. }
  6464. /* Given a basic map with one output dimension, compute the minimum or
  6465. * maximum of that dimension as an isl_pw_aff.
  6466. *
  6467. * Compute the optimum as a lexicographic optimum over the single
  6468. * output dimension and extract the single isl_pw_aff from the result.
  6469. */
  6470. static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
  6471. int max)
  6472. {
  6473. isl_pw_multi_aff *pma;
  6474. isl_pw_aff *pwaff;
  6475. bmap = isl_basic_map_copy(bmap);
  6476. pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX : 0);
  6477. pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
  6478. isl_pw_multi_aff_free(pma);
  6479. return pwaff;
  6480. }
  6481. /* Compute the minimum or maximum of the given output dimension
  6482. * as a function of the parameters and the input dimensions,
  6483. * but independently of the other output dimensions.
  6484. *
  6485. * We first project out the other output dimension and then compute
  6486. * the "lexicographic" maximum in each basic map, combining the results
  6487. * using isl_pw_aff_union_max.
  6488. */
  6489. static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
  6490. int max)
  6491. {
  6492. int i;
  6493. isl_pw_aff *pwaff;
  6494. isl_size n_out;
  6495. n_out = isl_map_dim(map, isl_dim_out);
  6496. if (n_out < 0)
  6497. map = isl_map_free(map);
  6498. map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
  6499. map = isl_map_project_out(map, isl_dim_out, 0, pos);
  6500. if (!map)
  6501. return NULL;
  6502. if (map->n == 0) {
  6503. isl_space *space = isl_map_get_space(map);
  6504. isl_map_free(map);
  6505. return isl_pw_aff_empty(space);
  6506. }
  6507. pwaff = basic_map_dim_opt(map->p[0], max);
  6508. for (i = 1; i < map->n; ++i) {
  6509. isl_pw_aff *pwaff_i;
  6510. pwaff_i = basic_map_dim_opt(map->p[i], max);
  6511. pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
  6512. }
  6513. isl_map_free(map);
  6514. return pwaff;
  6515. }
  6516. /* Compute the minimum of the given output dimension as a function of the
  6517. * parameters and input dimensions, but independently of
  6518. * the other output dimensions.
  6519. */
  6520. __isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos)
  6521. {
  6522. return map_dim_opt(map, pos, 0);
  6523. }
  6524. /* Compute the maximum of the given output dimension as a function of the
  6525. * parameters and input dimensions, but independently of
  6526. * the other output dimensions.
  6527. */
  6528. __isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
  6529. {
  6530. return map_dim_opt(map, pos, 1);
  6531. }
  6532. /* Compute the minimum or maximum of the given set dimension
  6533. * as a function of the parameters,
  6534. * but independently of the other set dimensions.
  6535. */
  6536. static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos,
  6537. int max)
  6538. {
  6539. return map_dim_opt(set, pos, max);
  6540. }
  6541. /* Compute the maximum of the given set dimension as a function of the
  6542. * parameters, but independently of the other set dimensions.
  6543. */
  6544. __isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_set *set, int pos)
  6545. {
  6546. return set_dim_opt(set, pos, 1);
  6547. }
  6548. /* Compute the minimum of the given set dimension as a function of the
  6549. * parameters, but independently of the other set dimensions.
  6550. */
  6551. __isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_set *set, int pos)
  6552. {
  6553. return set_dim_opt(set, pos, 0);
  6554. }
  6555. /* Apply a preimage specified by "mat" on the parameters of "bset".
  6556. * bset is assumed to have only parameters and divs.
  6557. */
  6558. static __isl_give isl_basic_set *basic_set_parameter_preimage(
  6559. __isl_take isl_basic_set *bset, __isl_take isl_mat *mat)
  6560. {
  6561. isl_size nparam;
  6562. nparam = isl_basic_set_dim(bset, isl_dim_param);
  6563. if (nparam < 0 || !mat)
  6564. goto error;
  6565. bset->dim = isl_space_cow(bset->dim);
  6566. if (!bset->dim)
  6567. goto error;
  6568. isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error);
  6569. bset->dim->nparam = 0;
  6570. bset->dim->n_out = nparam;
  6571. bset = isl_basic_set_preimage(bset, mat);
  6572. if (bset) {
  6573. bset->dim->nparam = bset->dim->n_out;
  6574. bset->dim->n_out = 0;
  6575. }
  6576. return bset;
  6577. error:
  6578. isl_mat_free(mat);
  6579. isl_basic_set_free(bset);
  6580. return NULL;
  6581. }
  6582. /* Apply a preimage specified by "mat" on the parameters of "set".
  6583. * set is assumed to have only parameters and divs.
  6584. */
  6585. static __isl_give isl_set *set_parameter_preimage(__isl_take isl_set *set,
  6586. __isl_take isl_mat *mat)
  6587. {
  6588. isl_space *space;
  6589. isl_size nparam;
  6590. nparam = isl_set_dim(set, isl_dim_param);
  6591. if (nparam < 0 || !mat)
  6592. goto error;
  6593. if (mat->n_row != 1 + nparam)
  6594. isl_die(isl_set_get_ctx(set), isl_error_internal,
  6595. "unexpected number of rows", goto error);
  6596. space = isl_set_get_space(set);
  6597. space = isl_space_move_dims(space, isl_dim_set, 0,
  6598. isl_dim_param, 0, nparam);
  6599. set = isl_set_reset_space(set, space);
  6600. set = isl_set_preimage(set, mat);
  6601. nparam = isl_set_dim(set, isl_dim_out);
  6602. if (nparam < 0)
  6603. set = isl_set_free(set);
  6604. space = isl_set_get_space(set);
  6605. space = isl_space_move_dims(space, isl_dim_param, 0,
  6606. isl_dim_out, 0, nparam);
  6607. set = isl_set_reset_space(set, space);
  6608. return set;
  6609. error:
  6610. isl_mat_free(mat);
  6611. isl_set_free(set);
  6612. return NULL;
  6613. }
  6614. /* Intersect the basic set "bset" with the affine space specified by the
  6615. * equalities in "eq".
  6616. */
  6617. static __isl_give isl_basic_set *basic_set_append_equalities(
  6618. __isl_take isl_basic_set *bset, __isl_take isl_mat *eq)
  6619. {
  6620. int i, k;
  6621. unsigned len;
  6622. if (!bset || !eq)
  6623. goto error;
  6624. bset = isl_basic_set_extend(bset, 0, eq->n_row, 0);
  6625. if (!bset)
  6626. goto error;
  6627. len = isl_basic_set_offset(bset, isl_dim_div) + bset->extra;
  6628. for (i = 0; i < eq->n_row; ++i) {
  6629. k = isl_basic_set_alloc_equality(bset);
  6630. if (k < 0)
  6631. goto error;
  6632. isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
  6633. isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
  6634. }
  6635. isl_mat_free(eq);
  6636. bset = isl_basic_set_gauss(bset, NULL);
  6637. bset = isl_basic_set_finalize(bset);
  6638. return bset;
  6639. error:
  6640. isl_mat_free(eq);
  6641. isl_basic_set_free(bset);
  6642. return NULL;
  6643. }
  6644. /* Intersect the set "set" with the affine space specified by the
  6645. * equalities in "eq".
  6646. */
  6647. static __isl_give isl_set *set_append_equalities(__isl_take isl_set *set,
  6648. __isl_take isl_mat *eq)
  6649. {
  6650. int i;
  6651. if (!set || !eq)
  6652. goto error;
  6653. for (i = 0; i < set->n; ++i) {
  6654. set->p[i] = basic_set_append_equalities(set->p[i],
  6655. isl_mat_copy(eq));
  6656. if (!set->p[i])
  6657. goto error;
  6658. }
  6659. isl_mat_free(eq);
  6660. return set;
  6661. error:
  6662. isl_mat_free(eq);
  6663. isl_set_free(set);
  6664. return NULL;
  6665. }
  6666. /* Given a basic set "bset" that only involves parameters and existentially
  6667. * quantified variables, return the index of the first equality
  6668. * that only involves parameters. If there is no such equality then
  6669. * return bset->n_eq.
  6670. *
  6671. * This function assumes that isl_basic_set_gauss has been called on "bset".
  6672. */
  6673. static int first_parameter_equality(__isl_keep isl_basic_set *bset)
  6674. {
  6675. int i, j;
  6676. isl_size nparam, n_div;
  6677. nparam = isl_basic_set_dim(bset, isl_dim_param);
  6678. n_div = isl_basic_set_dim(bset, isl_dim_div);
  6679. if (nparam < 0 || n_div < 0)
  6680. return -1;
  6681. for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
  6682. if (!isl_int_is_zero(bset->eq[i][1 + nparam + j]))
  6683. ++i;
  6684. }
  6685. return i;
  6686. }
  6687. /* Compute an explicit representation for the existentially quantified
  6688. * variables in "bset" by computing the "minimal value" of the set
  6689. * variables. Since there are no set variables, the computation of
  6690. * the minimal value essentially computes an explicit representation
  6691. * of the non-empty part(s) of "bset".
  6692. *
  6693. * The input only involves parameters and existentially quantified variables.
  6694. * All equalities among parameters have been removed.
  6695. *
  6696. * Since the existentially quantified variables in the result are in general
  6697. * going to be different from those in the input, we first replace
  6698. * them by the minimal number of variables based on their equalities.
  6699. * This should simplify the parametric integer programming.
  6700. */
  6701. static __isl_give isl_set *base_compute_divs(__isl_take isl_basic_set *bset)
  6702. {
  6703. isl_morph *morph1, *morph2;
  6704. isl_set *set;
  6705. isl_size n;
  6706. if (!bset)
  6707. return NULL;
  6708. if (bset->n_eq == 0)
  6709. return isl_basic_set_lexmin_compute_divs(bset);
  6710. morph1 = isl_basic_set_parameter_compression(bset);
  6711. bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
  6712. bset = isl_basic_set_lift(bset);
  6713. morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
  6714. bset = isl_morph_basic_set(morph2, bset);
  6715. n = isl_basic_set_dim(bset, isl_dim_set);
  6716. if (n < 0)
  6717. bset = isl_basic_set_free(bset);
  6718. bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
  6719. set = isl_basic_set_lexmin_compute_divs(bset);
  6720. set = isl_morph_set(isl_morph_inverse(morph1), set);
  6721. return set;
  6722. }
  6723. /* Project the given basic set onto its parameter domain, possibly introducing
  6724. * new, explicit, existential variables in the constraints.
  6725. * The input has parameters and (possibly implicit) existential variables.
  6726. * The output has the same parameters, but only
  6727. * explicit existentially quantified variables.
  6728. *
  6729. * The actual projection is performed by pip, but pip doesn't seem
  6730. * to like equalities very much, so we first remove the equalities
  6731. * among the parameters by performing a variable compression on
  6732. * the parameters. Afterward, an inverse transformation is performed
  6733. * and the equalities among the parameters are inserted back in.
  6734. *
  6735. * The variable compression on the parameters may uncover additional
  6736. * equalities that were only implicit before. We therefore check
  6737. * if there are any new parameter equalities in the result and
  6738. * if so recurse. The removal of parameter equalities is required
  6739. * for the parameter compression performed by base_compute_divs.
  6740. */
  6741. static __isl_give isl_set *parameter_compute_divs(
  6742. __isl_take isl_basic_set *bset)
  6743. {
  6744. int i;
  6745. struct isl_mat *eq;
  6746. struct isl_mat *T, *T2;
  6747. struct isl_set *set;
  6748. isl_size nparam;
  6749. bset = isl_basic_set_cow(bset);
  6750. if (!bset)
  6751. return NULL;
  6752. if (bset->n_eq == 0)
  6753. return base_compute_divs(bset);
  6754. bset = isl_basic_set_gauss(bset, NULL);
  6755. if (!bset)
  6756. return NULL;
  6757. if (isl_basic_set_plain_is_empty(bset))
  6758. return isl_set_from_basic_set(bset);
  6759. i = first_parameter_equality(bset);
  6760. if (i == bset->n_eq)
  6761. return base_compute_divs(bset);
  6762. nparam = isl_basic_set_dim(bset, isl_dim_param);
  6763. if (nparam < 0)
  6764. return isl_set_from_basic_set(isl_basic_set_free(bset));
  6765. eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
  6766. 0, 1 + nparam);
  6767. eq = isl_mat_cow(eq);
  6768. T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
  6769. if (T && T->n_col == 0) {
  6770. isl_mat_free(T);
  6771. isl_mat_free(T2);
  6772. isl_mat_free(eq);
  6773. bset = isl_basic_set_set_to_empty(bset);
  6774. return isl_set_from_basic_set(bset);
  6775. }
  6776. bset = basic_set_parameter_preimage(bset, T);
  6777. i = first_parameter_equality(bset);
  6778. if (!bset)
  6779. set = NULL;
  6780. else if (i == bset->n_eq)
  6781. set = base_compute_divs(bset);
  6782. else
  6783. set = parameter_compute_divs(bset);
  6784. set = set_parameter_preimage(set, T2);
  6785. set = set_append_equalities(set, eq);
  6786. return set;
  6787. }
  6788. /* Insert the divs from "ls" before those of "bmap".
  6789. *
  6790. * The number of columns is not changed, which means that the last
  6791. * dimensions of "bmap" are being reintepreted as the divs from "ls".
  6792. * The caller is responsible for removing the same number of dimensions
  6793. * from the space of "bmap".
  6794. */
  6795. static __isl_give isl_basic_map *insert_divs_from_local_space(
  6796. __isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls)
  6797. {
  6798. int i;
  6799. isl_size n_div;
  6800. int old_n_div;
  6801. n_div = isl_local_space_dim(ls, isl_dim_div);
  6802. if (n_div < 0)
  6803. return isl_basic_map_free(bmap);
  6804. if (n_div == 0)
  6805. return bmap;
  6806. old_n_div = bmap->n_div;
  6807. bmap = insert_div_rows(bmap, n_div);
  6808. if (!bmap)
  6809. return NULL;
  6810. for (i = 0; i < n_div; ++i) {
  6811. isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
  6812. isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div);
  6813. }
  6814. return bmap;
  6815. }
  6816. /* Replace the space of "bmap" by the space and divs of "ls".
  6817. *
  6818. * If "ls" has any divs, then we simplify the result since we may
  6819. * have discovered some additional equalities that could simplify
  6820. * the div expressions.
  6821. */
  6822. static __isl_give isl_basic_map *basic_replace_space_by_local_space(
  6823. __isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls)
  6824. {
  6825. isl_size n_div;
  6826. bmap = isl_basic_map_cow(bmap);
  6827. n_div = isl_local_space_dim(ls, isl_dim_div);
  6828. if (!bmap || n_div < 0)
  6829. goto error;
  6830. bmap = insert_divs_from_local_space(bmap, ls);
  6831. if (!bmap)
  6832. goto error;
  6833. isl_space_free(bmap->dim);
  6834. bmap->dim = isl_local_space_get_space(ls);
  6835. if (!bmap->dim)
  6836. goto error;
  6837. isl_local_space_free(ls);
  6838. if (n_div > 0)
  6839. bmap = isl_basic_map_simplify(bmap);
  6840. bmap = isl_basic_map_finalize(bmap);
  6841. return bmap;
  6842. error:
  6843. isl_basic_map_free(bmap);
  6844. isl_local_space_free(ls);
  6845. return NULL;
  6846. }
  6847. /* Replace the space of "map" by the space and divs of "ls".
  6848. */
  6849. static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map,
  6850. __isl_take isl_local_space *ls)
  6851. {
  6852. int i;
  6853. map = isl_map_cow(map);
  6854. if (!map || !ls)
  6855. goto error;
  6856. for (i = 0; i < map->n; ++i) {
  6857. map->p[i] = basic_replace_space_by_local_space(map->p[i],
  6858. isl_local_space_copy(ls));
  6859. if (!map->p[i])
  6860. goto error;
  6861. }
  6862. isl_space_free(isl_map_take_space(map));
  6863. map = isl_map_restore_space(map, isl_local_space_get_space(ls));
  6864. isl_local_space_free(ls);
  6865. return map;
  6866. error:
  6867. isl_local_space_free(ls);
  6868. isl_map_free(map);
  6869. return NULL;
  6870. }
  6871. /* Compute an explicit representation for the existentially
  6872. * quantified variables for which do not know any explicit representation yet.
  6873. *
  6874. * We first sort the existentially quantified variables so that the
  6875. * existentially quantified variables for which we already have an explicit
  6876. * representation are placed before those for which we do not.
  6877. * The input dimensions, the output dimensions and the existentially
  6878. * quantified variables for which we already have an explicit
  6879. * representation are then turned into parameters.
  6880. * compute_divs returns a map with the same parameters and
  6881. * no input or output dimensions and the dimension specification
  6882. * is reset to that of the input, including the existentially quantified
  6883. * variables for which we already had an explicit representation.
  6884. */
  6885. static __isl_give isl_map *compute_divs(__isl_take isl_basic_map *bmap)
  6886. {
  6887. struct isl_basic_set *bset;
  6888. struct isl_set *set;
  6889. struct isl_map *map;
  6890. isl_space *space;
  6891. isl_local_space *ls;
  6892. isl_size nparam;
  6893. isl_size n_in;
  6894. isl_size n_out;
  6895. int n_known;
  6896. int i;
  6897. bmap = isl_basic_map_sort_divs(bmap);
  6898. bmap = isl_basic_map_cow(bmap);
  6899. if (!bmap)
  6900. return NULL;
  6901. n_known = isl_basic_map_first_unknown_div(bmap);
  6902. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  6903. n_in = isl_basic_map_dim(bmap, isl_dim_in);
  6904. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  6905. if (n_known < 0 || nparam < 0 || n_in < 0 || n_out < 0)
  6906. return isl_map_from_basic_map(isl_basic_map_free(bmap));
  6907. space = isl_space_set_alloc(bmap->ctx,
  6908. nparam + n_in + n_out + n_known, 0);
  6909. if (!space)
  6910. goto error;
  6911. ls = isl_basic_map_get_local_space(bmap);
  6912. ls = isl_local_space_drop_dims(ls, isl_dim_div,
  6913. n_known, bmap->n_div - n_known);
  6914. if (n_known > 0) {
  6915. for (i = n_known; i < bmap->n_div; ++i)
  6916. swap_div(bmap, i - n_known, i);
  6917. bmap->n_div -= n_known;
  6918. bmap->extra -= n_known;
  6919. }
  6920. bmap = isl_basic_map_reset_space(bmap, space);
  6921. bset = bset_from_bmap(bmap);
  6922. set = parameter_compute_divs(bset);
  6923. map = set_to_map(set);
  6924. map = replace_space_by_local_space(map, ls);
  6925. return map;
  6926. error:
  6927. isl_basic_map_free(bmap);
  6928. return NULL;
  6929. }
  6930. /* Remove the explicit representation of local variable "div",
  6931. * if there is any.
  6932. */
  6933. __isl_give isl_basic_map *isl_basic_map_mark_div_unknown(
  6934. __isl_take isl_basic_map *bmap, int div)
  6935. {
  6936. isl_bool unknown;
  6937. unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
  6938. if (unknown < 0)
  6939. return isl_basic_map_free(bmap);
  6940. if (unknown)
  6941. return bmap;
  6942. bmap = isl_basic_map_cow(bmap);
  6943. if (!bmap)
  6944. return NULL;
  6945. isl_int_set_si(bmap->div[div][0], 0);
  6946. return bmap;
  6947. }
  6948. /* Is local variable "div" of "bmap" marked as not having an explicit
  6949. * representation?
  6950. * Note that even if "div" is not marked in this way and therefore
  6951. * has an explicit representation, this representation may still
  6952. * depend (indirectly) on other local variables that do not
  6953. * have an explicit representation.
  6954. */
  6955. isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap,
  6956. int div)
  6957. {
  6958. if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
  6959. return isl_bool_error;
  6960. return isl_int_is_zero(bmap->div[div][0]);
  6961. }
  6962. /* Return the position of the first local variable that does not
  6963. * have an explicit representation.
  6964. * Return the total number of local variables if they all have
  6965. * an explicit representation.
  6966. * Return -1 on error.
  6967. */
  6968. int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap)
  6969. {
  6970. int i;
  6971. if (!bmap)
  6972. return -1;
  6973. for (i = 0; i < bmap->n_div; ++i) {
  6974. if (!isl_basic_map_div_is_known(bmap, i))
  6975. return i;
  6976. }
  6977. return bmap->n_div;
  6978. }
  6979. /* Return the position of the first local variable that does not
  6980. * have an explicit representation.
  6981. * Return the total number of local variables if they all have
  6982. * an explicit representation.
  6983. * Return -1 on error.
  6984. */
  6985. int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set *bset)
  6986. {
  6987. return isl_basic_map_first_unknown_div(bset);
  6988. }
  6989. /* Does "bmap" have an explicit representation for all local variables?
  6990. */
  6991. isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
  6992. {
  6993. int first;
  6994. isl_size n;
  6995. n = isl_basic_map_dim(bmap, isl_dim_div);
  6996. first = isl_basic_map_first_unknown_div(bmap);
  6997. if (n < 0 || first < 0)
  6998. return isl_bool_error;
  6999. return first == n;
  7000. }
  7001. /* Do all basic maps in "map" have an explicit representation
  7002. * for all local variables?
  7003. */
  7004. isl_bool isl_map_divs_known(__isl_keep isl_map *map)
  7005. {
  7006. int i;
  7007. if (!map)
  7008. return isl_bool_error;
  7009. for (i = 0; i < map->n; ++i) {
  7010. int known = isl_basic_map_divs_known(map->p[i]);
  7011. if (known <= 0)
  7012. return known;
  7013. }
  7014. return isl_bool_true;
  7015. }
  7016. /* If bmap contains any unknown divs, then compute explicit
  7017. * expressions for them. However, this computation may be
  7018. * quite expensive, so first try to remove divs that aren't
  7019. * strictly needed.
  7020. */
  7021. __isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap)
  7022. {
  7023. int known;
  7024. struct isl_map *map;
  7025. known = isl_basic_map_divs_known(bmap);
  7026. if (known < 0)
  7027. goto error;
  7028. if (known)
  7029. return isl_map_from_basic_map(bmap);
  7030. bmap = isl_basic_map_drop_redundant_divs(bmap);
  7031. known = isl_basic_map_divs_known(bmap);
  7032. if (known < 0)
  7033. goto error;
  7034. if (known)
  7035. return isl_map_from_basic_map(bmap);
  7036. map = compute_divs(bmap);
  7037. return map;
  7038. error:
  7039. isl_basic_map_free(bmap);
  7040. return NULL;
  7041. }
  7042. __isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map)
  7043. {
  7044. int i;
  7045. int known;
  7046. struct isl_map *res;
  7047. if (!map)
  7048. return NULL;
  7049. if (map->n == 0)
  7050. return map;
  7051. known = isl_map_divs_known(map);
  7052. if (known < 0) {
  7053. isl_map_free(map);
  7054. return NULL;
  7055. }
  7056. if (known)
  7057. return map;
  7058. res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
  7059. for (i = 1 ; i < map->n; ++i) {
  7060. struct isl_map *r2;
  7061. r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
  7062. if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
  7063. res = isl_map_union_disjoint(res, r2);
  7064. else
  7065. res = isl_map_union(res, r2);
  7066. }
  7067. isl_map_free(map);
  7068. return res;
  7069. }
  7070. __isl_give isl_set *isl_basic_set_compute_divs(__isl_take isl_basic_set *bset)
  7071. {
  7072. return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset)));
  7073. }
  7074. __isl_give isl_set *isl_set_compute_divs(__isl_take isl_set *set)
  7075. {
  7076. return set_from_map(isl_map_compute_divs(set_to_map(set)));
  7077. }
  7078. __isl_give isl_set *isl_map_domain(__isl_take isl_map *map)
  7079. {
  7080. isl_space *space;
  7081. isl_size n_out;
  7082. n_out = isl_map_dim(map, isl_dim_out);
  7083. if (n_out < 0)
  7084. return set_from_map(isl_map_free(map));
  7085. space = isl_space_domain(isl_map_get_space(map));
  7086. map = isl_map_project_out(map, isl_dim_out, 0, n_out);
  7087. return set_from_map(isl_map_reset_space(map, space));
  7088. }
  7089. /* Return the union of "map1" and "map2", where we assume for now that
  7090. * "map1" and "map2" are disjoint. Note that the basic maps inside
  7091. * "map1" or "map2" may not be disjoint from each other.
  7092. * Also note that this function is also called from isl_map_union,
  7093. * which takes care of handling the situation where "map1" and "map2"
  7094. * may not be disjoint.
  7095. *
  7096. * If one of the inputs is empty, we can simply return the other input.
  7097. * Similarly, if one of the inputs is universal, then it is equal to the union.
  7098. */
  7099. static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
  7100. __isl_take isl_map *map2)
  7101. {
  7102. int i;
  7103. unsigned flags = 0;
  7104. struct isl_map *map = NULL;
  7105. int is_universe;
  7106. if (isl_map_check_equal_space(map1, map2) < 0)
  7107. goto error;
  7108. if (map1->n == 0) {
  7109. isl_map_free(map1);
  7110. return map2;
  7111. }
  7112. if (map2->n == 0) {
  7113. isl_map_free(map2);
  7114. return map1;
  7115. }
  7116. is_universe = isl_map_plain_is_universe(map1);
  7117. if (is_universe < 0)
  7118. goto error;
  7119. if (is_universe) {
  7120. isl_map_free(map2);
  7121. return map1;
  7122. }
  7123. is_universe = isl_map_plain_is_universe(map2);
  7124. if (is_universe < 0)
  7125. goto error;
  7126. if (is_universe) {
  7127. isl_map_free(map1);
  7128. return map2;
  7129. }
  7130. if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
  7131. ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
  7132. ISL_FL_SET(flags, ISL_MAP_DISJOINT);
  7133. map = isl_map_alloc_space(isl_space_copy(map1->dim),
  7134. map1->n + map2->n, flags);
  7135. if (!map)
  7136. goto error;
  7137. for (i = 0; i < map1->n; ++i) {
  7138. map = isl_map_add_basic_map(map,
  7139. isl_basic_map_copy(map1->p[i]));
  7140. if (!map)
  7141. goto error;
  7142. }
  7143. for (i = 0; i < map2->n; ++i) {
  7144. map = isl_map_add_basic_map(map,
  7145. isl_basic_map_copy(map2->p[i]));
  7146. if (!map)
  7147. goto error;
  7148. }
  7149. isl_map_free(map1);
  7150. isl_map_free(map2);
  7151. return map;
  7152. error:
  7153. isl_map_free(map);
  7154. isl_map_free(map1);
  7155. isl_map_free(map2);
  7156. return NULL;
  7157. }
  7158. /* Return the union of "map1" and "map2", where "map1" and "map2" are
  7159. * guaranteed to be disjoint by the caller.
  7160. *
  7161. * Note that this functions is called from within isl_map_make_disjoint,
  7162. * so we have to be careful not to touch the constraints of the inputs
  7163. * in any way.
  7164. */
  7165. __isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
  7166. __isl_take isl_map *map2)
  7167. {
  7168. isl_map_align_params_bin(&map1, &map2);
  7169. return map_union_disjoint(map1, map2);
  7170. }
  7171. /* Return the union of "map1" and "map2", where "map1" and "map2" may
  7172. * not be disjoint.
  7173. *
  7174. * We currently simply call map_union_disjoint, the internal operation
  7175. * of which does not really depend on the inputs being disjoint.
  7176. * If the result contains more than one basic map, then we clear
  7177. * the disjoint flag since the result may contain basic maps from
  7178. * both inputs and these are not guaranteed to be disjoint.
  7179. *
  7180. * As a special case, if "map1" and "map2" are obviously equal,
  7181. * then we simply return "map1".
  7182. */
  7183. __isl_give isl_map *isl_map_union(__isl_take isl_map *map1,
  7184. __isl_take isl_map *map2)
  7185. {
  7186. int equal;
  7187. if (isl_map_align_params_bin(&map1, &map2) < 0)
  7188. goto error;
  7189. equal = isl_map_plain_is_equal(map1, map2);
  7190. if (equal < 0)
  7191. goto error;
  7192. if (equal) {
  7193. isl_map_free(map2);
  7194. return map1;
  7195. }
  7196. map1 = map_union_disjoint(map1, map2);
  7197. if (!map1)
  7198. return NULL;
  7199. if (map1->n > 1)
  7200. ISL_F_CLR(map1, ISL_MAP_DISJOINT);
  7201. return map1;
  7202. error:
  7203. isl_map_free(map1);
  7204. isl_map_free(map2);
  7205. return NULL;
  7206. }
  7207. __isl_give isl_set *isl_set_union_disjoint(
  7208. __isl_take isl_set *set1, __isl_take isl_set *set2)
  7209. {
  7210. return set_from_map(isl_map_union_disjoint(set_to_map(set1),
  7211. set_to_map(set2)));
  7212. }
  7213. __isl_give isl_set *isl_set_union(__isl_take isl_set *set1,
  7214. __isl_take isl_set *set2)
  7215. {
  7216. return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2)));
  7217. }
  7218. /* Apply "fn" to pairs of elements from "map" and "set" and collect
  7219. * the results in a map living in "space".
  7220. *
  7221. * "map" and "set" are assumed to be compatible and non-NULL.
  7222. */
  7223. static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
  7224. __isl_take isl_space *space, __isl_take isl_set *set,
  7225. __isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
  7226. __isl_take isl_basic_set *bset))
  7227. {
  7228. unsigned flags = 0;
  7229. struct isl_map *result;
  7230. int i, j;
  7231. if (isl_set_plain_is_universe(set)) {
  7232. isl_set_free(set);
  7233. return isl_map_reset_equal_dim_space(map, space);
  7234. }
  7235. if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
  7236. ISL_F_ISSET(set, ISL_MAP_DISJOINT))
  7237. ISL_FL_SET(flags, ISL_MAP_DISJOINT);
  7238. result = isl_map_alloc_space(space, map->n * set->n, flags);
  7239. for (i = 0; result && i < map->n; ++i)
  7240. for (j = 0; j < set->n; ++j) {
  7241. result = isl_map_add_basic_map(result,
  7242. fn(isl_basic_map_copy(map->p[i]),
  7243. isl_basic_set_copy(set->p[j])));
  7244. if (!result)
  7245. break;
  7246. }
  7247. isl_map_free(map);
  7248. isl_set_free(set);
  7249. return result;
  7250. }
  7251. __isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
  7252. __isl_take isl_set *set)
  7253. {
  7254. isl_bool ok;
  7255. isl_space *space;
  7256. isl_map_align_params_set(&map, &set);
  7257. ok = isl_map_compatible_range(map, set);
  7258. if (ok < 0)
  7259. goto error;
  7260. if (!ok)
  7261. isl_die(set->ctx, isl_error_invalid,
  7262. "incompatible spaces", goto error);
  7263. space = isl_map_get_space(map);
  7264. return map_intersect_set(map, space, set,
  7265. &isl_basic_map_intersect_range);
  7266. error:
  7267. isl_map_free(map);
  7268. isl_set_free(set);
  7269. return NULL;
  7270. }
  7271. /* Intersect the domain of "map" with "set".
  7272. *
  7273. * If the domain dimensions of "map" do not have any identifiers,
  7274. * then copy them over from "set".
  7275. */
  7276. __isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
  7277. __isl_take isl_set *set)
  7278. {
  7279. isl_bool ok;
  7280. isl_space *space;
  7281. isl_map_align_params_set(&map, &set);
  7282. ok = isl_map_compatible_domain(map, set);
  7283. if (ok < 0)
  7284. goto error;
  7285. if (!ok)
  7286. isl_die(set->ctx, isl_error_invalid,
  7287. "incompatible spaces", goto error);
  7288. space = isl_map_get_space(map);
  7289. space = isl_space_copy_ids_if_unset(space, isl_dim_in,
  7290. isl_set_peek_space(set), isl_dim_set);
  7291. return map_intersect_set(map, space, set,
  7292. &isl_basic_map_intersect_domain);
  7293. error:
  7294. isl_map_free(map);
  7295. isl_set_free(set);
  7296. return NULL;
  7297. }
  7298. #undef TYPE
  7299. #define TYPE isl_map
  7300. static
  7301. #include "isl_copy_tuple_id_templ.c"
  7302. /* Data structure that specifies how isl_map_intersect_factor
  7303. * should operate.
  7304. *
  7305. * "preserve_type" is the tuple where the factor differs from
  7306. * the input map and of which the identifiers needs
  7307. * to be preserved explicitly.
  7308. * "other_factor" is used to extract the space of the other factor
  7309. * from the space of the product ("map").
  7310. * "product" is used to combine the given factor and a universe map
  7311. * in the space returned by "other_factor" to produce a map
  7312. * that lives in the same space as the input map.
  7313. */
  7314. struct isl_intersect_factor_control {
  7315. enum isl_dim_type preserve_type;
  7316. __isl_give isl_space *(*other_factor)(__isl_take isl_space *space);
  7317. __isl_give isl_map *(*product)(__isl_take isl_map *factor,
  7318. __isl_take isl_map *other);
  7319. };
  7320. /* Given a map "map" in some product space and a map "factor"
  7321. * living in some factor space, return the intersection.
  7322. *
  7323. * After aligning the parameters,
  7324. * the map "factor" is first extended to a map living in the same space
  7325. * as "map" and then a regular intersection is computed.
  7326. *
  7327. * Note that the extension is computed as a product, which is anonymous
  7328. * by default. If "map" has an identifier on the corresponding tuple,
  7329. * then this identifier needs to be set on the product
  7330. * before the intersection is computed.
  7331. */
  7332. static __isl_give isl_map *isl_map_intersect_factor(
  7333. __isl_take isl_map *map, __isl_take isl_map *factor,
  7334. struct isl_intersect_factor_control *control)
  7335. {
  7336. isl_bool equal;
  7337. isl_space *space;
  7338. isl_map *other, *product;
  7339. equal = isl_map_has_equal_params(map, factor);
  7340. if (equal < 0)
  7341. goto error;
  7342. if (!equal) {
  7343. map = isl_map_align_params(map, isl_map_get_space(factor));
  7344. factor = isl_map_align_params(factor, isl_map_get_space(map));
  7345. }
  7346. space = isl_map_get_space(map);
  7347. other = isl_map_universe(control->other_factor(space));
  7348. product = control->product(factor, other);
  7349. space = isl_map_peek_space(map);
  7350. product = isl_map_copy_tuple_id(product, control->preserve_type,
  7351. space, control->preserve_type);
  7352. return map_intersect(map, product);
  7353. error:
  7354. isl_map_free(map);
  7355. isl_map_free(factor);
  7356. return NULL;
  7357. }
  7358. /* Return the domain product of "map2" and "map1".
  7359. */
  7360. static __isl_give isl_map *isl_map_reverse_domain_product(
  7361. __isl_take isl_map *map1, __isl_take isl_map *map2)
  7362. {
  7363. return isl_map_domain_product(map2, map1);
  7364. }
  7365. /* Return the range product of "map2" and "map1".
  7366. */
  7367. static __isl_give isl_map *isl_map_reverse_range_product(
  7368. __isl_take isl_map *map1, __isl_take isl_map *map2)
  7369. {
  7370. return isl_map_range_product(map2, map1);
  7371. }
  7372. /* Given a map "map" in a space [A -> B] -> C and a map "factor"
  7373. * in the space A -> C, return the intersection.
  7374. */
  7375. __isl_give isl_map *isl_map_intersect_domain_factor_domain(
  7376. __isl_take isl_map *map, __isl_take isl_map *factor)
  7377. {
  7378. struct isl_intersect_factor_control control = {
  7379. .preserve_type = isl_dim_in,
  7380. .other_factor = isl_space_domain_factor_range,
  7381. .product = isl_map_domain_product,
  7382. };
  7383. return isl_map_intersect_factor(map, factor, &control);
  7384. }
  7385. /* Given a map "map" in a space [A -> B] -> C and a map "factor"
  7386. * in the space B -> C, return the intersection.
  7387. */
  7388. __isl_give isl_map *isl_map_intersect_domain_factor_range(
  7389. __isl_take isl_map *map, __isl_take isl_map *factor)
  7390. {
  7391. struct isl_intersect_factor_control control = {
  7392. .preserve_type = isl_dim_in,
  7393. .other_factor = isl_space_domain_factor_domain,
  7394. .product = isl_map_reverse_domain_product,
  7395. };
  7396. return isl_map_intersect_factor(map, factor, &control);
  7397. }
  7398. /* Given a map "map" in a space A -> [B -> C] and a map "factor"
  7399. * in the space A -> B, return the intersection.
  7400. */
  7401. __isl_give isl_map *isl_map_intersect_range_factor_domain(
  7402. __isl_take isl_map *map, __isl_take isl_map *factor)
  7403. {
  7404. struct isl_intersect_factor_control control = {
  7405. .preserve_type = isl_dim_out,
  7406. .other_factor = isl_space_range_factor_range,
  7407. .product = isl_map_range_product,
  7408. };
  7409. return isl_map_intersect_factor(map, factor, &control);
  7410. }
  7411. /* Given a map "map" in a space A -> [B -> C] and a map "factor"
  7412. * in the space A -> C, return the intersection.
  7413. */
  7414. __isl_give isl_map *isl_map_intersect_range_factor_range(
  7415. __isl_take isl_map *map, __isl_take isl_map *factor)
  7416. {
  7417. struct isl_intersect_factor_control control = {
  7418. .preserve_type = isl_dim_out,
  7419. .other_factor = isl_space_range_factor_domain,
  7420. .product = isl_map_reverse_range_product,
  7421. };
  7422. return isl_map_intersect_factor(map, factor, &control);
  7423. }
  7424. /* Given a set "set" in a space [A -> B] and a set "domain"
  7425. * in the space A, return the intersection.
  7426. *
  7427. * The set "domain" is first extended to a set living in the space
  7428. * [A -> B] and then a regular intersection is computed.
  7429. */
  7430. __isl_give isl_set *isl_set_intersect_factor_domain(__isl_take isl_set *set,
  7431. __isl_take isl_set *domain)
  7432. {
  7433. struct isl_intersect_factor_control control = {
  7434. .preserve_type = isl_dim_set,
  7435. .other_factor = isl_space_factor_range,
  7436. .product = isl_map_range_product,
  7437. };
  7438. return set_from_map(isl_map_intersect_factor(set_to_map(set),
  7439. set_to_map(domain), &control));
  7440. }
  7441. /* Given a set "set" in a space [A -> B] and a set "range"
  7442. * in the space B, return the intersection.
  7443. *
  7444. * The set "range" is first extended to a set living in the space
  7445. * [A -> B] and then a regular intersection is computed.
  7446. */
  7447. __isl_give isl_set *isl_set_intersect_factor_range(__isl_take isl_set *set,
  7448. __isl_take isl_set *range)
  7449. {
  7450. struct isl_intersect_factor_control control = {
  7451. .preserve_type = isl_dim_set,
  7452. .other_factor = isl_space_factor_domain,
  7453. .product = isl_map_reverse_range_product,
  7454. };
  7455. return set_from_map(isl_map_intersect_factor(set_to_map(set),
  7456. set_to_map(range), &control));
  7457. }
  7458. __isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
  7459. __isl_take isl_map *map2)
  7460. {
  7461. if (isl_map_align_params_bin(&map1, &map2) < 0)
  7462. goto error;
  7463. map1 = isl_map_reverse(map1);
  7464. map1 = isl_map_apply_range(map1, map2);
  7465. return isl_map_reverse(map1);
  7466. error:
  7467. isl_map_free(map1);
  7468. isl_map_free(map2);
  7469. return NULL;
  7470. }
  7471. __isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
  7472. __isl_take isl_map *map2)
  7473. {
  7474. isl_space *space;
  7475. struct isl_map *result;
  7476. int i, j;
  7477. if (isl_map_align_params_bin(&map1, &map2) < 0)
  7478. goto error;
  7479. space = isl_space_join(isl_space_copy(map1->dim),
  7480. isl_space_copy(map2->dim));
  7481. result = isl_map_alloc_space(space, map1->n * map2->n, 0);
  7482. if (!result)
  7483. goto error;
  7484. for (i = 0; i < map1->n; ++i)
  7485. for (j = 0; j < map2->n; ++j) {
  7486. result = isl_map_add_basic_map(result,
  7487. isl_basic_map_apply_range(
  7488. isl_basic_map_copy(map1->p[i]),
  7489. isl_basic_map_copy(map2->p[j])));
  7490. if (!result)
  7491. goto error;
  7492. }
  7493. isl_map_free(map1);
  7494. isl_map_free(map2);
  7495. if (result && result->n <= 1)
  7496. ISL_F_SET(result, ISL_MAP_DISJOINT);
  7497. return result;
  7498. error:
  7499. isl_map_free(map1);
  7500. isl_map_free(map2);
  7501. return NULL;
  7502. }
  7503. /* Is "bmap" a transformation, i.e.,
  7504. * does it relate elements from the same space.
  7505. */
  7506. isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap)
  7507. {
  7508. isl_space *space;
  7509. space = isl_basic_map_peek_space(bmap);
  7510. return isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
  7511. }
  7512. /* Check that "bmap" is a transformation, i.e.,
  7513. * that it relates elements from the same space.
  7514. */
  7515. static isl_stat isl_basic_map_check_transformation(
  7516. __isl_keep isl_basic_map *bmap)
  7517. {
  7518. isl_bool equal;
  7519. equal = isl_basic_map_is_transformation(bmap);
  7520. if (equal < 0)
  7521. return isl_stat_error;
  7522. if (!equal)
  7523. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  7524. "domain and range don't match", return isl_stat_error);
  7525. return isl_stat_ok;
  7526. }
  7527. /*
  7528. * returns range - domain
  7529. */
  7530. __isl_give isl_basic_set *isl_basic_map_deltas(__isl_take isl_basic_map *bmap)
  7531. {
  7532. isl_space *target_space;
  7533. struct isl_basic_set *bset;
  7534. isl_size dim;
  7535. isl_size nparam;
  7536. isl_size total;
  7537. int i;
  7538. if (isl_basic_map_check_transformation(bmap) < 0)
  7539. return isl_basic_map_free(bmap);
  7540. dim = isl_basic_map_dim(bmap, isl_dim_in);
  7541. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  7542. if (dim < 0 || nparam < 0)
  7543. goto error;
  7544. target_space = isl_space_domain(isl_basic_map_get_space(bmap));
  7545. bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
  7546. bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim);
  7547. total = isl_basic_map_dim(bmap, isl_dim_all);
  7548. if (total < 0)
  7549. bmap = isl_basic_map_free(bmap);
  7550. bmap = isl_basic_map_extend_constraints(bmap, dim, 0);
  7551. for (i = 0; i < dim; ++i) {
  7552. int j = isl_basic_map_alloc_equality(bmap);
  7553. if (j < 0) {
  7554. bmap = isl_basic_map_free(bmap);
  7555. break;
  7556. }
  7557. isl_seq_clr(bmap->eq[j], 1 + total);
  7558. isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
  7559. isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1);
  7560. isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1);
  7561. }
  7562. bset = isl_basic_map_domain(bmap);
  7563. bset = isl_basic_set_reset_space(bset, target_space);
  7564. return bset;
  7565. error:
  7566. isl_basic_map_free(bmap);
  7567. return NULL;
  7568. }
  7569. /* Is the tuple of type "type1" of "map" the same as
  7570. * the tuple of type "type2" of "space"?
  7571. */
  7572. isl_bool isl_map_space_tuple_is_equal(__isl_keep isl_map *map,
  7573. enum isl_dim_type type1, __isl_keep isl_space *space,
  7574. enum isl_dim_type type2)
  7575. {
  7576. isl_space *map_space;
  7577. map_space = isl_map_peek_space(map);
  7578. return isl_space_tuple_is_equal(map_space, type1, space, type2);
  7579. }
  7580. /* Is the tuple of type "type1" of "map1" the same as
  7581. * the tuple of type "type2" of "map2"?
  7582. */
  7583. isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1,
  7584. enum isl_dim_type type1, __isl_keep isl_map *map2,
  7585. enum isl_dim_type type2)
  7586. {
  7587. isl_space *space1, *space2;
  7588. space1 = isl_map_peek_space(map1);
  7589. space2 = isl_map_peek_space(map2);
  7590. return isl_space_tuple_is_equal(space1, type1, space2, type2);
  7591. }
  7592. /* Is the space of "obj" equal to "space", ignoring parameters?
  7593. */
  7594. isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map,
  7595. __isl_keep isl_space *space)
  7596. {
  7597. isl_space *map_space;
  7598. map_space = isl_map_peek_space(map);
  7599. return isl_space_has_equal_tuples(map_space, space);
  7600. }
  7601. /* Check that "map" is a transformation, i.e.,
  7602. * that it relates elements from the same space.
  7603. */
  7604. isl_stat isl_map_check_transformation(__isl_keep isl_map *map)
  7605. {
  7606. isl_bool equal;
  7607. equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
  7608. if (equal < 0)
  7609. return isl_stat_error;
  7610. if (!equal)
  7611. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  7612. "domain and range don't match", return isl_stat_error);
  7613. return isl_stat_ok;
  7614. }
  7615. /*
  7616. * returns range - domain
  7617. */
  7618. __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map)
  7619. {
  7620. int i;
  7621. isl_space *space;
  7622. struct isl_set *result;
  7623. if (isl_map_check_transformation(map) < 0)
  7624. goto error;
  7625. space = isl_map_get_space(map);
  7626. space = isl_space_domain(space);
  7627. result = isl_set_alloc_space(space, map->n, 0);
  7628. if (!result)
  7629. goto error;
  7630. for (i = 0; i < map->n; ++i)
  7631. result = isl_set_add_basic_set(result,
  7632. isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
  7633. isl_map_free(map);
  7634. return result;
  7635. error:
  7636. isl_map_free(map);
  7637. return NULL;
  7638. }
  7639. /*
  7640. * returns [domain -> range] -> range - domain
  7641. */
  7642. __isl_give isl_basic_map *isl_basic_map_deltas_map(
  7643. __isl_take isl_basic_map *bmap)
  7644. {
  7645. int i, k;
  7646. isl_space *space;
  7647. isl_basic_map *domain;
  7648. isl_size nparam, n;
  7649. isl_size total;
  7650. if (isl_basic_map_check_transformation(bmap) < 0)
  7651. return isl_basic_map_free(bmap);
  7652. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  7653. n = isl_basic_map_dim(bmap, isl_dim_in);
  7654. if (nparam < 0 || n < 0)
  7655. return isl_basic_map_free(bmap);
  7656. space = isl_basic_map_get_space(bmap);
  7657. space = isl_space_from_range(isl_space_domain(space));
  7658. domain = isl_basic_map_universe(space);
  7659. bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
  7660. bmap = isl_basic_map_apply_range(bmap, domain);
  7661. bmap = isl_basic_map_extend_constraints(bmap, n, 0);
  7662. total = isl_basic_map_dim(bmap, isl_dim_all);
  7663. if (total < 0)
  7664. return isl_basic_map_free(bmap);
  7665. for (i = 0; i < n; ++i) {
  7666. k = isl_basic_map_alloc_equality(bmap);
  7667. if (k < 0)
  7668. goto error;
  7669. isl_seq_clr(bmap->eq[k], 1 + total);
  7670. isl_int_set_si(bmap->eq[k][1 + nparam + i], 1);
  7671. isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1);
  7672. isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1);
  7673. }
  7674. bmap = isl_basic_map_gauss(bmap, NULL);
  7675. return isl_basic_map_finalize(bmap);
  7676. error:
  7677. isl_basic_map_free(bmap);
  7678. return NULL;
  7679. }
  7680. /*
  7681. * returns [domain -> range] -> range - domain
  7682. */
  7683. __isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
  7684. {
  7685. if (isl_map_check_transformation(map) < 0)
  7686. return isl_map_free(map);
  7687. return isl_map_transform(map, &isl_space_range_map,
  7688. &isl_basic_map_deltas_map);
  7689. }
  7690. /* Return pairs of elements { x -> y } such that y - x is in "deltas".
  7691. */
  7692. __isl_give isl_map *isl_set_translation(__isl_take isl_set *deltas)
  7693. {
  7694. isl_space *space;
  7695. isl_map *map;
  7696. space = isl_space_map_from_set(isl_set_get_space(deltas));
  7697. map = isl_map_deltas_map(isl_map_universe(space));
  7698. map = isl_map_intersect_range(map, deltas);
  7699. return isl_set_unwrap(isl_map_domain(map));
  7700. }
  7701. __isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space)
  7702. {
  7703. isl_size n_in, n_out;
  7704. n_in = isl_space_dim(space, isl_dim_in);
  7705. n_out = isl_space_dim(space, isl_dim_out);
  7706. if (n_in < 0 || n_out < 0)
  7707. goto error;
  7708. if (n_in != n_out)
  7709. isl_die(space->ctx, isl_error_invalid,
  7710. "number of input and output dimensions needs to be "
  7711. "the same", goto error);
  7712. return isl_basic_map_equal(space, n_in);
  7713. error:
  7714. isl_space_free(space);
  7715. return NULL;
  7716. }
  7717. __isl_give isl_map *isl_map_identity(__isl_take isl_space *space)
  7718. {
  7719. return isl_map_from_basic_map(isl_basic_map_identity(space));
  7720. }
  7721. __isl_give isl_map *isl_set_identity(__isl_take isl_set *set)
  7722. {
  7723. isl_space *space = isl_set_get_space(set);
  7724. isl_map *id;
  7725. id = isl_map_identity(isl_space_map_from_set(space));
  7726. return isl_map_intersect_range(id, set);
  7727. }
  7728. /* Construct a basic set with all set dimensions having only non-negative
  7729. * values.
  7730. */
  7731. __isl_give isl_basic_set *isl_basic_set_positive_orthant(
  7732. __isl_take isl_space *space)
  7733. {
  7734. int i;
  7735. isl_size nparam;
  7736. isl_size dim;
  7737. isl_size total;
  7738. struct isl_basic_set *bset;
  7739. nparam = isl_space_dim(space, isl_dim_param);
  7740. dim = isl_space_dim(space, isl_dim_set);
  7741. total = isl_space_dim(space, isl_dim_all);
  7742. if (nparam < 0 || dim < 0 || total < 0)
  7743. space = isl_space_free(space);
  7744. bset = isl_basic_set_alloc_space(space, 0, 0, dim);
  7745. if (!bset)
  7746. return NULL;
  7747. for (i = 0; i < dim; ++i) {
  7748. int k = isl_basic_set_alloc_inequality(bset);
  7749. if (k < 0)
  7750. goto error;
  7751. isl_seq_clr(bset->ineq[k], 1 + total);
  7752. isl_int_set_si(bset->ineq[k][1 + nparam + i], 1);
  7753. }
  7754. return bset;
  7755. error:
  7756. isl_basic_set_free(bset);
  7757. return NULL;
  7758. }
  7759. /* Construct the half-space x_pos >= 0.
  7760. */
  7761. static __isl_give isl_basic_set *nonneg_halfspace(__isl_take isl_space *space,
  7762. int pos)
  7763. {
  7764. int k;
  7765. isl_size total;
  7766. isl_basic_set *nonneg;
  7767. total = isl_space_dim(space, isl_dim_all);
  7768. if (total < 0)
  7769. space = isl_space_free(space);
  7770. nonneg = isl_basic_set_alloc_space(space, 0, 0, 1);
  7771. k = isl_basic_set_alloc_inequality(nonneg);
  7772. if (k < 0)
  7773. goto error;
  7774. isl_seq_clr(nonneg->ineq[k], 1 + total);
  7775. isl_int_set_si(nonneg->ineq[k][pos], 1);
  7776. return isl_basic_set_finalize(nonneg);
  7777. error:
  7778. isl_basic_set_free(nonneg);
  7779. return NULL;
  7780. }
  7781. /* Construct the half-space x_pos <= -1.
  7782. */
  7783. static __isl_give isl_basic_set *neg_halfspace(__isl_take isl_space *space,
  7784. int pos)
  7785. {
  7786. int k;
  7787. isl_size total;
  7788. isl_basic_set *neg;
  7789. total = isl_space_dim(space, isl_dim_all);
  7790. if (total < 0)
  7791. space = isl_space_free(space);
  7792. neg = isl_basic_set_alloc_space(space, 0, 0, 1);
  7793. k = isl_basic_set_alloc_inequality(neg);
  7794. if (k < 0)
  7795. goto error;
  7796. isl_seq_clr(neg->ineq[k], 1 + total);
  7797. isl_int_set_si(neg->ineq[k][0], -1);
  7798. isl_int_set_si(neg->ineq[k][pos], -1);
  7799. return isl_basic_set_finalize(neg);
  7800. error:
  7801. isl_basic_set_free(neg);
  7802. return NULL;
  7803. }
  7804. __isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
  7805. enum isl_dim_type type, unsigned first, unsigned n)
  7806. {
  7807. int i;
  7808. unsigned offset;
  7809. isl_basic_set *nonneg;
  7810. isl_basic_set *neg;
  7811. if (n == 0)
  7812. return set;
  7813. if (isl_set_check_range(set, type, first, n) < 0)
  7814. return isl_set_free(set);
  7815. offset = pos(set->dim, type);
  7816. for (i = 0; i < n; ++i) {
  7817. nonneg = nonneg_halfspace(isl_set_get_space(set),
  7818. offset + first + i);
  7819. neg = neg_halfspace(isl_set_get_space(set), offset + first + i);
  7820. set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
  7821. }
  7822. return set;
  7823. }
  7824. static isl_stat foreach_orthant(__isl_take isl_set *set, int *signs, int first,
  7825. int len,
  7826. isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
  7827. void *user)
  7828. {
  7829. isl_set *half;
  7830. if (!set)
  7831. return isl_stat_error;
  7832. if (isl_set_plain_is_empty(set)) {
  7833. isl_set_free(set);
  7834. return isl_stat_ok;
  7835. }
  7836. if (first == len)
  7837. return fn(set, signs, user);
  7838. signs[first] = 1;
  7839. half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
  7840. 1 + first));
  7841. half = isl_set_intersect(half, isl_set_copy(set));
  7842. if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
  7843. goto error;
  7844. signs[first] = -1;
  7845. half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
  7846. 1 + first));
  7847. half = isl_set_intersect(half, set);
  7848. return foreach_orthant(half, signs, first + 1, len, fn, user);
  7849. error:
  7850. isl_set_free(set);
  7851. return isl_stat_error;
  7852. }
  7853. /* Call "fn" on the intersections of "set" with each of the orthants
  7854. * (except for obviously empty intersections). The orthant is identified
  7855. * by the signs array, with each entry having value 1 or -1 according
  7856. * to the sign of the corresponding variable.
  7857. */
  7858. isl_stat isl_set_foreach_orthant(__isl_keep isl_set *set,
  7859. isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
  7860. void *user)
  7861. {
  7862. isl_size nparam;
  7863. isl_size nvar;
  7864. int *signs;
  7865. isl_stat r;
  7866. if (!set)
  7867. return isl_stat_error;
  7868. if (isl_set_plain_is_empty(set))
  7869. return isl_stat_ok;
  7870. nparam = isl_set_dim(set, isl_dim_param);
  7871. nvar = isl_set_dim(set, isl_dim_set);
  7872. if (nparam < 0 || nvar < 0)
  7873. return isl_stat_error;
  7874. signs = isl_alloc_array(set->ctx, int, nparam + nvar);
  7875. r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
  7876. fn, user);
  7877. free(signs);
  7878. return r;
  7879. }
  7880. isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
  7881. {
  7882. return isl_map_is_equal(set_to_map(set1), set_to_map(set2));
  7883. }
  7884. isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
  7885. __isl_keep isl_basic_map *bmap2)
  7886. {
  7887. isl_bool is_subset;
  7888. struct isl_map *map1;
  7889. struct isl_map *map2;
  7890. if (!bmap1 || !bmap2)
  7891. return isl_bool_error;
  7892. map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
  7893. map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
  7894. is_subset = isl_map_is_subset(map1, map2);
  7895. isl_map_free(map1);
  7896. isl_map_free(map2);
  7897. return is_subset;
  7898. }
  7899. isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1,
  7900. __isl_keep isl_basic_set *bset2)
  7901. {
  7902. return isl_basic_map_is_subset(bset1, bset2);
  7903. }
  7904. isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1,
  7905. __isl_keep isl_basic_map *bmap2)
  7906. {
  7907. isl_bool is_subset;
  7908. if (!bmap1 || !bmap2)
  7909. return isl_bool_error;
  7910. is_subset = isl_basic_map_is_subset(bmap1, bmap2);
  7911. if (is_subset != isl_bool_true)
  7912. return is_subset;
  7913. is_subset = isl_basic_map_is_subset(bmap2, bmap1);
  7914. return is_subset;
  7915. }
  7916. isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_set *bset1,
  7917. __isl_keep isl_basic_set *bset2)
  7918. {
  7919. return isl_basic_map_is_equal(
  7920. bset_to_bmap(bset1), bset_to_bmap(bset2));
  7921. }
  7922. isl_bool isl_map_is_empty(__isl_keep isl_map *map)
  7923. {
  7924. int i;
  7925. int is_empty;
  7926. if (!map)
  7927. return isl_bool_error;
  7928. for (i = 0; i < map->n; ++i) {
  7929. is_empty = isl_basic_map_is_empty(map->p[i]);
  7930. if (is_empty < 0)
  7931. return isl_bool_error;
  7932. if (!is_empty)
  7933. return isl_bool_false;
  7934. }
  7935. return isl_bool_true;
  7936. }
  7937. isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map)
  7938. {
  7939. return map ? map->n == 0 : isl_bool_error;
  7940. }
  7941. isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set)
  7942. {
  7943. return set ? set->n == 0 : isl_bool_error;
  7944. }
  7945. isl_bool isl_set_is_empty(__isl_keep isl_set *set)
  7946. {
  7947. return isl_map_is_empty(set_to_map(set));
  7948. }
  7949. #undef TYPE
  7950. #define TYPE isl_basic_map
  7951. static
  7952. #include "isl_type_has_equal_space_bin_templ.c"
  7953. #include "isl_type_check_equal_space_templ.c"
  7954. /* Check that "bset1" and "bset2" live in the same space,
  7955. * reporting an error if they do not.
  7956. */
  7957. isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_set *bset1,
  7958. __isl_keep isl_basic_set *bset2)
  7959. {
  7960. return isl_basic_map_check_equal_space(bset_to_bmap(bset1),
  7961. bset_to_bmap(bset1));
  7962. }
  7963. #undef TYPE
  7964. #define TYPE isl_map
  7965. #include "isl_type_has_equal_space_bin_templ.c"
  7966. #include "isl_type_check_equal_space_templ.c"
  7967. #include "isl_type_has_space_templ.c"
  7968. isl_bool isl_set_has_equal_space(__isl_keep isl_set *set1,
  7969. __isl_keep isl_set *set2)
  7970. {
  7971. return isl_map_has_equal_space(set_to_map(set1), set_to_map(set2));
  7972. }
  7973. #undef TYPE1
  7974. #define TYPE1 isl_map
  7975. #undef TYPE2
  7976. #define TYPE2 isl_basic_map
  7977. #undef TYPE_PAIR
  7978. #define TYPE_PAIR isl_map_basic_map
  7979. static
  7980. #include "isl_type_has_equal_space_templ.c"
  7981. #include "isl_type_check_equal_space_templ.c"
  7982. /* Check that "set" and "bset" live in the same space,
  7983. * reporting an error if they do not.
  7984. */
  7985. isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_set *set,
  7986. __isl_keep isl_basic_set *bset)
  7987. {
  7988. return isl_map_basic_map_check_equal_space(set_to_map(set),
  7989. bset_to_bmap(bset));
  7990. }
  7991. static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
  7992. {
  7993. isl_bool is_subset;
  7994. if (!map1 || !map2)
  7995. return isl_bool_error;
  7996. is_subset = isl_map_is_subset(map1, map2);
  7997. if (is_subset != isl_bool_true)
  7998. return is_subset;
  7999. is_subset = isl_map_is_subset(map2, map1);
  8000. return is_subset;
  8001. }
  8002. /* Is "map1" equal to "map2"?
  8003. *
  8004. * First check if they are obviously equal.
  8005. * If not, then perform a more detailed analysis.
  8006. */
  8007. isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
  8008. {
  8009. isl_bool equal;
  8010. equal = isl_map_plain_is_equal(map1, map2);
  8011. if (equal < 0 || equal)
  8012. return equal;
  8013. return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
  8014. }
  8015. isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1,
  8016. __isl_keep isl_basic_map *bmap2)
  8017. {
  8018. isl_bool is_subset;
  8019. if (!bmap1 || !bmap2)
  8020. return isl_bool_error;
  8021. is_subset = isl_basic_map_is_subset(bmap1, bmap2);
  8022. if (is_subset != isl_bool_true)
  8023. return is_subset;
  8024. is_subset = isl_basic_map_is_subset(bmap2, bmap1);
  8025. return isl_bool_not(is_subset);
  8026. }
  8027. isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1,
  8028. __isl_keep isl_map *map2)
  8029. {
  8030. isl_bool is_subset;
  8031. if (!map1 || !map2)
  8032. return isl_bool_error;
  8033. is_subset = isl_map_is_subset(map1, map2);
  8034. if (is_subset != isl_bool_true)
  8035. return is_subset;
  8036. is_subset = isl_map_is_subset(map2, map1);
  8037. return isl_bool_not(is_subset);
  8038. }
  8039. isl_bool isl_set_is_strict_subset(__isl_keep isl_set *set1,
  8040. __isl_keep isl_set *set2)
  8041. {
  8042. return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2));
  8043. }
  8044. /* Is "bmap" obviously equal to the universe with the same space?
  8045. *
  8046. * That is, does it not have any constraints?
  8047. */
  8048. isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap)
  8049. {
  8050. if (!bmap)
  8051. return isl_bool_error;
  8052. return bmap->n_eq == 0 && bmap->n_ineq == 0;
  8053. }
  8054. /* Is "bset" obviously equal to the universe with the same space?
  8055. */
  8056. isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_set *bset)
  8057. {
  8058. return isl_basic_map_plain_is_universe(bset);
  8059. }
  8060. /* If "c" does not involve any existentially quantified variables,
  8061. * then set *univ to false and abort
  8062. */
  8063. static isl_stat involves_divs(__isl_take isl_constraint *c, void *user)
  8064. {
  8065. isl_bool *univ = user;
  8066. isl_size n;
  8067. n = isl_constraint_dim(c, isl_dim_div);
  8068. if (n < 0)
  8069. c = isl_constraint_free(c);
  8070. *univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n);
  8071. isl_constraint_free(c);
  8072. if (*univ < 0 || !*univ)
  8073. return isl_stat_error;
  8074. return isl_stat_ok;
  8075. }
  8076. /* Is "bmap" equal to the universe with the same space?
  8077. *
  8078. * First check if it is obviously equal to the universe.
  8079. * If not and if there are any constraints not involving
  8080. * existentially quantified variables, then it is certainly
  8081. * not equal to the universe.
  8082. * Otherwise, check if the universe is a subset of "bmap".
  8083. */
  8084. isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap)
  8085. {
  8086. isl_size n_div;
  8087. isl_bool univ;
  8088. isl_basic_map *test;
  8089. univ = isl_basic_map_plain_is_universe(bmap);
  8090. if (univ < 0 || univ)
  8091. return univ;
  8092. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  8093. if (n_div < 0)
  8094. return isl_bool_error;
  8095. if (n_div == 0)
  8096. return isl_bool_false;
  8097. univ = isl_bool_true;
  8098. if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 &&
  8099. univ)
  8100. return isl_bool_error;
  8101. if (univ < 0 || !univ)
  8102. return univ;
  8103. test = isl_basic_map_universe(isl_basic_map_get_space(bmap));
  8104. univ = isl_basic_map_is_subset(test, bmap);
  8105. isl_basic_map_free(test);
  8106. return univ;
  8107. }
  8108. /* Is "bset" equal to the universe with the same space?
  8109. */
  8110. isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_set *bset)
  8111. {
  8112. return isl_basic_map_is_universe(bset);
  8113. }
  8114. isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map)
  8115. {
  8116. int i;
  8117. if (!map)
  8118. return isl_bool_error;
  8119. for (i = 0; i < map->n; ++i) {
  8120. isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
  8121. if (r < 0 || r)
  8122. return r;
  8123. }
  8124. return isl_bool_false;
  8125. }
  8126. isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set)
  8127. {
  8128. return isl_map_plain_is_universe(set_to_map(set));
  8129. }
  8130. isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap)
  8131. {
  8132. struct isl_basic_set *bset = NULL;
  8133. struct isl_vec *sample = NULL;
  8134. isl_bool empty, non_empty;
  8135. if (!bmap)
  8136. return isl_bool_error;
  8137. if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
  8138. return isl_bool_true;
  8139. if (isl_basic_map_plain_is_universe(bmap))
  8140. return isl_bool_false;
  8141. if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
  8142. struct isl_basic_map *copy = isl_basic_map_copy(bmap);
  8143. copy = isl_basic_map_remove_redundancies(copy);
  8144. empty = isl_basic_map_plain_is_empty(copy);
  8145. isl_basic_map_free(copy);
  8146. return empty;
  8147. }
  8148. non_empty = isl_basic_map_plain_is_non_empty(bmap);
  8149. if (non_empty < 0)
  8150. return isl_bool_error;
  8151. if (non_empty)
  8152. return isl_bool_false;
  8153. isl_vec_free(bmap->sample);
  8154. bmap->sample = NULL;
  8155. bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
  8156. if (!bset)
  8157. return isl_bool_error;
  8158. sample = isl_basic_set_sample_vec(bset);
  8159. if (!sample)
  8160. return isl_bool_error;
  8161. empty = sample->size == 0;
  8162. isl_vec_free(bmap->sample);
  8163. bmap->sample = sample;
  8164. if (empty)
  8165. ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
  8166. return empty;
  8167. }
  8168. isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
  8169. {
  8170. if (!bmap)
  8171. return isl_bool_error;
  8172. return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
  8173. }
  8174. isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset)
  8175. {
  8176. if (!bset)
  8177. return isl_bool_error;
  8178. return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
  8179. }
  8180. /* Is "bmap" known to be non-empty?
  8181. *
  8182. * That is, is the cached sample still valid?
  8183. */
  8184. isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap)
  8185. {
  8186. isl_size total;
  8187. if (!bmap)
  8188. return isl_bool_error;
  8189. if (!bmap->sample)
  8190. return isl_bool_false;
  8191. total = isl_basic_map_dim(bmap, isl_dim_all);
  8192. if (total < 0)
  8193. return isl_bool_error;
  8194. if (bmap->sample->size != 1 + total)
  8195. return isl_bool_false;
  8196. return isl_basic_map_contains(bmap, bmap->sample);
  8197. }
  8198. isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_set *bset)
  8199. {
  8200. return isl_basic_map_is_empty(bset_to_bmap(bset));
  8201. }
  8202. __isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1,
  8203. __isl_take isl_basic_map *bmap2)
  8204. {
  8205. struct isl_map *map;
  8206. if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
  8207. goto error;
  8208. map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
  8209. if (!map)
  8210. goto error;
  8211. map = isl_map_add_basic_map(map, bmap1);
  8212. map = isl_map_add_basic_map(map, bmap2);
  8213. return map;
  8214. error:
  8215. isl_basic_map_free(bmap1);
  8216. isl_basic_map_free(bmap2);
  8217. return NULL;
  8218. }
  8219. __isl_give isl_set *isl_basic_set_union(__isl_take isl_basic_set *bset1,
  8220. __isl_take isl_basic_set *bset2)
  8221. {
  8222. return set_from_map(isl_basic_map_union(bset_to_bmap(bset1),
  8223. bset_to_bmap(bset2)));
  8224. }
  8225. /* Order divs such that any div only depends on previous divs */
  8226. __isl_give isl_basic_map *isl_basic_map_order_divs(
  8227. __isl_take isl_basic_map *bmap)
  8228. {
  8229. int i;
  8230. isl_size off;
  8231. off = isl_basic_map_var_offset(bmap, isl_dim_div);
  8232. if (off < 0)
  8233. return isl_basic_map_free(bmap);
  8234. for (i = 0; i < bmap->n_div; ++i) {
  8235. int pos;
  8236. if (isl_int_is_zero(bmap->div[i][0]))
  8237. continue;
  8238. pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
  8239. bmap->n_div-i);
  8240. if (pos == -1)
  8241. continue;
  8242. if (pos == 0)
  8243. isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,
  8244. "integer division depends on itself",
  8245. return isl_basic_map_free(bmap));
  8246. bmap = isl_basic_map_swap_div(bmap, i, i + pos);
  8247. if (!bmap)
  8248. return NULL;
  8249. --i;
  8250. }
  8251. return bmap;
  8252. }
  8253. __isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
  8254. {
  8255. int i;
  8256. if (!map)
  8257. return 0;
  8258. for (i = 0; i < map->n; ++i) {
  8259. map->p[i] = isl_basic_map_order_divs(map->p[i]);
  8260. if (!map->p[i])
  8261. goto error;
  8262. }
  8263. return map;
  8264. error:
  8265. isl_map_free(map);
  8266. return NULL;
  8267. }
  8268. /* Sort the local variables of "bset".
  8269. */
  8270. __isl_give isl_basic_set *isl_basic_set_sort_divs(
  8271. __isl_take isl_basic_set *bset)
  8272. {
  8273. return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset)));
  8274. }
  8275. /* Apply the expansion computed by isl_merge_divs.
  8276. * The expansion itself is given by "exp" while the resulting
  8277. * list of divs is given by "div".
  8278. *
  8279. * Move the integer divisions of "bmap" into the right position
  8280. * according to "exp" and then introduce the additional integer
  8281. * divisions, adding div constraints.
  8282. * The moving should be done first to avoid moving coefficients
  8283. * in the definitions of the extra integer divisions.
  8284. */
  8285. __isl_give isl_basic_map *isl_basic_map_expand_divs(
  8286. __isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp)
  8287. {
  8288. int i, j;
  8289. int n_div;
  8290. bmap = isl_basic_map_cow(bmap);
  8291. if (!bmap || !div)
  8292. goto error;
  8293. if (div->n_row < bmap->n_div)
  8294. isl_die(isl_mat_get_ctx(div), isl_error_invalid,
  8295. "not an expansion", goto error);
  8296. n_div = bmap->n_div;
  8297. bmap = isl_basic_map_extend(bmap, div->n_row - n_div, 0,
  8298. 2 * (div->n_row - n_div));
  8299. for (i = n_div; i < div->n_row; ++i)
  8300. if (isl_basic_map_alloc_div(bmap) < 0)
  8301. goto error;
  8302. for (j = n_div - 1; j >= 0; --j) {
  8303. if (exp[j] == j)
  8304. break;
  8305. bmap = isl_basic_map_swap_div(bmap, j, exp[j]);
  8306. if (!bmap)
  8307. goto error;
  8308. }
  8309. j = 0;
  8310. for (i = 0; i < div->n_row; ++i) {
  8311. if (j < n_div && exp[j] == i) {
  8312. j++;
  8313. } else {
  8314. isl_seq_cpy(bmap->div[i], div->row[i], div->n_col);
  8315. if (isl_basic_map_div_is_marked_unknown(bmap, i))
  8316. continue;
  8317. bmap = isl_basic_map_add_div_constraints(bmap, i);
  8318. if (!bmap)
  8319. goto error;
  8320. }
  8321. }
  8322. isl_mat_free(div);
  8323. return bmap;
  8324. error:
  8325. isl_basic_map_free(bmap);
  8326. isl_mat_free(div);
  8327. return NULL;
  8328. }
  8329. /* Apply the expansion computed by isl_merge_divs.
  8330. * The expansion itself is given by "exp" while the resulting
  8331. * list of divs is given by "div".
  8332. */
  8333. __isl_give isl_basic_set *isl_basic_set_expand_divs(
  8334. __isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp)
  8335. {
  8336. return isl_basic_map_expand_divs(bset, div, exp);
  8337. }
  8338. /* Look for a div in dst that corresponds to the div "div" in src.
  8339. * The divs before "div" in src and dst are assumed to be the same.
  8340. *
  8341. * Return the position of the corresponding div in dst
  8342. * if there is one. Otherwise, return a position beyond the integer divisions.
  8343. * Return -1 on error.
  8344. */
  8345. static int find_div(__isl_keep isl_basic_map *dst,
  8346. __isl_keep isl_basic_map *src, unsigned div)
  8347. {
  8348. int i;
  8349. isl_size n_div;
  8350. isl_size v_div;
  8351. v_div = isl_basic_map_var_offset(src, isl_dim_div);
  8352. n_div = isl_basic_map_dim(dst, isl_dim_div);
  8353. if (n_div < 0 || v_div < 0)
  8354. return -1;
  8355. isl_assert(dst->ctx, div <= n_div, return -1);
  8356. for (i = div; i < n_div; ++i)
  8357. if (isl_seq_eq(dst->div[i], src->div[div], 1+1+v_div+div) &&
  8358. isl_seq_first_non_zero(dst->div[i] + 1 + 1 + v_div + div,
  8359. n_div - div) == -1)
  8360. return i;
  8361. return n_div;
  8362. }
  8363. /* Align the divs of "dst" to those of "src", adding divs from "src"
  8364. * if needed. That is, make sure that the first src->n_div divs
  8365. * of the result are equal to those of src.
  8366. * The integer division of "src" are assumed to be ordered.
  8367. *
  8368. * The integer divisions are swapped into the right position
  8369. * (possibly after adding them first). This may result
  8370. * in the remaining integer divisions appearing in the wrong order,
  8371. * i.e., with some integer division appearing before
  8372. * some other integer division on which it depends.
  8373. * The integer divisions therefore need to be ordered.
  8374. * This will not affect the integer divisions aligned to those of "src",
  8375. * since "src" is assumed to have ordered integer divisions.
  8376. *
  8377. * The result is not finalized as by design it will have redundant
  8378. * divs if any divs from "src" were copied.
  8379. */
  8380. __isl_give isl_basic_map *isl_basic_map_align_divs(
  8381. __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src)
  8382. {
  8383. int i;
  8384. isl_bool known;
  8385. int extended;
  8386. isl_size v_div;
  8387. isl_size dst_n_div;
  8388. if (!dst || !src)
  8389. return isl_basic_map_free(dst);
  8390. if (src->n_div == 0)
  8391. return dst;
  8392. known = isl_basic_map_divs_known(src);
  8393. if (known < 0)
  8394. return isl_basic_map_free(dst);
  8395. if (!known)
  8396. isl_die(isl_basic_map_get_ctx(src), isl_error_invalid,
  8397. "some src divs are unknown",
  8398. return isl_basic_map_free(dst));
  8399. v_div = isl_basic_map_var_offset(src, isl_dim_div);
  8400. if (v_div < 0)
  8401. return isl_basic_map_free(dst);
  8402. extended = 0;
  8403. dst_n_div = isl_basic_map_dim(dst, isl_dim_div);
  8404. if (dst_n_div < 0)
  8405. dst = isl_basic_map_free(dst);
  8406. for (i = 0; i < src->n_div; ++i) {
  8407. int j = find_div(dst, src, i);
  8408. if (j < 0)
  8409. dst = isl_basic_map_free(dst);
  8410. if (j == dst_n_div) {
  8411. if (!extended) {
  8412. int extra = src->n_div - i;
  8413. dst = isl_basic_map_cow(dst);
  8414. if (!dst)
  8415. return isl_basic_map_free(dst);
  8416. dst = isl_basic_map_extend(dst,
  8417. extra, 0, 2 * extra);
  8418. extended = 1;
  8419. }
  8420. j = isl_basic_map_alloc_div(dst);
  8421. if (j < 0)
  8422. return isl_basic_map_free(dst);
  8423. isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i);
  8424. isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i);
  8425. dst_n_div++;
  8426. dst = isl_basic_map_add_div_constraints(dst, j);
  8427. if (!dst)
  8428. return isl_basic_map_free(dst);
  8429. }
  8430. if (j != i)
  8431. dst = isl_basic_map_swap_div(dst, i, j);
  8432. if (!dst)
  8433. return isl_basic_map_free(dst);
  8434. }
  8435. return isl_basic_map_order_divs(dst);
  8436. }
  8437. __isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
  8438. {
  8439. int i;
  8440. if (!map)
  8441. return NULL;
  8442. if (map->n == 0)
  8443. return map;
  8444. map = isl_map_compute_divs(map);
  8445. map = isl_map_order_divs(map);
  8446. map = isl_map_cow(map);
  8447. if (!map)
  8448. return NULL;
  8449. for (i = 1; i < map->n; ++i)
  8450. map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
  8451. for (i = 1; i < map->n; ++i) {
  8452. map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
  8453. if (!map->p[i])
  8454. return isl_map_free(map);
  8455. }
  8456. map = isl_map_unmark_normalized(map);
  8457. return map;
  8458. }
  8459. __isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map)
  8460. {
  8461. return isl_map_align_divs_internal(map);
  8462. }
  8463. __isl_give isl_set *isl_set_align_divs(__isl_take isl_set *set)
  8464. {
  8465. return set_from_map(isl_map_align_divs_internal(set_to_map(set)));
  8466. }
  8467. /* Align the divs of the basic maps in "map" to those
  8468. * of the basic maps in "list", as well as to the other basic maps in "map".
  8469. * The elements in "list" are assumed to have known divs.
  8470. */
  8471. __isl_give isl_map *isl_map_align_divs_to_basic_map_list(
  8472. __isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
  8473. {
  8474. int i;
  8475. isl_size n;
  8476. n = isl_basic_map_list_n_basic_map(list);
  8477. map = isl_map_compute_divs(map);
  8478. map = isl_map_cow(map);
  8479. if (!map || n < 0)
  8480. return isl_map_free(map);
  8481. if (map->n == 0)
  8482. return map;
  8483. for (i = 0; i < n; ++i) {
  8484. isl_basic_map *bmap;
  8485. bmap = isl_basic_map_list_get_basic_map(list, i);
  8486. bmap = isl_basic_map_order_divs(bmap);
  8487. map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
  8488. isl_basic_map_free(bmap);
  8489. }
  8490. if (!map->p[0])
  8491. return isl_map_free(map);
  8492. return isl_map_align_divs_internal(map);
  8493. }
  8494. /* Align the divs of each element of "list" to those of "bmap".
  8495. * Both "bmap" and the elements of "list" are assumed to have known divs.
  8496. */
  8497. __isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
  8498. __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
  8499. {
  8500. int i;
  8501. isl_size n;
  8502. n = isl_basic_map_list_n_basic_map(list);
  8503. if (n < 0 || !bmap)
  8504. return isl_basic_map_list_free(list);
  8505. for (i = 0; i < n; ++i) {
  8506. isl_basic_map *bmap_i;
  8507. bmap_i = isl_basic_map_list_get_basic_map(list, i);
  8508. bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
  8509. list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
  8510. }
  8511. return list;
  8512. }
  8513. __isl_give isl_set *isl_set_apply( __isl_take isl_set *set,
  8514. __isl_take isl_map *map)
  8515. {
  8516. isl_bool ok;
  8517. isl_map_align_params_set(&map, &set);
  8518. ok = isl_map_compatible_domain(map, set);
  8519. if (ok < 0)
  8520. goto error;
  8521. if (!ok)
  8522. isl_die(isl_set_get_ctx(set), isl_error_invalid,
  8523. "incompatible spaces", goto error);
  8524. map = isl_map_intersect_domain(map, set);
  8525. set = isl_map_range(map);
  8526. return set;
  8527. error:
  8528. isl_set_free(set);
  8529. isl_map_free(map);
  8530. return NULL;
  8531. }
  8532. /* There is no need to cow as removing empty parts doesn't change
  8533. * the meaning of the set.
  8534. */
  8535. __isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map)
  8536. {
  8537. int i;
  8538. if (!map)
  8539. return NULL;
  8540. for (i = map->n - 1; i >= 0; --i)
  8541. map = remove_if_empty(map, i);
  8542. return map;
  8543. }
  8544. __isl_give isl_set *isl_set_remove_empty_parts(__isl_take isl_set *set)
  8545. {
  8546. return set_from_map(isl_map_remove_empty_parts(set_to_map(set)));
  8547. }
  8548. /* Create a binary relation that maps the shared initial "pos" dimensions
  8549. * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
  8550. */
  8551. static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_set *bset1,
  8552. __isl_keep isl_basic_set *bset2, int pos)
  8553. {
  8554. isl_basic_map *bmap1;
  8555. isl_basic_map *bmap2;
  8556. bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1));
  8557. bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2));
  8558. bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0,
  8559. isl_dim_out, 0, pos);
  8560. bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0,
  8561. isl_dim_out, 0, pos);
  8562. return isl_basic_map_range_product(bmap1, bmap2);
  8563. }
  8564. /* Given two basic sets bset1 and bset2, compute the maximal difference
  8565. * between the values of dimension pos in bset1 and those in bset2
  8566. * for any common value of the parameters and dimensions preceding pos.
  8567. */
  8568. static enum isl_lp_result basic_set_maximal_difference_at(
  8569. __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
  8570. int pos, isl_int *opt)
  8571. {
  8572. isl_basic_map *bmap1;
  8573. struct isl_ctx *ctx;
  8574. struct isl_vec *obj;
  8575. isl_size total;
  8576. isl_size nparam;
  8577. isl_size dim1;
  8578. enum isl_lp_result res;
  8579. nparam = isl_basic_set_dim(bset1, isl_dim_param);
  8580. dim1 = isl_basic_set_dim(bset1, isl_dim_set);
  8581. if (nparam < 0 || dim1 < 0 || !bset2)
  8582. return isl_lp_error;
  8583. bmap1 = join_initial(bset1, bset2, pos);
  8584. total = isl_basic_map_dim(bmap1, isl_dim_all);
  8585. if (total < 0)
  8586. return isl_lp_error;
  8587. ctx = bmap1->ctx;
  8588. obj = isl_vec_alloc(ctx, 1 + total);
  8589. if (!obj)
  8590. goto error;
  8591. isl_seq_clr(obj->block.data, 1 + total);
  8592. isl_int_set_si(obj->block.data[1+nparam+pos], 1);
  8593. isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
  8594. res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
  8595. opt, NULL, NULL);
  8596. isl_basic_map_free(bmap1);
  8597. isl_vec_free(obj);
  8598. return res;
  8599. error:
  8600. isl_basic_map_free(bmap1);
  8601. return isl_lp_error;
  8602. }
  8603. /* Given two _disjoint_ basic sets bset1 and bset2, check whether
  8604. * for any common value of the parameters and dimensions preceding pos
  8605. * in both basic sets, the values of dimension pos in bset1 are
  8606. * smaller or larger than those in bset2.
  8607. *
  8608. * Returns
  8609. * 1 if bset1 follows bset2
  8610. * -1 if bset1 precedes bset2
  8611. * 0 if bset1 and bset2 are incomparable
  8612. * -2 if some error occurred.
  8613. */
  8614. int isl_basic_set_compare_at(__isl_keep isl_basic_set *bset1,
  8615. __isl_keep isl_basic_set *bset2, int pos)
  8616. {
  8617. isl_int opt;
  8618. enum isl_lp_result res;
  8619. int cmp;
  8620. isl_int_init(opt);
  8621. res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
  8622. if (res == isl_lp_empty)
  8623. cmp = 0;
  8624. else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
  8625. res == isl_lp_unbounded)
  8626. cmp = 1;
  8627. else if (res == isl_lp_ok && isl_int_is_neg(opt))
  8628. cmp = -1;
  8629. else
  8630. cmp = -2;
  8631. isl_int_clear(opt);
  8632. return cmp;
  8633. }
  8634. /* Given two basic sets bset1 and bset2, check whether
  8635. * for any common value of the parameters and dimensions preceding pos
  8636. * there is a value of dimension pos in bset1 that is larger
  8637. * than a value of the same dimension in bset2.
  8638. *
  8639. * Return
  8640. * 1 if there exists such a pair
  8641. * 0 if there is no such pair, but there is a pair of equal values
  8642. * -1 otherwise
  8643. * -2 if some error occurred.
  8644. */
  8645. int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
  8646. __isl_keep isl_basic_set *bset2, int pos)
  8647. {
  8648. isl_bool empty;
  8649. isl_basic_map *bmap;
  8650. isl_size dim1;
  8651. dim1 = isl_basic_set_dim(bset1, isl_dim_set);
  8652. if (dim1 < 0)
  8653. return -2;
  8654. bmap = join_initial(bset1, bset2, pos);
  8655. bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0,
  8656. isl_dim_out, dim1 - pos);
  8657. empty = isl_basic_map_is_empty(bmap);
  8658. if (empty < 0)
  8659. goto error;
  8660. if (empty) {
  8661. isl_basic_map_free(bmap);
  8662. return -1;
  8663. }
  8664. bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0,
  8665. isl_dim_out, dim1 - pos);
  8666. empty = isl_basic_map_is_empty(bmap);
  8667. if (empty < 0)
  8668. goto error;
  8669. isl_basic_map_free(bmap);
  8670. if (empty)
  8671. return 0;
  8672. return 1;
  8673. error:
  8674. isl_basic_map_free(bmap);
  8675. return -2;
  8676. }
  8677. /* Given two sets set1 and set2, check whether
  8678. * for any common value of the parameters and dimensions preceding pos
  8679. * there is a value of dimension pos in set1 that is larger
  8680. * than a value of the same dimension in set2.
  8681. *
  8682. * Return
  8683. * 1 if there exists such a pair
  8684. * 0 if there is no such pair, but there is a pair of equal values
  8685. * -1 otherwise
  8686. * -2 if some error occurred.
  8687. */
  8688. int isl_set_follows_at(__isl_keep isl_set *set1,
  8689. __isl_keep isl_set *set2, int pos)
  8690. {
  8691. int i, j;
  8692. int follows = -1;
  8693. if (!set1 || !set2)
  8694. return -2;
  8695. for (i = 0; i < set1->n; ++i)
  8696. for (j = 0; j < set2->n; ++j) {
  8697. int f;
  8698. f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
  8699. if (f == 1 || f == -2)
  8700. return f;
  8701. if (f > follows)
  8702. follows = f;
  8703. }
  8704. return follows;
  8705. }
  8706. static isl_bool isl_basic_map_plain_has_fixed_var(
  8707. __isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val)
  8708. {
  8709. int i;
  8710. int d;
  8711. isl_size total;
  8712. total = isl_basic_map_dim(bmap, isl_dim_all);
  8713. if (total < 0)
  8714. return isl_bool_error;
  8715. for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
  8716. for (; d+1 > pos; --d)
  8717. if (!isl_int_is_zero(bmap->eq[i][1+d]))
  8718. break;
  8719. if (d != pos)
  8720. continue;
  8721. if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
  8722. return isl_bool_false;
  8723. if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
  8724. return isl_bool_false;
  8725. if (!isl_int_is_one(bmap->eq[i][1+d]))
  8726. return isl_bool_false;
  8727. if (val)
  8728. isl_int_neg(*val, bmap->eq[i][0]);
  8729. return isl_bool_true;
  8730. }
  8731. return isl_bool_false;
  8732. }
  8733. static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
  8734. unsigned pos, isl_int *val)
  8735. {
  8736. int i;
  8737. isl_int v;
  8738. isl_int tmp;
  8739. isl_bool fixed;
  8740. if (!map)
  8741. return isl_bool_error;
  8742. if (map->n == 0)
  8743. return isl_bool_false;
  8744. if (map->n == 1)
  8745. return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val);
  8746. isl_int_init(v);
  8747. isl_int_init(tmp);
  8748. fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v);
  8749. for (i = 1; fixed == isl_bool_true && i < map->n; ++i) {
  8750. fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp);
  8751. if (fixed == isl_bool_true && isl_int_ne(tmp, v))
  8752. fixed = isl_bool_false;
  8753. }
  8754. if (val)
  8755. isl_int_set(*val, v);
  8756. isl_int_clear(tmp);
  8757. isl_int_clear(v);
  8758. return fixed;
  8759. }
  8760. static isl_bool isl_basic_set_plain_has_fixed_var(
  8761. __isl_keep isl_basic_set *bset, unsigned pos, isl_int *val)
  8762. {
  8763. return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset),
  8764. pos, val);
  8765. }
  8766. isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
  8767. enum isl_dim_type type, unsigned pos, isl_int *val)
  8768. {
  8769. if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
  8770. return isl_bool_error;
  8771. return isl_basic_map_plain_has_fixed_var(bmap,
  8772. isl_basic_map_offset(bmap, type) - 1 + pos, val);
  8773. }
  8774. /* If "bmap" obviously lies on a hyperplane where the given dimension
  8775. * has a fixed value, then return that value.
  8776. * Otherwise return NaN.
  8777. */
  8778. __isl_give isl_val *isl_basic_map_plain_get_val_if_fixed(
  8779. __isl_keep isl_basic_map *bmap,
  8780. enum isl_dim_type type, unsigned pos)
  8781. {
  8782. isl_ctx *ctx;
  8783. isl_val *v;
  8784. isl_bool fixed;
  8785. if (!bmap)
  8786. return NULL;
  8787. ctx = isl_basic_map_get_ctx(bmap);
  8788. v = isl_val_alloc(ctx);
  8789. if (!v)
  8790. return NULL;
  8791. fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n);
  8792. if (fixed < 0)
  8793. return isl_val_free(v);
  8794. if (fixed) {
  8795. isl_int_set_si(v->d, 1);
  8796. return v;
  8797. }
  8798. isl_val_free(v);
  8799. return isl_val_nan(ctx);
  8800. }
  8801. isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
  8802. enum isl_dim_type type, unsigned pos, isl_int *val)
  8803. {
  8804. if (isl_map_check_range(map, type, pos, 1) < 0)
  8805. return isl_bool_error;
  8806. return isl_map_plain_has_fixed_var(map,
  8807. map_offset(map, type) - 1 + pos, val);
  8808. }
  8809. /* If "map" obviously lies on a hyperplane where the given dimension
  8810. * has a fixed value, then return that value.
  8811. * Otherwise return NaN.
  8812. */
  8813. __isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
  8814. enum isl_dim_type type, unsigned pos)
  8815. {
  8816. isl_ctx *ctx;
  8817. isl_val *v;
  8818. isl_bool fixed;
  8819. if (!map)
  8820. return NULL;
  8821. ctx = isl_map_get_ctx(map);
  8822. v = isl_val_alloc(ctx);
  8823. if (!v)
  8824. return NULL;
  8825. fixed = isl_map_plain_is_fixed(map, type, pos, &v->n);
  8826. if (fixed < 0)
  8827. return isl_val_free(v);
  8828. if (fixed) {
  8829. isl_int_set_si(v->d, 1);
  8830. return v;
  8831. }
  8832. isl_val_free(v);
  8833. return isl_val_nan(ctx);
  8834. }
  8835. /* If "set" obviously lies on a hyperplane where the given dimension
  8836. * has a fixed value, then return that value.
  8837. * Otherwise return NaN.
  8838. */
  8839. __isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_set *set,
  8840. enum isl_dim_type type, unsigned pos)
  8841. {
  8842. return isl_map_plain_get_val_if_fixed(set, type, pos);
  8843. }
  8844. /* Return a sequence of values in the same space as "set"
  8845. * that are equal to the corresponding set dimensions of "set"
  8846. * for those set dimensions that obviously lie on a hyperplane
  8847. * where the dimension has a fixed value.
  8848. * The other elements are set to NaN.
  8849. */
  8850. __isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed(
  8851. __isl_keep isl_set *set)
  8852. {
  8853. int i;
  8854. isl_size n;
  8855. isl_space *space;
  8856. isl_multi_val *mv;
  8857. space = isl_space_drop_all_params(isl_set_get_space(set));
  8858. mv = isl_multi_val_alloc(space);
  8859. n = isl_multi_val_size(mv);
  8860. if (n < 0)
  8861. return isl_multi_val_free(mv);
  8862. for (i = 0; i < n; ++i) {
  8863. isl_val *v;
  8864. v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, i);
  8865. mv = isl_multi_val_set_val(mv, i, v);
  8866. }
  8867. return mv;
  8868. }
  8869. /* Check if dimension dim has fixed value and if so and if val is not NULL,
  8870. * then return this fixed value in *val.
  8871. */
  8872. isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
  8873. unsigned dim, isl_int *val)
  8874. {
  8875. isl_size nparam;
  8876. nparam = isl_basic_set_dim(bset, isl_dim_param);
  8877. if (nparam < 0)
  8878. return isl_bool_error;
  8879. return isl_basic_set_plain_has_fixed_var(bset, nparam + dim, val);
  8880. }
  8881. /* Return -1 if the constraint "c1" should be sorted before "c2"
  8882. * and 1 if it should be sorted after "c2".
  8883. * Return 0 if the two constraints are the same (up to the constant term).
  8884. *
  8885. * In particular, if a constraint involves later variables than another
  8886. * then it is sorted after this other constraint.
  8887. * uset_gist depends on constraints without existentially quantified
  8888. * variables sorting first.
  8889. *
  8890. * For constraints that have the same latest variable, those
  8891. * with the same coefficient for this latest variable (first in absolute value
  8892. * and then in actual value) are grouped together.
  8893. * This is useful for detecting pairs of constraints that can
  8894. * be chained in their printed representation.
  8895. *
  8896. * Finally, within a group, constraints are sorted according to
  8897. * their coefficients (excluding the constant term).
  8898. */
  8899. static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
  8900. {
  8901. isl_int **c1 = (isl_int **) p1;
  8902. isl_int **c2 = (isl_int **) p2;
  8903. int l1, l2;
  8904. unsigned size = *(unsigned *) arg;
  8905. int cmp;
  8906. l1 = isl_seq_last_non_zero(*c1 + 1, size);
  8907. l2 = isl_seq_last_non_zero(*c2 + 1, size);
  8908. if (l1 != l2)
  8909. return l1 - l2;
  8910. cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
  8911. if (cmp != 0)
  8912. return cmp;
  8913. cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
  8914. if (cmp != 0)
  8915. return -cmp;
  8916. return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
  8917. }
  8918. /* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
  8919. * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
  8920. * and 0 if the two constraints are the same (up to the constant term).
  8921. */
  8922. int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
  8923. isl_int *c1, isl_int *c2)
  8924. {
  8925. isl_size total;
  8926. unsigned size;
  8927. total = isl_basic_map_dim(bmap, isl_dim_all);
  8928. if (total < 0)
  8929. return -2;
  8930. size = total;
  8931. return sort_constraint_cmp(&c1, &c2, &size);
  8932. }
  8933. __isl_give isl_basic_map *isl_basic_map_sort_constraints(
  8934. __isl_take isl_basic_map *bmap)
  8935. {
  8936. isl_size total;
  8937. unsigned size;
  8938. if (!bmap)
  8939. return NULL;
  8940. if (bmap->n_ineq == 0)
  8941. return bmap;
  8942. if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_SORTED))
  8943. return bmap;
  8944. total = isl_basic_map_dim(bmap, isl_dim_all);
  8945. if (total < 0)
  8946. return isl_basic_map_free(bmap);
  8947. size = total;
  8948. if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *),
  8949. &sort_constraint_cmp, &size) < 0)
  8950. return isl_basic_map_free(bmap);
  8951. ISL_F_SET(bmap, ISL_BASIC_MAP_SORTED);
  8952. return bmap;
  8953. }
  8954. __isl_give isl_basic_set *isl_basic_set_sort_constraints(
  8955. __isl_take isl_basic_set *bset)
  8956. {
  8957. isl_basic_map *bmap = bset_to_bmap(bset);
  8958. return bset_from_bmap(isl_basic_map_sort_constraints(bmap));
  8959. }
  8960. __isl_give isl_basic_map *isl_basic_map_normalize(
  8961. __isl_take isl_basic_map *bmap)
  8962. {
  8963. bmap = isl_basic_map_remove_redundancies(bmap);
  8964. bmap = isl_basic_map_sort_constraints(bmap);
  8965. return bmap;
  8966. }
  8967. int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1,
  8968. __isl_keep isl_basic_map *bmap2)
  8969. {
  8970. int i, cmp;
  8971. isl_size total;
  8972. isl_space *space1, *space2;
  8973. if (!bmap1 || !bmap2)
  8974. return -1;
  8975. if (bmap1 == bmap2)
  8976. return 0;
  8977. space1 = isl_basic_map_peek_space(bmap1);
  8978. space2 = isl_basic_map_peek_space(bmap2);
  8979. cmp = isl_space_cmp(space1, space2);
  8980. if (cmp)
  8981. return cmp;
  8982. if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) !=
  8983. ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL))
  8984. return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) ? -1 : 1;
  8985. if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
  8986. ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
  8987. return 0;
  8988. if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
  8989. return 1;
  8990. if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
  8991. return -1;
  8992. if (bmap1->n_eq != bmap2->n_eq)
  8993. return bmap1->n_eq - bmap2->n_eq;
  8994. if (bmap1->n_ineq != bmap2->n_ineq)
  8995. return bmap1->n_ineq - bmap2->n_ineq;
  8996. if (bmap1->n_div != bmap2->n_div)
  8997. return bmap1->n_div - bmap2->n_div;
  8998. total = isl_basic_map_dim(bmap1, isl_dim_all);
  8999. if (total < 0)
  9000. return -1;
  9001. for (i = 0; i < bmap1->n_eq; ++i) {
  9002. cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
  9003. if (cmp)
  9004. return cmp;
  9005. }
  9006. for (i = 0; i < bmap1->n_ineq; ++i) {
  9007. cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
  9008. if (cmp)
  9009. return cmp;
  9010. }
  9011. for (i = 0; i < bmap1->n_div; ++i) {
  9012. cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
  9013. if (cmp)
  9014. return cmp;
  9015. }
  9016. return 0;
  9017. }
  9018. int isl_basic_set_plain_cmp(__isl_keep isl_basic_set *bset1,
  9019. __isl_keep isl_basic_set *bset2)
  9020. {
  9021. return isl_basic_map_plain_cmp(bset1, bset2);
  9022. }
  9023. int isl_set_plain_cmp(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
  9024. {
  9025. int i, cmp;
  9026. if (set1 == set2)
  9027. return 0;
  9028. if (set1->n != set2->n)
  9029. return set1->n - set2->n;
  9030. for (i = 0; i < set1->n; ++i) {
  9031. cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
  9032. if (cmp)
  9033. return cmp;
  9034. }
  9035. return 0;
  9036. }
  9037. isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
  9038. __isl_keep isl_basic_map *bmap2)
  9039. {
  9040. if (!bmap1 || !bmap2)
  9041. return isl_bool_error;
  9042. return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
  9043. }
  9044. isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1,
  9045. __isl_keep isl_basic_set *bset2)
  9046. {
  9047. return isl_basic_map_plain_is_equal(bset_to_bmap(bset1),
  9048. bset_to_bmap(bset2));
  9049. }
  9050. static int qsort_bmap_cmp(const void *p1, const void *p2)
  9051. {
  9052. isl_basic_map *bmap1 = *(isl_basic_map **) p1;
  9053. isl_basic_map *bmap2 = *(isl_basic_map **) p2;
  9054. return isl_basic_map_plain_cmp(bmap1, bmap2);
  9055. }
  9056. /* Sort the basic maps of "map" and remove duplicate basic maps.
  9057. *
  9058. * While removing basic maps, we make sure that the basic maps remain
  9059. * sorted because isl_map_normalize expects the basic maps of the result
  9060. * to be sorted.
  9061. */
  9062. static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map)
  9063. {
  9064. int i, j;
  9065. map = isl_map_remove_empty_parts(map);
  9066. if (!map)
  9067. return NULL;
  9068. qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
  9069. for (i = map->n - 1; i >= 1; --i) {
  9070. if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i]))
  9071. continue;
  9072. isl_basic_map_free(map->p[i-1]);
  9073. for (j = i; j < map->n; ++j)
  9074. map->p[j - 1] = map->p[j];
  9075. map->n--;
  9076. }
  9077. return map;
  9078. }
  9079. /* Remove obvious duplicates among the basic maps of "map".
  9080. *
  9081. * Unlike isl_map_normalize, this function does not remove redundant
  9082. * constraints and only removes duplicates that have exactly the same
  9083. * constraints in the input. It does sort the constraints and
  9084. * the basic maps to ease the detection of duplicates.
  9085. *
  9086. * If "map" has already been normalized or if the basic maps are
  9087. * disjoint, then there can be no duplicates.
  9088. */
  9089. __isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map)
  9090. {
  9091. int i;
  9092. isl_basic_map *bmap;
  9093. if (!map)
  9094. return NULL;
  9095. if (map->n <= 1)
  9096. return map;
  9097. if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT))
  9098. return map;
  9099. for (i = 0; i < map->n; ++i) {
  9100. bmap = isl_basic_map_copy(map->p[i]);
  9101. bmap = isl_basic_map_sort_constraints(bmap);
  9102. if (!bmap)
  9103. return isl_map_free(map);
  9104. isl_basic_map_free(map->p[i]);
  9105. map->p[i] = bmap;
  9106. }
  9107. map = sort_and_remove_duplicates(map);
  9108. return map;
  9109. }
  9110. /* We normalize in place, but if anything goes wrong we need
  9111. * to return NULL, so we need to make sure we don't change the
  9112. * meaning of any possible other copies of map.
  9113. */
  9114. __isl_give isl_map *isl_map_normalize(__isl_take isl_map *map)
  9115. {
  9116. int i;
  9117. struct isl_basic_map *bmap;
  9118. if (!map)
  9119. return NULL;
  9120. if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
  9121. return map;
  9122. for (i = 0; i < map->n; ++i) {
  9123. bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
  9124. if (!bmap)
  9125. goto error;
  9126. isl_basic_map_free(map->p[i]);
  9127. map->p[i] = bmap;
  9128. }
  9129. map = sort_and_remove_duplicates(map);
  9130. if (map)
  9131. ISL_F_SET(map, ISL_MAP_NORMALIZED);
  9132. return map;
  9133. error:
  9134. isl_map_free(map);
  9135. return NULL;
  9136. }
  9137. __isl_give isl_set *isl_set_normalize(__isl_take isl_set *set)
  9138. {
  9139. return set_from_map(isl_map_normalize(set_to_map(set)));
  9140. }
  9141. isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1,
  9142. __isl_keep isl_map *map2)
  9143. {
  9144. int i;
  9145. isl_bool equal;
  9146. if (!map1 || !map2)
  9147. return isl_bool_error;
  9148. if (map1 == map2)
  9149. return isl_bool_true;
  9150. equal = isl_map_has_equal_space(map1, map2);
  9151. if (equal < 0 || !equal)
  9152. return equal;
  9153. map1 = isl_map_copy(map1);
  9154. map2 = isl_map_copy(map2);
  9155. map1 = isl_map_normalize(map1);
  9156. map2 = isl_map_normalize(map2);
  9157. if (!map1 || !map2)
  9158. goto error;
  9159. equal = map1->n == map2->n;
  9160. for (i = 0; equal && i < map1->n; ++i) {
  9161. equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
  9162. if (equal < 0)
  9163. goto error;
  9164. }
  9165. isl_map_free(map1);
  9166. isl_map_free(map2);
  9167. return equal;
  9168. error:
  9169. isl_map_free(map1);
  9170. isl_map_free(map2);
  9171. return isl_bool_error;
  9172. }
  9173. isl_bool isl_set_plain_is_equal(__isl_keep isl_set *set1,
  9174. __isl_keep isl_set *set2)
  9175. {
  9176. return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2));
  9177. }
  9178. /* Return the basic maps in "map" as a list.
  9179. */
  9180. __isl_give isl_basic_map_list *isl_map_get_basic_map_list(
  9181. __isl_keep isl_map *map)
  9182. {
  9183. int i;
  9184. isl_ctx *ctx;
  9185. isl_basic_map_list *list;
  9186. if (!map)
  9187. return NULL;
  9188. ctx = isl_map_get_ctx(map);
  9189. list = isl_basic_map_list_alloc(ctx, map->n);
  9190. for (i = 0; i < map->n; ++i) {
  9191. isl_basic_map *bmap;
  9192. bmap = isl_basic_map_copy(map->p[i]);
  9193. list = isl_basic_map_list_add(list, bmap);
  9194. }
  9195. return list;
  9196. }
  9197. /* Return the intersection of the elements in the non-empty list "list".
  9198. * All elements are assumed to live in the same space.
  9199. */
  9200. __isl_give isl_basic_map *isl_basic_map_list_intersect(
  9201. __isl_take isl_basic_map_list *list)
  9202. {
  9203. int i;
  9204. isl_size n;
  9205. isl_basic_map *bmap;
  9206. n = isl_basic_map_list_n_basic_map(list);
  9207. if (n < 0)
  9208. goto error;
  9209. if (n < 1)
  9210. isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,
  9211. "expecting non-empty list", goto error);
  9212. bmap = isl_basic_map_list_get_basic_map(list, 0);
  9213. for (i = 1; i < n; ++i) {
  9214. isl_basic_map *bmap_i;
  9215. bmap_i = isl_basic_map_list_get_basic_map(list, i);
  9216. bmap = isl_basic_map_intersect(bmap, bmap_i);
  9217. }
  9218. isl_basic_map_list_free(list);
  9219. return bmap;
  9220. error:
  9221. isl_basic_map_list_free(list);
  9222. return NULL;
  9223. }
  9224. /* Return the intersection of the elements in the non-empty list "list".
  9225. * All elements are assumed to live in the same space.
  9226. */
  9227. __isl_give isl_basic_set *isl_basic_set_list_intersect(
  9228. __isl_take isl_basic_set_list *list)
  9229. {
  9230. return isl_basic_map_list_intersect(list);
  9231. }
  9232. /* Return the union of the elements of "list".
  9233. * The list is required to have at least one element.
  9234. */
  9235. __isl_give isl_set *isl_basic_set_list_union(
  9236. __isl_take isl_basic_set_list *list)
  9237. {
  9238. int i;
  9239. isl_size n;
  9240. isl_space *space;
  9241. isl_basic_set *bset;
  9242. isl_set *set;
  9243. n = isl_basic_set_list_n_basic_set(list);
  9244. if (n < 0)
  9245. goto error;
  9246. if (n < 1)
  9247. isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,
  9248. "expecting non-empty list", goto error);
  9249. bset = isl_basic_set_list_get_basic_set(list, 0);
  9250. space = isl_basic_set_get_space(bset);
  9251. isl_basic_set_free(bset);
  9252. set = isl_set_alloc_space(space, n, 0);
  9253. for (i = 0; i < n; ++i) {
  9254. bset = isl_basic_set_list_get_basic_set(list, i);
  9255. set = isl_set_add_basic_set(set, bset);
  9256. }
  9257. isl_basic_set_list_free(list);
  9258. return set;
  9259. error:
  9260. isl_basic_set_list_free(list);
  9261. return NULL;
  9262. }
  9263. /* Return the union of the elements in the non-empty list "list".
  9264. * All elements are assumed to live in the same space.
  9265. */
  9266. __isl_give isl_set *isl_set_list_union(__isl_take isl_set_list *list)
  9267. {
  9268. int i;
  9269. isl_size n;
  9270. isl_set *set;
  9271. n = isl_set_list_n_set(list);
  9272. if (n < 0)
  9273. goto error;
  9274. if (n < 1)
  9275. isl_die(isl_set_list_get_ctx(list), isl_error_invalid,
  9276. "expecting non-empty list", goto error);
  9277. set = isl_set_list_get_set(list, 0);
  9278. for (i = 1; i < n; ++i) {
  9279. isl_set *set_i;
  9280. set_i = isl_set_list_get_set(list, i);
  9281. set = isl_set_union(set, set_i);
  9282. }
  9283. isl_set_list_free(list);
  9284. return set;
  9285. error:
  9286. isl_set_list_free(list);
  9287. return NULL;
  9288. }
  9289. __isl_give isl_basic_map *isl_basic_map_product(
  9290. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  9291. {
  9292. isl_space *space_result = NULL;
  9293. struct isl_basic_map *bmap;
  9294. unsigned in1, in2, out1, out2, nparam, total, pos;
  9295. struct isl_dim_map *dim_map1, *dim_map2;
  9296. if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
  9297. goto error;
  9298. space_result = isl_space_product(isl_space_copy(bmap1->dim),
  9299. isl_space_copy(bmap2->dim));
  9300. in1 = isl_basic_map_dim(bmap1, isl_dim_in);
  9301. in2 = isl_basic_map_dim(bmap2, isl_dim_in);
  9302. out1 = isl_basic_map_dim(bmap1, isl_dim_out);
  9303. out2 = isl_basic_map_dim(bmap2, isl_dim_out);
  9304. nparam = isl_basic_map_dim(bmap1, isl_dim_param);
  9305. total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
  9306. dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
  9307. dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
  9308. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
  9309. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
  9310. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
  9311. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
  9312. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
  9313. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
  9314. isl_dim_map_div(dim_map1, bmap1, pos += out2);
  9315. isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
  9316. bmap = isl_basic_map_alloc_space(space_result,
  9317. bmap1->n_div + bmap2->n_div,
  9318. bmap1->n_eq + bmap2->n_eq,
  9319. bmap1->n_ineq + bmap2->n_ineq);
  9320. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
  9321. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
  9322. bmap = isl_basic_map_simplify(bmap);
  9323. return isl_basic_map_finalize(bmap);
  9324. error:
  9325. isl_basic_map_free(bmap1);
  9326. isl_basic_map_free(bmap2);
  9327. return NULL;
  9328. }
  9329. __isl_give isl_basic_map *isl_basic_map_flat_product(
  9330. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  9331. {
  9332. isl_basic_map *prod;
  9333. prod = isl_basic_map_product(bmap1, bmap2);
  9334. prod = isl_basic_map_flatten(prod);
  9335. return prod;
  9336. }
  9337. __isl_give isl_basic_set *isl_basic_set_flat_product(
  9338. __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
  9339. {
  9340. return isl_basic_map_flat_range_product(bset1, bset2);
  9341. }
  9342. __isl_give isl_basic_map *isl_basic_map_domain_product(
  9343. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  9344. {
  9345. isl_space *space1, *space2;
  9346. isl_space *space_result = NULL;
  9347. isl_basic_map *bmap;
  9348. isl_size in1, in2, out, nparam;
  9349. unsigned total, pos;
  9350. struct isl_dim_map *dim_map1, *dim_map2;
  9351. in1 = isl_basic_map_dim(bmap1, isl_dim_in);
  9352. in2 = isl_basic_map_dim(bmap2, isl_dim_in);
  9353. out = isl_basic_map_dim(bmap1, isl_dim_out);
  9354. nparam = isl_basic_map_dim(bmap1, isl_dim_param);
  9355. if (in1 < 0 || in2 < 0 || out < 0 || nparam < 0)
  9356. goto error;
  9357. space1 = isl_basic_map_get_space(bmap1);
  9358. space2 = isl_basic_map_get_space(bmap2);
  9359. space_result = isl_space_domain_product(space1, space2);
  9360. total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
  9361. dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
  9362. dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
  9363. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
  9364. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
  9365. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
  9366. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
  9367. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
  9368. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
  9369. isl_dim_map_div(dim_map1, bmap1, pos += out);
  9370. isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
  9371. bmap = isl_basic_map_alloc_space(space_result,
  9372. bmap1->n_div + bmap2->n_div,
  9373. bmap1->n_eq + bmap2->n_eq,
  9374. bmap1->n_ineq + bmap2->n_ineq);
  9375. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
  9376. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
  9377. bmap = isl_basic_map_simplify(bmap);
  9378. return isl_basic_map_finalize(bmap);
  9379. error:
  9380. isl_basic_map_free(bmap1);
  9381. isl_basic_map_free(bmap2);
  9382. return NULL;
  9383. }
  9384. __isl_give isl_basic_map *isl_basic_map_range_product(
  9385. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  9386. {
  9387. isl_bool rational;
  9388. isl_space *space_result = NULL;
  9389. isl_basic_map *bmap;
  9390. isl_size in, out1, out2, nparam;
  9391. unsigned total, pos;
  9392. struct isl_dim_map *dim_map1, *dim_map2;
  9393. rational = isl_basic_map_is_rational(bmap1);
  9394. if (rational >= 0 && rational)
  9395. rational = isl_basic_map_is_rational(bmap2);
  9396. in = isl_basic_map_dim(bmap1, isl_dim_in);
  9397. out1 = isl_basic_map_dim(bmap1, isl_dim_out);
  9398. out2 = isl_basic_map_dim(bmap2, isl_dim_out);
  9399. nparam = isl_basic_map_dim(bmap1, isl_dim_param);
  9400. if (in < 0 || out1 < 0 || out2 < 0 || nparam < 0 || rational < 0)
  9401. goto error;
  9402. if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
  9403. goto error;
  9404. space_result = isl_space_range_product(isl_space_copy(bmap1->dim),
  9405. isl_space_copy(bmap2->dim));
  9406. total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
  9407. dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
  9408. dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
  9409. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
  9410. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
  9411. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
  9412. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
  9413. isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
  9414. isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
  9415. isl_dim_map_div(dim_map1, bmap1, pos += out2);
  9416. isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
  9417. bmap = isl_basic_map_alloc_space(space_result,
  9418. bmap1->n_div + bmap2->n_div,
  9419. bmap1->n_eq + bmap2->n_eq,
  9420. bmap1->n_ineq + bmap2->n_ineq);
  9421. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
  9422. bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
  9423. if (rational)
  9424. bmap = isl_basic_map_set_rational(bmap);
  9425. bmap = isl_basic_map_simplify(bmap);
  9426. return isl_basic_map_finalize(bmap);
  9427. error:
  9428. isl_basic_map_free(bmap1);
  9429. isl_basic_map_free(bmap2);
  9430. return NULL;
  9431. }
  9432. __isl_give isl_basic_map *isl_basic_map_flat_range_product(
  9433. __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
  9434. {
  9435. isl_basic_map *prod;
  9436. prod = isl_basic_map_range_product(bmap1, bmap2);
  9437. prod = isl_basic_map_flatten_range(prod);
  9438. return prod;
  9439. }
  9440. /* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
  9441. * and collect the results.
  9442. * The result live in the space obtained by calling "space_product"
  9443. * on the spaces of "map1" and "map2".
  9444. * If "remove_duplicates" is set then the result may contain duplicates
  9445. * (even if the inputs do not) and so we try and remove the obvious
  9446. * duplicates.
  9447. */
  9448. static __isl_give isl_map *map_product(__isl_take isl_map *map1,
  9449. __isl_take isl_map *map2,
  9450. __isl_give isl_space *(*space_product)(__isl_take isl_space *left,
  9451. __isl_take isl_space *right),
  9452. __isl_give isl_basic_map *(*basic_map_product)(
  9453. __isl_take isl_basic_map *left,
  9454. __isl_take isl_basic_map *right),
  9455. int remove_duplicates)
  9456. {
  9457. unsigned flags = 0;
  9458. struct isl_map *result;
  9459. int i, j;
  9460. isl_bool m;
  9461. m = isl_map_has_equal_params(map1, map2);
  9462. if (m < 0)
  9463. goto error;
  9464. if (!m)
  9465. isl_die(isl_map_get_ctx(map1), isl_error_invalid,
  9466. "parameters don't match", goto error);
  9467. if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
  9468. ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
  9469. ISL_FL_SET(flags, ISL_MAP_DISJOINT);
  9470. result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim),
  9471. isl_space_copy(map2->dim)),
  9472. map1->n * map2->n, flags);
  9473. if (!result)
  9474. goto error;
  9475. for (i = 0; i < map1->n; ++i)
  9476. for (j = 0; j < map2->n; ++j) {
  9477. struct isl_basic_map *part;
  9478. part = basic_map_product(isl_basic_map_copy(map1->p[i]),
  9479. isl_basic_map_copy(map2->p[j]));
  9480. if (isl_basic_map_is_empty(part))
  9481. isl_basic_map_free(part);
  9482. else
  9483. result = isl_map_add_basic_map(result, part);
  9484. if (!result)
  9485. goto error;
  9486. }
  9487. if (remove_duplicates)
  9488. result = isl_map_remove_obvious_duplicates(result);
  9489. isl_map_free(map1);
  9490. isl_map_free(map2);
  9491. return result;
  9492. error:
  9493. isl_map_free(map1);
  9494. isl_map_free(map2);
  9495. return NULL;
  9496. }
  9497. /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
  9498. */
  9499. __isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
  9500. __isl_take isl_map *map2)
  9501. {
  9502. isl_map_align_params_bin(&map1, &map2);
  9503. return map_product(map1, map2, &isl_space_product,
  9504. &isl_basic_map_product, 0);
  9505. }
  9506. /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
  9507. */
  9508. __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
  9509. __isl_take isl_map *map2)
  9510. {
  9511. isl_map *prod;
  9512. prod = isl_map_product(map1, map2);
  9513. prod = isl_map_flatten(prod);
  9514. return prod;
  9515. }
  9516. /* Given two set A and B, construct its Cartesian product A x B.
  9517. */
  9518. __isl_give isl_set *isl_set_product(__isl_take isl_set *set1,
  9519. __isl_take isl_set *set2)
  9520. {
  9521. return isl_map_range_product(set1, set2);
  9522. }
  9523. __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
  9524. __isl_take isl_set *set2)
  9525. {
  9526. return isl_map_flat_range_product(set1, set2);
  9527. }
  9528. /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
  9529. */
  9530. __isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
  9531. __isl_take isl_map *map2)
  9532. {
  9533. isl_map_align_params_bin(&map1, &map2);
  9534. return map_product(map1, map2, &isl_space_domain_product,
  9535. &isl_basic_map_domain_product, 1);
  9536. }
  9537. /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
  9538. */
  9539. __isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
  9540. __isl_take isl_map *map2)
  9541. {
  9542. isl_map_align_params_bin(&map1, &map2);
  9543. return map_product(map1, map2, &isl_space_range_product,
  9544. &isl_basic_map_range_product, 1);
  9545. }
  9546. /* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
  9547. */
  9548. __isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map)
  9549. {
  9550. isl_space *space;
  9551. isl_size total1, keep1, total2, keep2;
  9552. total1 = isl_map_dim(map, isl_dim_in);
  9553. total2 = isl_map_dim(map, isl_dim_out);
  9554. if (total1 < 0 || total2 < 0)
  9555. return isl_map_free(map);
  9556. if (!isl_space_domain_is_wrapping(map->dim) ||
  9557. !isl_space_range_is_wrapping(map->dim))
  9558. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  9559. "not a product", return isl_map_free(map));
  9560. space = isl_map_get_space(map);
  9561. space = isl_space_factor_domain(space);
  9562. keep1 = isl_space_dim(space, isl_dim_in);
  9563. keep2 = isl_space_dim(space, isl_dim_out);
  9564. if (keep1 < 0 || keep2 < 0)
  9565. map = isl_map_free(map);
  9566. map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1);
  9567. map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2);
  9568. map = isl_map_reset_space(map, space);
  9569. return map;
  9570. }
  9571. /* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
  9572. */
  9573. __isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map)
  9574. {
  9575. isl_space *space;
  9576. isl_size total1, keep1, total2, keep2;
  9577. total1 = isl_map_dim(map, isl_dim_in);
  9578. total2 = isl_map_dim(map, isl_dim_out);
  9579. if (total1 < 0 || total2 < 0)
  9580. return isl_map_free(map);
  9581. if (!isl_space_domain_is_wrapping(map->dim) ||
  9582. !isl_space_range_is_wrapping(map->dim))
  9583. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  9584. "not a product", return isl_map_free(map));
  9585. space = isl_map_get_space(map);
  9586. space = isl_space_factor_range(space);
  9587. keep1 = isl_space_dim(space, isl_dim_in);
  9588. keep2 = isl_space_dim(space, isl_dim_out);
  9589. if (keep1 < 0 || keep2 < 0)
  9590. map = isl_map_free(map);
  9591. map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1);
  9592. map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2);
  9593. map = isl_map_reset_space(map, space);
  9594. return map;
  9595. }
  9596. /* Given a map of the form [A -> B] -> C, return the map A -> C.
  9597. */
  9598. __isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map)
  9599. {
  9600. isl_space *space;
  9601. isl_size total, keep;
  9602. total = isl_map_dim(map, isl_dim_in);
  9603. if (total < 0)
  9604. return isl_map_free(map);
  9605. if (!isl_space_domain_is_wrapping(map->dim))
  9606. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  9607. "domain is not a product", return isl_map_free(map));
  9608. space = isl_map_get_space(map);
  9609. space = isl_space_domain_factor_domain(space);
  9610. keep = isl_space_dim(space, isl_dim_in);
  9611. if (keep < 0)
  9612. map = isl_map_free(map);
  9613. map = isl_map_project_out(map, isl_dim_in, keep, total - keep);
  9614. map = isl_map_reset_space(map, space);
  9615. return map;
  9616. }
  9617. /* Given a map of the form [A -> B] -> C, return the map B -> C.
  9618. */
  9619. __isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map)
  9620. {
  9621. isl_space *space;
  9622. isl_size total, keep;
  9623. total = isl_map_dim(map, isl_dim_in);
  9624. if (total < 0)
  9625. return isl_map_free(map);
  9626. if (!isl_space_domain_is_wrapping(map->dim))
  9627. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  9628. "domain is not a product", return isl_map_free(map));
  9629. space = isl_map_get_space(map);
  9630. space = isl_space_domain_factor_range(space);
  9631. keep = isl_space_dim(space, isl_dim_in);
  9632. if (keep < 0)
  9633. map = isl_map_free(map);
  9634. map = isl_map_project_out(map, isl_dim_in, 0, total - keep);
  9635. map = isl_map_reset_space(map, space);
  9636. return map;
  9637. }
  9638. /* Given a map A -> [B -> C], extract the map A -> B.
  9639. */
  9640. __isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map)
  9641. {
  9642. isl_space *space;
  9643. isl_size total, keep;
  9644. total = isl_map_dim(map, isl_dim_out);
  9645. if (total < 0)
  9646. return isl_map_free(map);
  9647. if (!isl_space_range_is_wrapping(map->dim))
  9648. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  9649. "range is not a product", return isl_map_free(map));
  9650. space = isl_map_get_space(map);
  9651. space = isl_space_range_factor_domain(space);
  9652. keep = isl_space_dim(space, isl_dim_out);
  9653. if (keep < 0)
  9654. map = isl_map_free(map);
  9655. map = isl_map_project_out(map, isl_dim_out, keep, total - keep);
  9656. map = isl_map_reset_space(map, space);
  9657. return map;
  9658. }
  9659. /* Given a map A -> [B -> C], extract the map A -> C.
  9660. */
  9661. __isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map)
  9662. {
  9663. isl_space *space;
  9664. isl_size total, keep;
  9665. total = isl_map_dim(map, isl_dim_out);
  9666. if (total < 0)
  9667. return isl_map_free(map);
  9668. if (!isl_space_range_is_wrapping(map->dim))
  9669. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  9670. "range is not a product", return isl_map_free(map));
  9671. space = isl_map_get_space(map);
  9672. space = isl_space_range_factor_range(space);
  9673. keep = isl_space_dim(space, isl_dim_out);
  9674. if (keep < 0)
  9675. map = isl_map_free(map);
  9676. map = isl_map_project_out(map, isl_dim_out, 0, total - keep);
  9677. map = isl_map_reset_space(map, space);
  9678. return map;
  9679. }
  9680. /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
  9681. */
  9682. __isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
  9683. __isl_take isl_map *map2)
  9684. {
  9685. isl_map *prod;
  9686. prod = isl_map_domain_product(map1, map2);
  9687. prod = isl_map_flatten_domain(prod);
  9688. return prod;
  9689. }
  9690. /* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
  9691. */
  9692. __isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
  9693. __isl_take isl_map *map2)
  9694. {
  9695. isl_map *prod;
  9696. prod = isl_map_range_product(map1, map2);
  9697. prod = isl_map_flatten_range(prod);
  9698. return prod;
  9699. }
  9700. uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
  9701. {
  9702. int i;
  9703. uint32_t hash = isl_hash_init();
  9704. isl_size total;
  9705. if (!bmap)
  9706. return 0;
  9707. bmap = isl_basic_map_copy(bmap);
  9708. bmap = isl_basic_map_normalize(bmap);
  9709. total = isl_basic_map_dim(bmap, isl_dim_all);
  9710. if (total < 0)
  9711. return 0;
  9712. isl_hash_byte(hash, bmap->n_eq & 0xFF);
  9713. for (i = 0; i < bmap->n_eq; ++i) {
  9714. uint32_t c_hash;
  9715. c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
  9716. isl_hash_hash(hash, c_hash);
  9717. }
  9718. isl_hash_byte(hash, bmap->n_ineq & 0xFF);
  9719. for (i = 0; i < bmap->n_ineq; ++i) {
  9720. uint32_t c_hash;
  9721. c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
  9722. isl_hash_hash(hash, c_hash);
  9723. }
  9724. isl_hash_byte(hash, bmap->n_div & 0xFF);
  9725. for (i = 0; i < bmap->n_div; ++i) {
  9726. uint32_t c_hash;
  9727. if (isl_int_is_zero(bmap->div[i][0]))
  9728. continue;
  9729. isl_hash_byte(hash, i & 0xFF);
  9730. c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
  9731. isl_hash_hash(hash, c_hash);
  9732. }
  9733. isl_basic_map_free(bmap);
  9734. return hash;
  9735. }
  9736. uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set *bset)
  9737. {
  9738. return isl_basic_map_get_hash(bset_to_bmap(bset));
  9739. }
  9740. uint32_t isl_map_get_hash(__isl_keep isl_map *map)
  9741. {
  9742. int i;
  9743. uint32_t hash;
  9744. if (!map)
  9745. return 0;
  9746. map = isl_map_copy(map);
  9747. map = isl_map_normalize(map);
  9748. if (!map)
  9749. return 0;
  9750. hash = isl_hash_init();
  9751. for (i = 0; i < map->n; ++i) {
  9752. uint32_t bmap_hash;
  9753. bmap_hash = isl_basic_map_get_hash(map->p[i]);
  9754. isl_hash_hash(hash, bmap_hash);
  9755. }
  9756. isl_map_free(map);
  9757. return hash;
  9758. }
  9759. uint32_t isl_set_get_hash(__isl_keep isl_set *set)
  9760. {
  9761. return isl_map_get_hash(set_to_map(set));
  9762. }
  9763. /* Return the number of basic maps in the (current) representation of "map".
  9764. */
  9765. isl_size isl_map_n_basic_map(__isl_keep isl_map *map)
  9766. {
  9767. return map ? map->n : isl_size_error;
  9768. }
  9769. isl_size isl_set_n_basic_set(__isl_keep isl_set *set)
  9770. {
  9771. return set ? set->n : isl_size_error;
  9772. }
  9773. isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map,
  9774. isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
  9775. {
  9776. int i;
  9777. if (!map)
  9778. return isl_stat_error;
  9779. for (i = 0; i < map->n; ++i)
  9780. if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
  9781. return isl_stat_error;
  9782. return isl_stat_ok;
  9783. }
  9784. isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set,
  9785. isl_stat (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
  9786. {
  9787. int i;
  9788. if (!set)
  9789. return isl_stat_error;
  9790. for (i = 0; i < set->n; ++i)
  9791. if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
  9792. return isl_stat_error;
  9793. return isl_stat_ok;
  9794. }
  9795. /* Does "test" succeed on every basic set in "set"?
  9796. */
  9797. isl_bool isl_set_every_basic_set(__isl_keep isl_set *set,
  9798. isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user),
  9799. void *user)
  9800. {
  9801. int i;
  9802. if (!set)
  9803. return isl_bool_error;
  9804. for (i = 0; i < set->n; ++i) {
  9805. isl_bool r;
  9806. r = test(set->p[i], user);
  9807. if (r < 0 || !r)
  9808. return r;
  9809. }
  9810. return isl_bool_true;
  9811. }
  9812. /* Return a list of basic sets, the union of which is equal to "set".
  9813. */
  9814. __isl_give isl_basic_set_list *isl_set_get_basic_set_list(
  9815. __isl_keep isl_set *set)
  9816. {
  9817. int i;
  9818. isl_basic_set_list *list;
  9819. if (!set)
  9820. return NULL;
  9821. list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n);
  9822. for (i = 0; i < set->n; ++i) {
  9823. isl_basic_set *bset;
  9824. bset = isl_basic_set_copy(set->p[i]);
  9825. list = isl_basic_set_list_add(list, bset);
  9826. }
  9827. return list;
  9828. }
  9829. __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
  9830. {
  9831. isl_space *space;
  9832. if (!bset)
  9833. return NULL;
  9834. bset = isl_basic_set_cow(bset);
  9835. if (!bset)
  9836. return NULL;
  9837. space = isl_basic_set_get_space(bset);
  9838. space = isl_space_lift(space, bset->n_div);
  9839. if (!space)
  9840. goto error;
  9841. isl_space_free(bset->dim);
  9842. bset->dim = space;
  9843. bset->extra -= bset->n_div;
  9844. bset->n_div = 0;
  9845. bset = isl_basic_set_finalize(bset);
  9846. return bset;
  9847. error:
  9848. isl_basic_set_free(bset);
  9849. return NULL;
  9850. }
  9851. __isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
  9852. {
  9853. int i;
  9854. isl_space *space;
  9855. unsigned n_div;
  9856. set = set_from_map(isl_map_align_divs_internal(set_to_map(set)));
  9857. if (!set)
  9858. return NULL;
  9859. set = isl_set_cow(set);
  9860. if (!set)
  9861. return NULL;
  9862. n_div = set->p[0]->n_div;
  9863. space = isl_set_get_space(set);
  9864. space = isl_space_lift(space, n_div);
  9865. if (!space)
  9866. goto error;
  9867. isl_space_free(set->dim);
  9868. set->dim = space;
  9869. for (i = 0; i < set->n; ++i) {
  9870. set->p[i] = isl_basic_set_lift(set->p[i]);
  9871. if (!set->p[i])
  9872. goto error;
  9873. }
  9874. return set;
  9875. error:
  9876. isl_set_free(set);
  9877. return NULL;
  9878. }
  9879. int isl_basic_set_size(__isl_keep isl_basic_set *bset)
  9880. {
  9881. isl_size dim;
  9882. int size = 0;
  9883. dim = isl_basic_set_dim(bset, isl_dim_all);
  9884. if (dim < 0)
  9885. return -1;
  9886. size += bset->n_eq * (1 + dim);
  9887. size += bset->n_ineq * (1 + dim);
  9888. size += bset->n_div * (2 + dim);
  9889. return size;
  9890. }
  9891. int isl_set_size(__isl_keep isl_set *set)
  9892. {
  9893. int i;
  9894. int size = 0;
  9895. if (!set)
  9896. return -1;
  9897. for (i = 0; i < set->n; ++i)
  9898. size += isl_basic_set_size(set->p[i]);
  9899. return size;
  9900. }
  9901. /* Check if there is any lower bound (if lower == 0) and/or upper
  9902. * bound (if upper == 0) on the specified dim.
  9903. */
  9904. static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
  9905. enum isl_dim_type type, unsigned pos, int lower, int upper)
  9906. {
  9907. int i;
  9908. if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
  9909. return isl_bool_error;
  9910. pos += isl_basic_map_offset(bmap, type);
  9911. for (i = 0; i < bmap->n_div; ++i) {
  9912. if (isl_int_is_zero(bmap->div[i][0]))
  9913. continue;
  9914. if (!isl_int_is_zero(bmap->div[i][1 + pos]))
  9915. return isl_bool_true;
  9916. }
  9917. for (i = 0; i < bmap->n_eq; ++i)
  9918. if (!isl_int_is_zero(bmap->eq[i][pos]))
  9919. return isl_bool_true;
  9920. for (i = 0; i < bmap->n_ineq; ++i) {
  9921. int sgn = isl_int_sgn(bmap->ineq[i][pos]);
  9922. if (sgn > 0)
  9923. lower = 1;
  9924. if (sgn < 0)
  9925. upper = 1;
  9926. }
  9927. return lower && upper;
  9928. }
  9929. isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
  9930. enum isl_dim_type type, unsigned pos)
  9931. {
  9932. return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
  9933. }
  9934. isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
  9935. enum isl_dim_type type, unsigned pos)
  9936. {
  9937. return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
  9938. }
  9939. isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
  9940. enum isl_dim_type type, unsigned pos)
  9941. {
  9942. return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
  9943. }
  9944. isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map,
  9945. enum isl_dim_type type, unsigned pos)
  9946. {
  9947. int i;
  9948. if (!map)
  9949. return isl_bool_error;
  9950. for (i = 0; i < map->n; ++i) {
  9951. isl_bool bounded;
  9952. bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
  9953. if (bounded < 0 || !bounded)
  9954. return bounded;
  9955. }
  9956. return isl_bool_true;
  9957. }
  9958. /* Return true if the specified dim is involved in both an upper bound
  9959. * and a lower bound.
  9960. */
  9961. isl_bool isl_set_dim_is_bounded(__isl_keep isl_set *set,
  9962. enum isl_dim_type type, unsigned pos)
  9963. {
  9964. return isl_map_dim_is_bounded(set_to_map(set), type, pos);
  9965. }
  9966. /* Does "map" have a bound (according to "fn") for any of its basic maps?
  9967. */
  9968. static isl_bool has_any_bound(__isl_keep isl_map *map,
  9969. enum isl_dim_type type, unsigned pos,
  9970. isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
  9971. enum isl_dim_type type, unsigned pos))
  9972. {
  9973. int i;
  9974. if (!map)
  9975. return isl_bool_error;
  9976. for (i = 0; i < map->n; ++i) {
  9977. isl_bool bounded;
  9978. bounded = fn(map->p[i], type, pos);
  9979. if (bounded < 0 || bounded)
  9980. return bounded;
  9981. }
  9982. return isl_bool_false;
  9983. }
  9984. /* Return 1 if the specified dim is involved in any lower bound.
  9985. */
  9986. isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set,
  9987. enum isl_dim_type type, unsigned pos)
  9988. {
  9989. return has_any_bound(set, type, pos,
  9990. &isl_basic_map_dim_has_lower_bound);
  9991. }
  9992. /* Return 1 if the specified dim is involved in any upper bound.
  9993. */
  9994. isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set,
  9995. enum isl_dim_type type, unsigned pos)
  9996. {
  9997. return has_any_bound(set, type, pos,
  9998. &isl_basic_map_dim_has_upper_bound);
  9999. }
  10000. /* Does "map" have a bound (according to "fn") for all of its basic maps?
  10001. */
  10002. static isl_bool has_bound(__isl_keep isl_map *map,
  10003. enum isl_dim_type type, unsigned pos,
  10004. isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
  10005. enum isl_dim_type type, unsigned pos))
  10006. {
  10007. int i;
  10008. if (!map)
  10009. return isl_bool_error;
  10010. for (i = 0; i < map->n; ++i) {
  10011. isl_bool bounded;
  10012. bounded = fn(map->p[i], type, pos);
  10013. if (bounded < 0 || !bounded)
  10014. return bounded;
  10015. }
  10016. return isl_bool_true;
  10017. }
  10018. /* Return 1 if the specified dim has a lower bound (in each of its basic sets).
  10019. */
  10020. isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_set *set,
  10021. enum isl_dim_type type, unsigned pos)
  10022. {
  10023. return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
  10024. }
  10025. /* Return 1 if the specified dim has an upper bound (in each of its basic sets).
  10026. */
  10027. isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_set *set,
  10028. enum isl_dim_type type, unsigned pos)
  10029. {
  10030. return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
  10031. }
  10032. /* For each of the "n" variables starting at "first", determine
  10033. * the sign of the variable and put the results in the first "n"
  10034. * elements of the array "signs".
  10035. * Sign
  10036. * 1 means that the variable is non-negative
  10037. * -1 means that the variable is non-positive
  10038. * 0 means the variable attains both positive and negative values.
  10039. */
  10040. isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
  10041. unsigned first, unsigned n, int *signs)
  10042. {
  10043. isl_vec *bound = NULL;
  10044. struct isl_tab *tab = NULL;
  10045. struct isl_tab_undo *snap;
  10046. int i;
  10047. isl_size total;
  10048. total = isl_basic_set_dim(bset, isl_dim_all);
  10049. if (total < 0 || !signs)
  10050. return isl_stat_error;
  10051. bound = isl_vec_alloc(bset->ctx, 1 + total);
  10052. tab = isl_tab_from_basic_set(bset, 0);
  10053. if (!bound || !tab)
  10054. goto error;
  10055. isl_seq_clr(bound->el, bound->size);
  10056. isl_int_set_si(bound->el[0], -1);
  10057. snap = isl_tab_snap(tab);
  10058. for (i = 0; i < n; ++i) {
  10059. int empty;
  10060. isl_int_set_si(bound->el[1 + first + i], -1);
  10061. if (isl_tab_add_ineq(tab, bound->el) < 0)
  10062. goto error;
  10063. empty = tab->empty;
  10064. isl_int_set_si(bound->el[1 + first + i], 0);
  10065. if (isl_tab_rollback(tab, snap) < 0)
  10066. goto error;
  10067. if (empty) {
  10068. signs[i] = 1;
  10069. continue;
  10070. }
  10071. isl_int_set_si(bound->el[1 + first + i], 1);
  10072. if (isl_tab_add_ineq(tab, bound->el) < 0)
  10073. goto error;
  10074. empty = tab->empty;
  10075. isl_int_set_si(bound->el[1 + first + i], 0);
  10076. if (isl_tab_rollback(tab, snap) < 0)
  10077. goto error;
  10078. signs[i] = empty ? -1 : 0;
  10079. }
  10080. isl_tab_free(tab);
  10081. isl_vec_free(bound);
  10082. return isl_stat_ok;
  10083. error:
  10084. isl_tab_free(tab);
  10085. isl_vec_free(bound);
  10086. return isl_stat_error;
  10087. }
  10088. isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
  10089. enum isl_dim_type type, unsigned first, unsigned n, int *signs)
  10090. {
  10091. if (!bset || !signs)
  10092. return isl_stat_error;
  10093. if (isl_basic_set_check_range(bset, type, first, n) < 0)
  10094. return isl_stat_error;
  10095. first += pos(bset->dim, type) - 1;
  10096. return isl_basic_set_vars_get_sign(bset, first, n, signs);
  10097. }
  10098. /* Is it possible for the integer division "div" to depend (possibly
  10099. * indirectly) on any output dimensions?
  10100. *
  10101. * If the div is undefined, then we conservatively assume that it
  10102. * may depend on them.
  10103. * Otherwise, we check if it actually depends on them or on any integer
  10104. * divisions that may depend on them.
  10105. */
  10106. static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
  10107. {
  10108. int i;
  10109. isl_size n_out, n_div;
  10110. unsigned o_out, o_div;
  10111. if (isl_int_is_zero(bmap->div[div][0]))
  10112. return isl_bool_true;
  10113. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  10114. if (n_out < 0)
  10115. return isl_bool_error;
  10116. o_out = isl_basic_map_offset(bmap, isl_dim_out);
  10117. if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1)
  10118. return isl_bool_true;
  10119. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  10120. if (n_div < 0)
  10121. return isl_bool_error;
  10122. o_div = isl_basic_map_offset(bmap, isl_dim_div);
  10123. for (i = 0; i < n_div; ++i) {
  10124. isl_bool may_involve;
  10125. if (isl_int_is_zero(bmap->div[div][1 + o_div + i]))
  10126. continue;
  10127. may_involve = div_may_involve_output(bmap, i);
  10128. if (may_involve < 0 || may_involve)
  10129. return may_involve;
  10130. }
  10131. return isl_bool_false;
  10132. }
  10133. /* Return the first integer division of "bmap" in the range
  10134. * [first, first + n[ that may depend on any output dimensions and
  10135. * that has a non-zero coefficient in "c" (where the first coefficient
  10136. * in "c" corresponds to integer division "first").
  10137. */
  10138. static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
  10139. isl_int *c, int first, int n)
  10140. {
  10141. int k;
  10142. if (!bmap)
  10143. return -1;
  10144. for (k = first; k < first + n; ++k) {
  10145. isl_bool may_involve;
  10146. if (isl_int_is_zero(c[k]))
  10147. continue;
  10148. may_involve = div_may_involve_output(bmap, k);
  10149. if (may_involve < 0)
  10150. return -1;
  10151. if (may_involve)
  10152. return k;
  10153. }
  10154. return first + n;
  10155. }
  10156. /* Look for a pair of inequality constraints in "bmap" of the form
  10157. *
  10158. * -l + i >= 0 or i >= l
  10159. * and
  10160. * n + l - i >= 0 or i <= l + n
  10161. *
  10162. * with n < "m" and i the output dimension at position "pos".
  10163. * (Note that n >= 0 as otherwise the two constraints would conflict.)
  10164. * Furthermore, "l" is only allowed to involve parameters, input dimensions
  10165. * and earlier output dimensions, as well as integer divisions that do
  10166. * not involve any of the output dimensions.
  10167. *
  10168. * Return the index of the first inequality constraint or bmap->n_ineq
  10169. * if no such pair can be found.
  10170. */
  10171. static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
  10172. int pos, isl_int m)
  10173. {
  10174. int i, j;
  10175. isl_ctx *ctx;
  10176. isl_size total;
  10177. isl_size n_div, n_out;
  10178. unsigned o_div, o_out;
  10179. int less;
  10180. total = isl_basic_map_dim(bmap, isl_dim_all);
  10181. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  10182. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  10183. if (total < 0 || n_out < 0 || n_div < 0)
  10184. return -1;
  10185. ctx = isl_basic_map_get_ctx(bmap);
  10186. o_out = isl_basic_map_offset(bmap, isl_dim_out);
  10187. o_div = isl_basic_map_offset(bmap, isl_dim_div);
  10188. for (i = 0; i < bmap->n_ineq; ++i) {
  10189. if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one))
  10190. continue;
  10191. if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
  10192. n_out - (pos + 1)) != -1)
  10193. continue;
  10194. if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
  10195. 0, n_div) < n_div)
  10196. continue;
  10197. for (j = i + 1; j < bmap->n_ineq; ++j) {
  10198. if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],
  10199. ctx->one))
  10200. continue;
  10201. if (!isl_seq_is_neg(bmap->ineq[i] + 1,
  10202. bmap->ineq[j] + 1, total))
  10203. continue;
  10204. break;
  10205. }
  10206. if (j >= bmap->n_ineq)
  10207. continue;
  10208. isl_int_add(bmap->ineq[i][0],
  10209. bmap->ineq[i][0], bmap->ineq[j][0]);
  10210. less = isl_int_abs_lt(bmap->ineq[i][0], m);
  10211. isl_int_sub(bmap->ineq[i][0],
  10212. bmap->ineq[i][0], bmap->ineq[j][0]);
  10213. if (!less)
  10214. continue;
  10215. if (isl_int_is_one(bmap->ineq[i][o_out + pos]))
  10216. return i;
  10217. else
  10218. return j;
  10219. }
  10220. return bmap->n_ineq;
  10221. }
  10222. /* Return the index of the equality of "bmap" that defines
  10223. * the output dimension "pos" in terms of earlier dimensions.
  10224. * The equality may also involve integer divisions, as long
  10225. * as those integer divisions are defined in terms of
  10226. * parameters or input dimensions.
  10227. * In this case, *div is set to the number of integer divisions and
  10228. * *ineq is set to the number of inequality constraints (provided
  10229. * div and ineq are not NULL).
  10230. *
  10231. * The equality may also involve a single integer division involving
  10232. * the output dimensions (typically only output dimension "pos") as
  10233. * long as the coefficient of output dimension "pos" is 1 or -1 and
  10234. * there is a pair of constraints i >= l and i <= l + n, with i referring
  10235. * to output dimension "pos", l an expression involving only earlier
  10236. * dimensions and n smaller than the coefficient of the integer division
  10237. * in the equality. In this case, the output dimension can be defined
  10238. * in terms of a modulo expression that does not involve the integer division.
  10239. * *div is then set to this single integer division and
  10240. * *ineq is set to the index of constraint i >= l.
  10241. *
  10242. * Return bmap->n_eq if there is no such equality.
  10243. * Return -1 on error.
  10244. */
  10245. int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
  10246. int pos, int *div, int *ineq)
  10247. {
  10248. int j, k, l;
  10249. isl_size n_div, n_out;
  10250. unsigned o_div, o_out;
  10251. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  10252. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  10253. if (n_out < 0 || n_div < 0)
  10254. return -1;
  10255. o_out = isl_basic_map_offset(bmap, isl_dim_out);
  10256. o_div = isl_basic_map_offset(bmap, isl_dim_div);
  10257. if (ineq)
  10258. *ineq = bmap->n_ineq;
  10259. if (div)
  10260. *div = n_div;
  10261. for (j = 0; j < bmap->n_eq; ++j) {
  10262. if (isl_int_is_zero(bmap->eq[j][o_out + pos]))
  10263. continue;
  10264. if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1,
  10265. n_out - (pos + 1)) != -1)
  10266. continue;
  10267. k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
  10268. 0, n_div);
  10269. if (k >= n_div)
  10270. return j;
  10271. if (!isl_int_is_one(bmap->eq[j][o_out + pos]) &&
  10272. !isl_int_is_negone(bmap->eq[j][o_out + pos]))
  10273. continue;
  10274. if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
  10275. k + 1, n_div - (k+1)) < n_div)
  10276. continue;
  10277. l = find_modulo_constraint_pair(bmap, pos,
  10278. bmap->eq[j][o_div + k]);
  10279. if (l < 0)
  10280. return -1;
  10281. if (l >= bmap->n_ineq)
  10282. continue;
  10283. if (div)
  10284. *div = k;
  10285. if (ineq)
  10286. *ineq = l;
  10287. return j;
  10288. }
  10289. return bmap->n_eq;
  10290. }
  10291. /* Check if the given basic map is obviously single-valued.
  10292. * In particular, for each output dimension, check that there is
  10293. * an equality that defines the output dimension in terms of
  10294. * earlier dimensions.
  10295. */
  10296. isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
  10297. {
  10298. int i;
  10299. isl_size n_out;
  10300. n_out = isl_basic_map_dim(bmap, isl_dim_out);
  10301. if (n_out < 0)
  10302. return isl_bool_error;
  10303. for (i = 0; i < n_out; ++i) {
  10304. int eq;
  10305. eq = isl_basic_map_output_defining_equality(bmap, i,
  10306. NULL, NULL);
  10307. if (eq < 0)
  10308. return isl_bool_error;
  10309. if (eq >= bmap->n_eq)
  10310. return isl_bool_false;
  10311. }
  10312. return isl_bool_true;
  10313. }
  10314. /* Check if the given basic map is single-valued.
  10315. * We simply compute
  10316. *
  10317. * M \circ M^-1
  10318. *
  10319. * and check if the result is a subset of the identity mapping.
  10320. */
  10321. isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
  10322. {
  10323. isl_space *space;
  10324. isl_basic_map *test;
  10325. isl_basic_map *id;
  10326. isl_bool sv;
  10327. sv = isl_basic_map_plain_is_single_valued(bmap);
  10328. if (sv < 0 || sv)
  10329. return sv;
  10330. test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
  10331. test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
  10332. space = isl_basic_map_get_space(bmap);
  10333. space = isl_space_map_from_set(isl_space_range(space));
  10334. id = isl_basic_map_identity(space);
  10335. sv = isl_basic_map_is_subset(test, id);
  10336. isl_basic_map_free(test);
  10337. isl_basic_map_free(id);
  10338. return sv;
  10339. }
  10340. /* Check if the given map is obviously single-valued.
  10341. */
  10342. isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map)
  10343. {
  10344. if (!map)
  10345. return isl_bool_error;
  10346. if (map->n == 0)
  10347. return isl_bool_true;
  10348. if (map->n >= 2)
  10349. return isl_bool_false;
  10350. return isl_basic_map_plain_is_single_valued(map->p[0]);
  10351. }
  10352. /* Check if the given map is single-valued.
  10353. * We simply compute
  10354. *
  10355. * M \circ M^-1
  10356. *
  10357. * and check if the result is a subset of the identity mapping.
  10358. */
  10359. isl_bool isl_map_is_single_valued(__isl_keep isl_map *map)
  10360. {
  10361. isl_space *space;
  10362. isl_map *test;
  10363. isl_map *id;
  10364. isl_bool sv;
  10365. sv = isl_map_plain_is_single_valued(map);
  10366. if (sv < 0 || sv)
  10367. return sv;
  10368. test = isl_map_reverse(isl_map_copy(map));
  10369. test = isl_map_apply_range(test, isl_map_copy(map));
  10370. space = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
  10371. id = isl_map_identity(space);
  10372. sv = isl_map_is_subset(test, id);
  10373. isl_map_free(test);
  10374. isl_map_free(id);
  10375. return sv;
  10376. }
  10377. isl_bool isl_map_is_injective(__isl_keep isl_map *map)
  10378. {
  10379. isl_bool in;
  10380. map = isl_map_copy(map);
  10381. map = isl_map_reverse(map);
  10382. in = isl_map_is_single_valued(map);
  10383. isl_map_free(map);
  10384. return in;
  10385. }
  10386. /* Check if the given map is obviously injective.
  10387. */
  10388. isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map)
  10389. {
  10390. isl_bool in;
  10391. map = isl_map_copy(map);
  10392. map = isl_map_reverse(map);
  10393. in = isl_map_plain_is_single_valued(map);
  10394. isl_map_free(map);
  10395. return in;
  10396. }
  10397. isl_bool isl_map_is_bijective(__isl_keep isl_map *map)
  10398. {
  10399. isl_bool sv;
  10400. sv = isl_map_is_single_valued(map);
  10401. if (sv < 0 || !sv)
  10402. return sv;
  10403. return isl_map_is_injective(map);
  10404. }
  10405. isl_bool isl_set_is_singleton(__isl_keep isl_set *set)
  10406. {
  10407. return isl_map_is_single_valued(set_to_map(set));
  10408. }
  10409. /* Does "map" only map elements to themselves?
  10410. *
  10411. * If the domain and range spaces are different, then "map"
  10412. * is considered not to be an identity relation, even if it is empty.
  10413. * Otherwise, construct the maximal identity relation and
  10414. * check whether "map" is a subset of this relation.
  10415. */
  10416. isl_bool isl_map_is_identity(__isl_keep isl_map *map)
  10417. {
  10418. isl_map *id;
  10419. isl_bool equal, is_identity;
  10420. equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
  10421. if (equal < 0 || !equal)
  10422. return equal;
  10423. id = isl_map_identity(isl_map_get_space(map));
  10424. is_identity = isl_map_is_subset(map, id);
  10425. isl_map_free(id);
  10426. return is_identity;
  10427. }
  10428. int isl_map_is_translation(__isl_keep isl_map *map)
  10429. {
  10430. int ok;
  10431. isl_set *delta;
  10432. delta = isl_map_deltas(isl_map_copy(map));
  10433. ok = isl_set_is_singleton(delta);
  10434. isl_set_free(delta);
  10435. return ok;
  10436. }
  10437. static int unique(isl_int *p, unsigned pos, unsigned len)
  10438. {
  10439. if (isl_seq_first_non_zero(p, pos) != -1)
  10440. return 0;
  10441. if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
  10442. return 0;
  10443. return 1;
  10444. }
  10445. isl_bool isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
  10446. {
  10447. int i, j;
  10448. isl_size nvar, n_div;
  10449. unsigned ovar;
  10450. n_div = isl_basic_set_dim(bset, isl_dim_div);
  10451. if (n_div < 0)
  10452. return isl_bool_error;
  10453. if (n_div != 0)
  10454. return isl_bool_false;
  10455. nvar = isl_basic_set_dim(bset, isl_dim_set);
  10456. if (nvar < 0)
  10457. return isl_bool_error;
  10458. ovar = isl_space_offset(bset->dim, isl_dim_set);
  10459. for (j = 0; j < nvar; ++j) {
  10460. int lower = 0, upper = 0;
  10461. for (i = 0; i < bset->n_eq; ++i) {
  10462. if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
  10463. continue;
  10464. if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
  10465. return isl_bool_false;
  10466. break;
  10467. }
  10468. if (i < bset->n_eq)
  10469. continue;
  10470. for (i = 0; i < bset->n_ineq; ++i) {
  10471. if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
  10472. continue;
  10473. if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
  10474. return isl_bool_false;
  10475. if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
  10476. lower = 1;
  10477. else
  10478. upper = 1;
  10479. }
  10480. if (!lower || !upper)
  10481. return isl_bool_false;
  10482. }
  10483. return isl_bool_true;
  10484. }
  10485. isl_bool isl_set_is_box(__isl_keep isl_set *set)
  10486. {
  10487. if (!set)
  10488. return isl_bool_error;
  10489. if (set->n != 1)
  10490. return isl_bool_false;
  10491. return isl_basic_set_is_box(set->p[0]);
  10492. }
  10493. isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
  10494. {
  10495. if (!bset)
  10496. return isl_bool_error;
  10497. return isl_space_is_wrapping(bset->dim);
  10498. }
  10499. isl_bool isl_set_is_wrapping(__isl_keep isl_set *set)
  10500. {
  10501. if (!set)
  10502. return isl_bool_error;
  10503. return isl_space_is_wrapping(set->dim);
  10504. }
  10505. /* Modify the space of "map" through a call to "change".
  10506. * If "can_change" is set (not NULL), then first call it to check
  10507. * if the modification is allowed, printing the error message "cannot_change"
  10508. * if it is not.
  10509. */
  10510. static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
  10511. isl_bool (*can_change)(__isl_keep isl_map *map),
  10512. const char *cannot_change,
  10513. __isl_give isl_space *(*change)(__isl_take isl_space *space))
  10514. {
  10515. isl_bool ok;
  10516. isl_space *space;
  10517. if (!map)
  10518. return NULL;
  10519. ok = can_change ? can_change(map) : isl_bool_true;
  10520. if (ok < 0)
  10521. return isl_map_free(map);
  10522. if (!ok)
  10523. isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,
  10524. return isl_map_free(map));
  10525. space = change(isl_map_get_space(map));
  10526. map = isl_map_reset_space(map, space);
  10527. return map;
  10528. }
  10529. /* Is the domain of "map" a wrapped relation?
  10530. */
  10531. isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
  10532. {
  10533. if (!map)
  10534. return isl_bool_error;
  10535. return isl_space_domain_is_wrapping(map->dim);
  10536. }
  10537. /* Does "map" have a wrapped relation in both domain and range?
  10538. */
  10539. isl_bool isl_map_is_product(__isl_keep isl_map *map)
  10540. {
  10541. return isl_space_is_product(isl_map_peek_space(map));
  10542. }
  10543. /* Is the range of "map" a wrapped relation?
  10544. */
  10545. isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map)
  10546. {
  10547. if (!map)
  10548. return isl_bool_error;
  10549. return isl_space_range_is_wrapping(map->dim);
  10550. }
  10551. __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
  10552. {
  10553. isl_space *space;
  10554. space = isl_basic_map_take_space(bmap);
  10555. space = isl_space_wrap(space);
  10556. bmap = isl_basic_map_restore_space(bmap, space);
  10557. bmap = isl_basic_map_finalize(bmap);
  10558. return bset_from_bmap(bmap);
  10559. }
  10560. /* Given a map A -> B, return the set (A -> B).
  10561. */
  10562. __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
  10563. {
  10564. return isl_map_change_space(map, NULL, NULL, &isl_space_wrap);
  10565. }
  10566. __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
  10567. {
  10568. bset = isl_basic_set_cow(bset);
  10569. if (!bset)
  10570. return NULL;
  10571. bset->dim = isl_space_unwrap(bset->dim);
  10572. if (!bset->dim)
  10573. goto error;
  10574. bset = isl_basic_set_finalize(bset);
  10575. return bset_to_bmap(bset);
  10576. error:
  10577. isl_basic_set_free(bset);
  10578. return NULL;
  10579. }
  10580. /* Given a set (A -> B), return the map A -> B.
  10581. * Error out if "set" is not of the form (A -> B).
  10582. */
  10583. __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
  10584. {
  10585. return isl_map_change_space(set, &isl_set_is_wrapping,
  10586. "not a wrapping set", &isl_space_unwrap);
  10587. }
  10588. __isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
  10589. enum isl_dim_type type)
  10590. {
  10591. isl_space *space;
  10592. space = isl_basic_map_take_space(bmap);
  10593. space = isl_space_reset(space, type);
  10594. bmap = isl_basic_map_restore_space(bmap, space);
  10595. bmap = isl_basic_map_mark_final(bmap);
  10596. return bmap;
  10597. }
  10598. __isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
  10599. enum isl_dim_type type)
  10600. {
  10601. int i;
  10602. isl_space *space;
  10603. if (!map)
  10604. return NULL;
  10605. if (!isl_space_is_named_or_nested(map->dim, type))
  10606. return map;
  10607. map = isl_map_cow(map);
  10608. if (!map)
  10609. return NULL;
  10610. for (i = 0; i < map->n; ++i) {
  10611. map->p[i] = isl_basic_map_reset(map->p[i], type);
  10612. if (!map->p[i])
  10613. goto error;
  10614. }
  10615. space = isl_map_take_space(map);
  10616. space = isl_space_reset(space, type);
  10617. map = isl_map_restore_space(map, space);
  10618. return map;
  10619. error:
  10620. isl_map_free(map);
  10621. return NULL;
  10622. }
  10623. __isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
  10624. {
  10625. isl_space *space;
  10626. space = isl_basic_map_take_space(bmap);
  10627. space = isl_space_flatten(space);
  10628. bmap = isl_basic_map_restore_space(bmap, space);
  10629. bmap = isl_basic_map_mark_final(bmap);
  10630. return bmap;
  10631. }
  10632. __isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
  10633. {
  10634. return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset)));
  10635. }
  10636. __isl_give isl_basic_map *isl_basic_map_flatten_domain(
  10637. __isl_take isl_basic_map *bmap)
  10638. {
  10639. isl_space *space;
  10640. space = isl_basic_map_take_space(bmap);
  10641. space = isl_space_flatten_domain(space);
  10642. bmap = isl_basic_map_restore_space(bmap, space);
  10643. bmap = isl_basic_map_mark_final(bmap);
  10644. return bmap;
  10645. }
  10646. __isl_give isl_basic_map *isl_basic_map_flatten_range(
  10647. __isl_take isl_basic_map *bmap)
  10648. {
  10649. isl_space *space;
  10650. space = isl_basic_map_take_space(bmap);
  10651. space = isl_space_flatten_range(space);
  10652. bmap = isl_basic_map_restore_space(bmap, space);
  10653. bmap = isl_basic_map_mark_final(bmap);
  10654. return bmap;
  10655. }
  10656. /* Remove any internal structure from the spaces of domain and range of "map".
  10657. */
  10658. __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
  10659. {
  10660. if (!map)
  10661. return NULL;
  10662. if (!map->dim->nested[0] && !map->dim->nested[1])
  10663. return map;
  10664. return isl_map_change_space(map, NULL, NULL, &isl_space_flatten);
  10665. }
  10666. __isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
  10667. {
  10668. return set_from_map(isl_map_flatten(set_to_map(set)));
  10669. }
  10670. __isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
  10671. {
  10672. isl_space *space, *flat_space;
  10673. isl_map *map;
  10674. space = isl_set_get_space(set);
  10675. flat_space = isl_space_flatten(isl_space_copy(space));
  10676. map = isl_map_identity(isl_space_join(isl_space_reverse(space),
  10677. flat_space));
  10678. map = isl_map_intersect_domain(map, set);
  10679. return map;
  10680. }
  10681. /* Remove any internal structure from the space of the domain of "map".
  10682. */
  10683. __isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
  10684. {
  10685. if (!map)
  10686. return NULL;
  10687. if (!map->dim->nested[0])
  10688. return map;
  10689. return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_domain);
  10690. }
  10691. /* Remove any internal structure from the space of the range of "map".
  10692. */
  10693. __isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
  10694. {
  10695. if (!map)
  10696. return NULL;
  10697. if (!map->dim->nested[1])
  10698. return map;
  10699. return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_range);
  10700. }
  10701. /* Reorder the dimensions of "bmap" according to the given dim_map
  10702. * and set the dimension specification to "space" and
  10703. * perform Gaussian elimination on the result.
  10704. */
  10705. __isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
  10706. __isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map)
  10707. {
  10708. isl_basic_map *res;
  10709. unsigned flags;
  10710. isl_size n_div;
  10711. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  10712. if (n_div < 0 || !space || !dim_map)
  10713. goto error;
  10714. flags = bmap->flags;
  10715. ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL);
  10716. ISL_FL_CLR(flags, ISL_BASIC_MAP_SORTED);
  10717. ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS);
  10718. res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq);
  10719. res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
  10720. if (res)
  10721. res->flags = flags;
  10722. res = isl_basic_map_gauss(res, NULL);
  10723. res = isl_basic_map_finalize(res);
  10724. return res;
  10725. error:
  10726. isl_dim_map_free(dim_map);
  10727. isl_basic_map_free(bmap);
  10728. isl_space_free(space);
  10729. return NULL;
  10730. }
  10731. /* Reorder the dimensions of "map" according to given reordering.
  10732. */
  10733. __isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
  10734. __isl_take isl_reordering *r)
  10735. {
  10736. int i;
  10737. struct isl_dim_map *dim_map;
  10738. map = isl_map_cow(map);
  10739. dim_map = isl_dim_map_from_reordering(r);
  10740. if (!map || !r || !dim_map)
  10741. goto error;
  10742. for (i = 0; i < map->n; ++i) {
  10743. struct isl_dim_map *dim_map_i;
  10744. isl_space *space;
  10745. dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
  10746. space = isl_reordering_get_space(r);
  10747. map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i);
  10748. if (!map->p[i])
  10749. goto error;
  10750. }
  10751. map = isl_map_reset_space(map, isl_reordering_get_space(r));
  10752. map = isl_map_unmark_normalized(map);
  10753. isl_reordering_free(r);
  10754. isl_dim_map_free(dim_map);
  10755. return map;
  10756. error:
  10757. isl_dim_map_free(dim_map);
  10758. isl_map_free(map);
  10759. isl_reordering_free(r);
  10760. return NULL;
  10761. }
  10762. __isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
  10763. __isl_take isl_reordering *r)
  10764. {
  10765. return set_from_map(isl_map_realign(set_to_map(set), r));
  10766. }
  10767. __isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
  10768. __isl_take isl_space *model)
  10769. {
  10770. isl_ctx *ctx;
  10771. isl_bool aligned;
  10772. if (!map || !model)
  10773. goto error;
  10774. ctx = isl_space_get_ctx(model);
  10775. if (!isl_space_has_named_params(model))
  10776. isl_die(ctx, isl_error_invalid,
  10777. "model has unnamed parameters", goto error);
  10778. if (isl_map_check_named_params(map) < 0)
  10779. goto error;
  10780. aligned = isl_map_space_has_equal_params(map, model);
  10781. if (aligned < 0)
  10782. goto error;
  10783. if (!aligned) {
  10784. isl_reordering *exp;
  10785. exp = isl_parameter_alignment_reordering(map->dim, model);
  10786. exp = isl_reordering_extend_space(exp, isl_map_get_space(map));
  10787. map = isl_map_realign(map, exp);
  10788. }
  10789. isl_space_free(model);
  10790. return map;
  10791. error:
  10792. isl_space_free(model);
  10793. isl_map_free(map);
  10794. return NULL;
  10795. }
  10796. __isl_give isl_set *isl_set_align_params(__isl_take isl_set *set,
  10797. __isl_take isl_space *model)
  10798. {
  10799. return isl_map_align_params(set, model);
  10800. }
  10801. /* Align the parameters of "bmap" to those of "model", introducing
  10802. * additional parameters if needed.
  10803. */
  10804. __isl_give isl_basic_map *isl_basic_map_align_params(
  10805. __isl_take isl_basic_map *bmap, __isl_take isl_space *model)
  10806. {
  10807. isl_ctx *ctx;
  10808. isl_bool equal_params;
  10809. if (!bmap || !model)
  10810. goto error;
  10811. ctx = isl_space_get_ctx(model);
  10812. if (!isl_space_has_named_params(model))
  10813. isl_die(ctx, isl_error_invalid,
  10814. "model has unnamed parameters", goto error);
  10815. if (isl_basic_map_check_named_params(bmap) < 0)
  10816. goto error;
  10817. equal_params = isl_space_has_equal_params(bmap->dim, model);
  10818. if (equal_params < 0)
  10819. goto error;
  10820. if (!equal_params) {
  10821. isl_reordering *exp;
  10822. struct isl_dim_map *dim_map;
  10823. exp = isl_parameter_alignment_reordering(bmap->dim, model);
  10824. exp = isl_reordering_extend_space(exp,
  10825. isl_basic_map_get_space(bmap));
  10826. dim_map = isl_dim_map_from_reordering(exp);
  10827. bmap = isl_basic_map_realign(bmap,
  10828. isl_reordering_get_space(exp),
  10829. isl_dim_map_extend(dim_map, bmap));
  10830. isl_reordering_free(exp);
  10831. isl_dim_map_free(dim_map);
  10832. }
  10833. isl_space_free(model);
  10834. return bmap;
  10835. error:
  10836. isl_space_free(model);
  10837. isl_basic_map_free(bmap);
  10838. return NULL;
  10839. }
  10840. /* Do "bset" and "space" have the same parameters?
  10841. */
  10842. isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_set *bset,
  10843. __isl_keep isl_space *space)
  10844. {
  10845. isl_space *bset_space;
  10846. bset_space = isl_basic_set_peek_space(bset);
  10847. return isl_space_has_equal_params(bset_space, space);
  10848. }
  10849. /* Do "map" and "space" have the same parameters?
  10850. */
  10851. isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map,
  10852. __isl_keep isl_space *space)
  10853. {
  10854. isl_space *map_space;
  10855. map_space = isl_map_peek_space(map);
  10856. return isl_space_has_equal_params(map_space, space);
  10857. }
  10858. /* Do "set" and "space" have the same parameters?
  10859. */
  10860. isl_bool isl_set_space_has_equal_params(__isl_keep isl_set *set,
  10861. __isl_keep isl_space *space)
  10862. {
  10863. return isl_map_space_has_equal_params(set_to_map(set), space);
  10864. }
  10865. /* Align the parameters of "bset" to those of "model", introducing
  10866. * additional parameters if needed.
  10867. */
  10868. __isl_give isl_basic_set *isl_basic_set_align_params(
  10869. __isl_take isl_basic_set *bset, __isl_take isl_space *model)
  10870. {
  10871. return isl_basic_map_align_params(bset, model);
  10872. }
  10873. /* Drop all parameters not referenced by "map".
  10874. */
  10875. __isl_give isl_map *isl_map_drop_unused_params(__isl_take isl_map *map)
  10876. {
  10877. int i;
  10878. isl_size n;
  10879. n = isl_map_dim(map, isl_dim_param);
  10880. if (isl_map_check_named_params(map) < 0 || n < 0)
  10881. return isl_map_free(map);
  10882. for (i = n - 1; i >= 0; i--) {
  10883. isl_bool involves;
  10884. involves = isl_map_involves_dims(map, isl_dim_param, i, 1);
  10885. if (involves < 0)
  10886. return isl_map_free(map);
  10887. if (!involves)
  10888. map = isl_map_project_out(map, isl_dim_param, i, 1);
  10889. }
  10890. return map;
  10891. }
  10892. /* Drop all parameters not referenced by "set".
  10893. */
  10894. __isl_give isl_set *isl_set_drop_unused_params(
  10895. __isl_take isl_set *set)
  10896. {
  10897. return set_from_map(isl_map_drop_unused_params(set_to_map(set)));
  10898. }
  10899. /* Drop all parameters not referenced by "bmap".
  10900. */
  10901. __isl_give isl_basic_map *isl_basic_map_drop_unused_params(
  10902. __isl_take isl_basic_map *bmap)
  10903. {
  10904. isl_size nparam;
  10905. int i;
  10906. nparam = isl_basic_map_dim(bmap, isl_dim_param);
  10907. if (nparam < 0 || isl_basic_map_check_named_params(bmap) < 0)
  10908. return isl_basic_map_free(bmap);
  10909. for (i = nparam - 1; i >= 0; i--) {
  10910. isl_bool involves;
  10911. involves = isl_basic_map_involves_dims(bmap,
  10912. isl_dim_param, i, 1);
  10913. if (involves < 0)
  10914. return isl_basic_map_free(bmap);
  10915. if (!involves)
  10916. bmap = isl_basic_map_drop(bmap, isl_dim_param, i, 1);
  10917. }
  10918. return bmap;
  10919. }
  10920. /* Drop all parameters not referenced by "bset".
  10921. */
  10922. __isl_give isl_basic_set *isl_basic_set_drop_unused_params(
  10923. __isl_take isl_basic_set *bset)
  10924. {
  10925. return bset_from_bmap(isl_basic_map_drop_unused_params(
  10926. bset_to_bmap(bset)));
  10927. }
  10928. /* Given a tuple of identifiers "tuple" in a space that corresponds
  10929. * to that of "set", if any of those identifiers appear as parameters
  10930. * in "set", then equate those parameters with the corresponding
  10931. * set dimensions and project out the parameters.
  10932. * The result therefore has no such parameters.
  10933. */
  10934. static __isl_give isl_set *equate_params(__isl_take isl_set *set,
  10935. __isl_keep isl_multi_id *tuple)
  10936. {
  10937. int i;
  10938. isl_size n;
  10939. isl_space *set_space, *tuple_space;
  10940. set_space = isl_set_peek_space(set);
  10941. tuple_space = isl_multi_id_peek_space(tuple);
  10942. if (isl_space_check_equal_tuples(tuple_space, set_space) < 0)
  10943. return isl_set_free(set);
  10944. n = isl_multi_id_size(tuple);
  10945. if (n < 0)
  10946. return isl_set_free(set);
  10947. for (i = 0; i < n; ++i) {
  10948. isl_id *id;
  10949. int pos;
  10950. id = isl_multi_id_get_at(tuple, i);
  10951. if (!id)
  10952. return isl_set_free(set);
  10953. pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
  10954. isl_id_free(id);
  10955. if (pos < 0)
  10956. continue;
  10957. set = isl_set_equate(set, isl_dim_param, pos, isl_dim_set, i);
  10958. set = isl_set_project_out(set, isl_dim_param, pos, 1);
  10959. }
  10960. return set;
  10961. }
  10962. /* Bind the set dimensions of "set" to parameters with identifiers
  10963. * specified by "tuple", living in the same space as "set".
  10964. *
  10965. * If no parameters with these identifiers appear in "set" already,
  10966. * then the set dimensions are simply reinterpreted as parameters.
  10967. * Otherwise, the parameters are first equated to the corresponding
  10968. * set dimensions.
  10969. */
  10970. __isl_give isl_set *isl_set_bind(__isl_take isl_set *set,
  10971. __isl_take isl_multi_id *tuple)
  10972. {
  10973. isl_space *space;
  10974. set = equate_params(set, tuple);
  10975. space = isl_set_get_space(set);
  10976. space = isl_space_bind_set(space, tuple);
  10977. isl_multi_id_free(tuple);
  10978. set = isl_set_reset_space(set, space);
  10979. return set;
  10980. }
  10981. /* Given a tuple of identifiers "tuple" in a space that corresponds
  10982. * to the domain of "map", if any of those identifiers appear as parameters
  10983. * in "map", then equate those parameters with the corresponding
  10984. * input dimensions and project out the parameters.
  10985. * The result therefore has no such parameters.
  10986. */
  10987. static __isl_give isl_map *map_equate_params(__isl_take isl_map *map,
  10988. __isl_keep isl_multi_id *tuple)
  10989. {
  10990. int i;
  10991. isl_size n;
  10992. isl_space *map_space, *tuple_space;
  10993. map_space = isl_map_peek_space(map);
  10994. tuple_space = isl_multi_id_peek_space(tuple);
  10995. if (isl_space_check_domain_tuples(tuple_space, map_space) < 0)
  10996. return isl_map_free(map);
  10997. n = isl_multi_id_size(tuple);
  10998. if (n < 0)
  10999. return isl_map_free(map);
  11000. for (i = 0; i < n; ++i) {
  11001. isl_id *id;
  11002. int pos;
  11003. id = isl_multi_id_get_at(tuple, i);
  11004. if (!id)
  11005. return isl_map_free(map);
  11006. pos = isl_map_find_dim_by_id(map, isl_dim_param, id);
  11007. isl_id_free(id);
  11008. if (pos < 0)
  11009. continue;
  11010. map = isl_map_equate(map, isl_dim_param, pos, isl_dim_in, i);
  11011. map = isl_map_project_out(map, isl_dim_param, pos, 1);
  11012. }
  11013. return map;
  11014. }
  11015. /* Bind the input dimensions of "map" to parameters with identifiers
  11016. * specified by "tuple", living in the domain space of "map".
  11017. *
  11018. * If no parameters with these identifiers appear in "map" already,
  11019. * then the input dimensions are simply reinterpreted as parameters.
  11020. * Otherwise, the parameters are first equated to the corresponding
  11021. * input dimensions.
  11022. */
  11023. __isl_give isl_set *isl_map_bind_domain(__isl_take isl_map *map,
  11024. __isl_take isl_multi_id *tuple)
  11025. {
  11026. isl_space *space;
  11027. isl_set *set;
  11028. map = map_equate_params(map, tuple);
  11029. space = isl_map_get_space(map);
  11030. space = isl_space_bind_map_domain(space, tuple);
  11031. isl_multi_id_free(tuple);
  11032. set = set_from_map(isl_map_reset_space(map, space));
  11033. return set;
  11034. }
  11035. /* Bind the output dimensions of "map" to parameters with identifiers
  11036. * specified by "tuple", living in the range space of "map".
  11037. *
  11038. * Since binding is more easily implemented on the domain,
  11039. * bind the input dimensions of the inverse of "map".
  11040. */
  11041. __isl_give isl_set *isl_map_bind_range(__isl_take isl_map *map,
  11042. __isl_take isl_multi_id *tuple)
  11043. {
  11044. return isl_map_bind_domain(isl_map_reverse(map), tuple);
  11045. }
  11046. /* Insert a domain corresponding to "tuple"
  11047. * into the nullary or unary relation "set".
  11048. * The result has an extra initial tuple and is therefore
  11049. * either a unary or binary relation.
  11050. * Any parameters with identifiers in "tuple" are reinterpreted
  11051. * as the corresponding domain dimensions.
  11052. */
  11053. static __isl_give isl_map *unbind_params_insert_domain(
  11054. __isl_take isl_set *set, __isl_take isl_multi_id *tuple)
  11055. {
  11056. isl_space *space;
  11057. isl_reordering *r;
  11058. space = isl_set_peek_space(set);
  11059. r = isl_reordering_unbind_params_insert_domain(space, tuple);
  11060. isl_multi_id_free(tuple);
  11061. return isl_map_realign(set_to_map(set), r);
  11062. }
  11063. /* Construct a set with "tuple" as domain from the parameter domain "set".
  11064. * Any parameters with identifiers in "tuple" are reinterpreted
  11065. * as the corresponding set dimensions.
  11066. */
  11067. __isl_give isl_set *isl_set_unbind_params(__isl_take isl_set *set,
  11068. __isl_take isl_multi_id *tuple)
  11069. {
  11070. isl_bool is_params;
  11071. is_params = isl_set_is_params(set);
  11072. if (is_params < 0)
  11073. set = isl_set_free(set);
  11074. else if (!is_params)
  11075. isl_die(isl_set_get_ctx(set), isl_error_invalid,
  11076. "expecting parameter domain", set = isl_set_free(set));
  11077. return set_from_map(unbind_params_insert_domain(set, tuple));
  11078. }
  11079. /* Check that "set" is a proper set, i.e., that it is not a parameter domain.
  11080. */
  11081. static isl_stat isl_set_check_is_set(__isl_keep isl_set *set)
  11082. {
  11083. isl_bool is_params;
  11084. is_params = isl_set_is_params(set);
  11085. if (is_params < 0)
  11086. return isl_stat_error;
  11087. else if (is_params)
  11088. isl_die(isl_set_get_ctx(set), isl_error_invalid,
  11089. "expecting proper set", return isl_stat_error);
  11090. return isl_stat_ok;
  11091. }
  11092. /* Construct a map with "domain" as domain and "set" as range.
  11093. * Any parameters with identifiers in "domain" are reinterpreted
  11094. * as the corresponding domain dimensions.
  11095. */
  11096. __isl_give isl_map *isl_set_unbind_params_insert_domain(
  11097. __isl_take isl_set *set, __isl_take isl_multi_id *domain)
  11098. {
  11099. if (isl_set_check_is_set(set) < 0)
  11100. set = isl_set_free(set);
  11101. return unbind_params_insert_domain(set, domain);
  11102. }
  11103. /* Construct a map with "domain" as domain and "set" as range.
  11104. */
  11105. __isl_give isl_map *isl_set_insert_domain(__isl_take isl_set *set,
  11106. __isl_take isl_space *domain)
  11107. {
  11108. isl_size dim;
  11109. isl_space *space;
  11110. isl_map *map;
  11111. if (isl_set_check_is_set(set) < 0 || isl_space_check_is_set(domain) < 0)
  11112. domain = isl_space_free(domain);
  11113. dim = isl_space_dim(domain, isl_dim_set);
  11114. if (dim < 0)
  11115. domain = isl_space_free(domain);
  11116. space = isl_set_get_space(set);
  11117. domain = isl_space_replace_params(domain, space);
  11118. space = isl_space_map_from_domain_and_range(domain, space);
  11119. map = isl_map_from_range(set);
  11120. map = isl_map_add_dims(map, isl_dim_in, dim);
  11121. map = isl_map_reset_space(map, space);
  11122. return map;
  11123. }
  11124. __isl_give isl_mat *isl_basic_map_equalities_matrix(
  11125. __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
  11126. enum isl_dim_type c2, enum isl_dim_type c3,
  11127. enum isl_dim_type c4, enum isl_dim_type c5)
  11128. {
  11129. enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
  11130. struct isl_mat *mat;
  11131. int i, j, k;
  11132. int pos;
  11133. isl_size total;
  11134. total = isl_basic_map_dim(bmap, isl_dim_all);
  11135. if (total < 0)
  11136. return NULL;
  11137. mat = isl_mat_alloc(bmap->ctx, bmap->n_eq, total + 1);
  11138. if (!mat)
  11139. return NULL;
  11140. for (i = 0; i < bmap->n_eq; ++i)
  11141. for (j = 0, pos = 0; j < 5; ++j) {
  11142. int off = isl_basic_map_offset(bmap, c[j]);
  11143. isl_size dim = isl_basic_map_dim(bmap, c[j]);
  11144. if (dim < 0)
  11145. return isl_mat_free(mat);
  11146. for (k = 0; k < dim; ++k) {
  11147. isl_int_set(mat->row[i][pos],
  11148. bmap->eq[i][off + k]);
  11149. ++pos;
  11150. }
  11151. }
  11152. return mat;
  11153. }
  11154. __isl_give isl_mat *isl_basic_map_inequalities_matrix(
  11155. __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
  11156. enum isl_dim_type c2, enum isl_dim_type c3,
  11157. enum isl_dim_type c4, enum isl_dim_type c5)
  11158. {
  11159. enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
  11160. struct isl_mat *mat;
  11161. int i, j, k;
  11162. int pos;
  11163. isl_size total;
  11164. total = isl_basic_map_dim(bmap, isl_dim_all);
  11165. if (total < 0)
  11166. return NULL;
  11167. mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq, total + 1);
  11168. if (!mat)
  11169. return NULL;
  11170. for (i = 0; i < bmap->n_ineq; ++i)
  11171. for (j = 0, pos = 0; j < 5; ++j) {
  11172. int off = isl_basic_map_offset(bmap, c[j]);
  11173. isl_size dim = isl_basic_map_dim(bmap, c[j]);
  11174. if (dim < 0)
  11175. return isl_mat_free(mat);
  11176. for (k = 0; k < dim; ++k) {
  11177. isl_int_set(mat->row[i][pos],
  11178. bmap->ineq[i][off + k]);
  11179. ++pos;
  11180. }
  11181. }
  11182. return mat;
  11183. }
  11184. __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
  11185. __isl_take isl_space *space,
  11186. __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
  11187. enum isl_dim_type c2, enum isl_dim_type c3,
  11188. enum isl_dim_type c4, enum isl_dim_type c5)
  11189. {
  11190. enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
  11191. isl_basic_map *bmap = NULL;
  11192. isl_size dim;
  11193. unsigned total;
  11194. unsigned extra;
  11195. int i, j, k, l;
  11196. int pos;
  11197. dim = isl_space_dim(space, isl_dim_all);
  11198. if (dim < 0 || !eq || !ineq)
  11199. goto error;
  11200. if (eq->n_col != ineq->n_col)
  11201. isl_die(space->ctx, isl_error_invalid,
  11202. "equalities and inequalities matrices should have "
  11203. "same number of columns", goto error);
  11204. total = 1 + dim;
  11205. if (eq->n_col < total)
  11206. isl_die(space->ctx, isl_error_invalid,
  11207. "number of columns too small", goto error);
  11208. extra = eq->n_col - total;
  11209. bmap = isl_basic_map_alloc_space(isl_space_copy(space), extra,
  11210. eq->n_row, ineq->n_row);
  11211. if (!bmap)
  11212. goto error;
  11213. for (i = 0; i < extra; ++i) {
  11214. k = isl_basic_map_alloc_div(bmap);
  11215. if (k < 0)
  11216. goto error;
  11217. isl_int_set_si(bmap->div[k][0], 0);
  11218. }
  11219. for (i = 0; i < eq->n_row; ++i) {
  11220. l = isl_basic_map_alloc_equality(bmap);
  11221. if (l < 0)
  11222. goto error;
  11223. for (j = 0, pos = 0; j < 5; ++j) {
  11224. int off = isl_basic_map_offset(bmap, c[j]);
  11225. isl_size dim = isl_basic_map_dim(bmap, c[j]);
  11226. if (dim < 0)
  11227. goto error;
  11228. for (k = 0; k < dim; ++k) {
  11229. isl_int_set(bmap->eq[l][off + k],
  11230. eq->row[i][pos]);
  11231. ++pos;
  11232. }
  11233. }
  11234. }
  11235. for (i = 0; i < ineq->n_row; ++i) {
  11236. l = isl_basic_map_alloc_inequality(bmap);
  11237. if (l < 0)
  11238. goto error;
  11239. for (j = 0, pos = 0; j < 5; ++j) {
  11240. int off = isl_basic_map_offset(bmap, c[j]);
  11241. isl_size dim = isl_basic_map_dim(bmap, c[j]);
  11242. if (dim < 0)
  11243. goto error;
  11244. for (k = 0; k < dim; ++k) {
  11245. isl_int_set(bmap->ineq[l][off + k],
  11246. ineq->row[i][pos]);
  11247. ++pos;
  11248. }
  11249. }
  11250. }
  11251. isl_space_free(space);
  11252. isl_mat_free(eq);
  11253. isl_mat_free(ineq);
  11254. bmap = isl_basic_map_simplify(bmap);
  11255. return isl_basic_map_finalize(bmap);
  11256. error:
  11257. isl_space_free(space);
  11258. isl_mat_free(eq);
  11259. isl_mat_free(ineq);
  11260. isl_basic_map_free(bmap);
  11261. return NULL;
  11262. }
  11263. __isl_give isl_mat *isl_basic_set_equalities_matrix(
  11264. __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
  11265. enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
  11266. {
  11267. return isl_basic_map_equalities_matrix(bset_to_bmap(bset),
  11268. c1, c2, c3, c4, isl_dim_in);
  11269. }
  11270. __isl_give isl_mat *isl_basic_set_inequalities_matrix(
  11271. __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
  11272. enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
  11273. {
  11274. return isl_basic_map_inequalities_matrix(bset_to_bmap(bset),
  11275. c1, c2, c3, c4, isl_dim_in);
  11276. }
  11277. __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
  11278. __isl_take isl_space *space,
  11279. __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
  11280. enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
  11281. {
  11282. isl_basic_map *bmap;
  11283. bmap = isl_basic_map_from_constraint_matrices(space, eq, ineq,
  11284. c1, c2, c3, c4, isl_dim_in);
  11285. return bset_from_bmap(bmap);
  11286. }
  11287. isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
  11288. {
  11289. if (!bmap)
  11290. return isl_bool_error;
  11291. return isl_space_can_zip(bmap->dim);
  11292. }
  11293. isl_bool isl_map_can_zip(__isl_keep isl_map *map)
  11294. {
  11295. if (!map)
  11296. return isl_bool_error;
  11297. return isl_space_can_zip(map->dim);
  11298. }
  11299. /* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
  11300. * (A -> C) -> (B -> D).
  11301. */
  11302. __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
  11303. {
  11304. unsigned pos;
  11305. isl_size n_in;
  11306. isl_size n1;
  11307. isl_size n2;
  11308. if (!bmap)
  11309. return NULL;
  11310. if (!isl_basic_map_can_zip(bmap))
  11311. isl_die(bmap->ctx, isl_error_invalid,
  11312. "basic map cannot be zipped", goto error);
  11313. n_in = isl_space_dim(bmap->dim->nested[0], isl_dim_in);
  11314. n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
  11315. n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
  11316. if (n_in < 0 || n1 < 0 || n2 < 0)
  11317. return isl_basic_map_free(bmap);
  11318. pos = isl_basic_map_offset(bmap, isl_dim_in) + n_in;
  11319. bmap = isl_basic_map_cow(bmap);
  11320. bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
  11321. if (!bmap)
  11322. return NULL;
  11323. bmap->dim = isl_space_zip(bmap->dim);
  11324. if (!bmap->dim)
  11325. goto error;
  11326. bmap = isl_basic_map_mark_final(bmap);
  11327. return bmap;
  11328. error:
  11329. isl_basic_map_free(bmap);
  11330. return NULL;
  11331. }
  11332. /* Given a map (A -> B) -> (C -> D), return the corresponding map
  11333. * (A -> C) -> (B -> D).
  11334. */
  11335. __isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
  11336. {
  11337. if (!map)
  11338. return NULL;
  11339. if (!isl_map_can_zip(map))
  11340. isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",
  11341. goto error);
  11342. return isl_map_transform(map, &isl_space_zip, &isl_basic_map_zip);
  11343. error:
  11344. isl_map_free(map);
  11345. return NULL;
  11346. }
  11347. /* Can we apply isl_basic_map_curry to "bmap"?
  11348. * That is, does it have a nested relation in its domain?
  11349. */
  11350. isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
  11351. {
  11352. if (!bmap)
  11353. return isl_bool_error;
  11354. return isl_space_can_curry(bmap->dim);
  11355. }
  11356. /* Can we apply isl_map_curry to "map"?
  11357. * That is, does it have a nested relation in its domain?
  11358. */
  11359. isl_bool isl_map_can_curry(__isl_keep isl_map *map)
  11360. {
  11361. if (!map)
  11362. return isl_bool_error;
  11363. return isl_space_can_curry(map->dim);
  11364. }
  11365. /* Given a basic map (A -> B) -> C, return the corresponding basic map
  11366. * A -> (B -> C).
  11367. */
  11368. __isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
  11369. {
  11370. if (!bmap)
  11371. return NULL;
  11372. if (!isl_basic_map_can_curry(bmap))
  11373. isl_die(bmap->ctx, isl_error_invalid,
  11374. "basic map cannot be curried", goto error);
  11375. bmap = isl_basic_map_cow(bmap);
  11376. if (!bmap)
  11377. return NULL;
  11378. bmap->dim = isl_space_curry(bmap->dim);
  11379. if (!bmap->dim)
  11380. goto error;
  11381. bmap = isl_basic_map_mark_final(bmap);
  11382. return bmap;
  11383. error:
  11384. isl_basic_map_free(bmap);
  11385. return NULL;
  11386. }
  11387. /* Given a map (A -> B) -> C, return the corresponding map
  11388. * A -> (B -> C).
  11389. */
  11390. __isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
  11391. {
  11392. return isl_map_change_space(map, &isl_map_can_curry,
  11393. "map cannot be curried", &isl_space_curry);
  11394. }
  11395. /* Can isl_map_range_curry be applied to "map"?
  11396. * That is, does it have a nested relation in its range,
  11397. * the domain of which is itself a nested relation?
  11398. */
  11399. isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
  11400. {
  11401. if (!map)
  11402. return isl_bool_error;
  11403. return isl_space_can_range_curry(map->dim);
  11404. }
  11405. /* Given a map A -> ((B -> C) -> D), return the corresponding map
  11406. * A -> (B -> (C -> D)).
  11407. */
  11408. __isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
  11409. {
  11410. return isl_map_change_space(map, &isl_map_can_range_curry,
  11411. "map range cannot be curried",
  11412. &isl_space_range_curry);
  11413. }
  11414. /* Can we apply isl_basic_map_uncurry to "bmap"?
  11415. * That is, does it have a nested relation in its domain?
  11416. */
  11417. isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
  11418. {
  11419. if (!bmap)
  11420. return isl_bool_error;
  11421. return isl_space_can_uncurry(bmap->dim);
  11422. }
  11423. /* Can we apply isl_map_uncurry to "map"?
  11424. * That is, does it have a nested relation in its domain?
  11425. */
  11426. isl_bool isl_map_can_uncurry(__isl_keep isl_map *map)
  11427. {
  11428. if (!map)
  11429. return isl_bool_error;
  11430. return isl_space_can_uncurry(map->dim);
  11431. }
  11432. /* Given a basic map A -> (B -> C), return the corresponding basic map
  11433. * (A -> B) -> C.
  11434. */
  11435. __isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
  11436. {
  11437. if (!bmap)
  11438. return NULL;
  11439. if (!isl_basic_map_can_uncurry(bmap))
  11440. isl_die(bmap->ctx, isl_error_invalid,
  11441. "basic map cannot be uncurried",
  11442. return isl_basic_map_free(bmap));
  11443. bmap = isl_basic_map_cow(bmap);
  11444. if (!bmap)
  11445. return NULL;
  11446. bmap->dim = isl_space_uncurry(bmap->dim);
  11447. if (!bmap->dim)
  11448. return isl_basic_map_free(bmap);
  11449. bmap = isl_basic_map_mark_final(bmap);
  11450. return bmap;
  11451. }
  11452. /* Given a map A -> (B -> C), return the corresponding map
  11453. * (A -> B) -> C.
  11454. */
  11455. __isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
  11456. {
  11457. return isl_map_change_space(map, &isl_map_can_uncurry,
  11458. "map cannot be uncurried", &isl_space_uncurry);
  11459. }
  11460. __isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
  11461. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11462. {
  11463. return isl_map_equate(set, type1, pos1, type2, pos2);
  11464. }
  11465. /* Construct a basic map where the given dimensions are equal to each other.
  11466. */
  11467. static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
  11468. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11469. {
  11470. isl_basic_map *bmap = NULL;
  11471. int i;
  11472. isl_size total;
  11473. total = isl_space_dim(space, isl_dim_all);
  11474. if (total < 0 ||
  11475. isl_space_check_range(space, type1, pos1, 1) < 0 ||
  11476. isl_space_check_range(space, type2, pos2, 1) < 0)
  11477. goto error;
  11478. if (type1 == type2 && pos1 == pos2)
  11479. return isl_basic_map_universe(space);
  11480. bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
  11481. i = isl_basic_map_alloc_equality(bmap);
  11482. if (i < 0)
  11483. goto error;
  11484. isl_seq_clr(bmap->eq[i], 1 + total);
  11485. pos1 += isl_basic_map_offset(bmap, type1);
  11486. pos2 += isl_basic_map_offset(bmap, type2);
  11487. isl_int_set_si(bmap->eq[i][pos1], -1);
  11488. isl_int_set_si(bmap->eq[i][pos2], 1);
  11489. bmap = isl_basic_map_finalize(bmap);
  11490. isl_space_free(space);
  11491. return bmap;
  11492. error:
  11493. isl_space_free(space);
  11494. isl_basic_map_free(bmap);
  11495. return NULL;
  11496. }
  11497. /* Add a constraint imposing that the given two dimensions are equal.
  11498. */
  11499. __isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
  11500. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11501. {
  11502. isl_basic_map *eq;
  11503. eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
  11504. bmap = isl_basic_map_intersect(bmap, eq);
  11505. return bmap;
  11506. }
  11507. /* Add a constraint imposing that the given two dimensions are equal.
  11508. */
  11509. __isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
  11510. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11511. {
  11512. isl_basic_map *bmap;
  11513. bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
  11514. map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
  11515. return map;
  11516. }
  11517. /* Add a constraint imposing that the given two dimensions have opposite values.
  11518. */
  11519. __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
  11520. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11521. {
  11522. isl_basic_map *bmap = NULL;
  11523. int i;
  11524. isl_size total;
  11525. if (isl_map_check_range(map, type1, pos1, 1) < 0)
  11526. return isl_map_free(map);
  11527. if (isl_map_check_range(map, type2, pos2, 1) < 0)
  11528. return isl_map_free(map);
  11529. total = isl_map_dim(map, isl_dim_all);
  11530. if (total < 0)
  11531. return isl_map_free(map);
  11532. bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
  11533. i = isl_basic_map_alloc_equality(bmap);
  11534. if (i < 0)
  11535. goto error;
  11536. isl_seq_clr(bmap->eq[i], 1 + total);
  11537. pos1 += isl_basic_map_offset(bmap, type1);
  11538. pos2 += isl_basic_map_offset(bmap, type2);
  11539. isl_int_set_si(bmap->eq[i][pos1], 1);
  11540. isl_int_set_si(bmap->eq[i][pos2], 1);
  11541. bmap = isl_basic_map_finalize(bmap);
  11542. map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
  11543. return map;
  11544. error:
  11545. isl_basic_map_free(bmap);
  11546. isl_map_free(map);
  11547. return NULL;
  11548. }
  11549. /* Construct a constraint imposing that the value of the first dimension is
  11550. * greater than or equal to that of the second.
  11551. */
  11552. static __isl_give isl_constraint *constraint_order_ge(
  11553. __isl_take isl_space *space, enum isl_dim_type type1, int pos1,
  11554. enum isl_dim_type type2, int pos2)
  11555. {
  11556. isl_constraint *c;
  11557. if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
  11558. isl_space_check_range(space, type2, pos2, 1) < 0)
  11559. space = isl_space_free(space);
  11560. if (!space)
  11561. return NULL;
  11562. c = isl_constraint_alloc_inequality(isl_local_space_from_space(space));
  11563. if (type1 == type2 && pos1 == pos2)
  11564. return c;
  11565. c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
  11566. c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
  11567. return c;
  11568. }
  11569. /* Add a constraint imposing that the value of the first dimension is
  11570. * greater than or equal to that of the second.
  11571. */
  11572. __isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
  11573. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11574. {
  11575. isl_constraint *c;
  11576. isl_space *space;
  11577. if (type1 == type2 && pos1 == pos2)
  11578. return bmap;
  11579. space = isl_basic_map_get_space(bmap);
  11580. c = constraint_order_ge(space, type1, pos1, type2, pos2);
  11581. bmap = isl_basic_map_add_constraint(bmap, c);
  11582. return bmap;
  11583. }
  11584. /* Add a constraint imposing that the value of the first dimension is
  11585. * greater than or equal to that of the second.
  11586. */
  11587. __isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map,
  11588. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11589. {
  11590. isl_constraint *c;
  11591. isl_space *space;
  11592. if (type1 == type2 && pos1 == pos2)
  11593. return map;
  11594. space = isl_map_get_space(map);
  11595. c = constraint_order_ge(space, type1, pos1, type2, pos2);
  11596. map = isl_map_add_constraint(map, c);
  11597. return map;
  11598. }
  11599. /* Add a constraint imposing that the value of the first dimension is
  11600. * less than or equal to that of the second.
  11601. */
  11602. __isl_give isl_map *isl_map_order_le(__isl_take isl_map *map,
  11603. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11604. {
  11605. return isl_map_order_ge(map, type2, pos2, type1, pos1);
  11606. }
  11607. /* Construct a basic map where the value of the first dimension is
  11608. * greater than that of the second.
  11609. */
  11610. static __isl_give isl_basic_map *greator(__isl_take isl_space *space,
  11611. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11612. {
  11613. isl_basic_map *bmap = NULL;
  11614. int i;
  11615. isl_size total;
  11616. if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
  11617. isl_space_check_range(space, type2, pos2, 1) < 0)
  11618. goto error;
  11619. if (type1 == type2 && pos1 == pos2)
  11620. return isl_basic_map_empty(space);
  11621. bmap = isl_basic_map_alloc_space(space, 0, 0, 1);
  11622. total = isl_basic_map_dim(bmap, isl_dim_all);
  11623. i = isl_basic_map_alloc_inequality(bmap);
  11624. if (total < 0 || i < 0)
  11625. return isl_basic_map_free(bmap);
  11626. isl_seq_clr(bmap->ineq[i], 1 + total);
  11627. pos1 += isl_basic_map_offset(bmap, type1);
  11628. pos2 += isl_basic_map_offset(bmap, type2);
  11629. isl_int_set_si(bmap->ineq[i][pos1], 1);
  11630. isl_int_set_si(bmap->ineq[i][pos2], -1);
  11631. isl_int_set_si(bmap->ineq[i][0], -1);
  11632. bmap = isl_basic_map_finalize(bmap);
  11633. return bmap;
  11634. error:
  11635. isl_space_free(space);
  11636. isl_basic_map_free(bmap);
  11637. return NULL;
  11638. }
  11639. /* Add a constraint imposing that the value of the first dimension is
  11640. * greater than that of the second.
  11641. */
  11642. __isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap,
  11643. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11644. {
  11645. isl_basic_map *gt;
  11646. gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
  11647. bmap = isl_basic_map_intersect(bmap, gt);
  11648. return bmap;
  11649. }
  11650. /* Add a constraint imposing that the value of the first dimension is
  11651. * greater than that of the second.
  11652. */
  11653. __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
  11654. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11655. {
  11656. isl_basic_map *bmap;
  11657. bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2);
  11658. map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
  11659. return map;
  11660. }
  11661. /* Add a constraint imposing that the value of the first dimension is
  11662. * smaller than that of the second.
  11663. */
  11664. __isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
  11665. enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
  11666. {
  11667. return isl_map_order_gt(map, type2, pos2, type1, pos1);
  11668. }
  11669. __isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
  11670. int pos)
  11671. {
  11672. isl_aff *div;
  11673. isl_local_space *ls;
  11674. if (!bmap)
  11675. return NULL;
  11676. if (!isl_basic_map_divs_known(bmap))
  11677. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  11678. "some divs are unknown", return NULL);
  11679. ls = isl_basic_map_get_local_space(bmap);
  11680. div = isl_local_space_get_div(ls, pos);
  11681. isl_local_space_free(ls);
  11682. return div;
  11683. }
  11684. __isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
  11685. int pos)
  11686. {
  11687. return isl_basic_map_get_div(bset, pos);
  11688. }
  11689. /* Plug in "subs" for set dimension "pos" of "set".
  11690. */
  11691. __isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
  11692. unsigned pos, __isl_keep isl_aff *subs)
  11693. {
  11694. isl_multi_aff *ma;
  11695. if (set && isl_set_plain_is_empty(set))
  11696. return set;
  11697. ma = isl_multi_aff_identity_on_domain_space(isl_set_get_space(set));
  11698. ma = isl_multi_aff_set_aff(ma, pos, isl_aff_copy(subs));
  11699. return isl_set_preimage_multi_aff(set, ma);
  11700. }
  11701. /* Check if the range of "ma" is compatible with the domain or range
  11702. * (depending on "type") of "bmap".
  11703. */
  11704. static isl_stat check_basic_map_compatible_range_multi_aff(
  11705. __isl_keep isl_basic_map *bmap, enum isl_dim_type type,
  11706. __isl_keep isl_multi_aff *ma)
  11707. {
  11708. isl_bool m;
  11709. isl_space *ma_space;
  11710. ma_space = isl_multi_aff_get_space(ma);
  11711. m = isl_space_has_equal_params(bmap->dim, ma_space);
  11712. if (m < 0)
  11713. goto error;
  11714. if (!m)
  11715. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  11716. "parameters don't match", goto error);
  11717. m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out);
  11718. if (m < 0)
  11719. goto error;
  11720. if (!m)
  11721. isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
  11722. "spaces don't match", goto error);
  11723. isl_space_free(ma_space);
  11724. return isl_stat_ok;
  11725. error:
  11726. isl_space_free(ma_space);
  11727. return isl_stat_error;
  11728. }
  11729. /* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
  11730. * coefficients before the transformed range of dimensions,
  11731. * the "n_after" coefficients after the transformed range of dimensions
  11732. * and the coefficients of the other divs in "bmap".
  11733. */
  11734. static __isl_give isl_basic_map *set_ma_divs(__isl_take isl_basic_map *bmap,
  11735. __isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div)
  11736. {
  11737. int i;
  11738. isl_size n_param;
  11739. isl_size n_set;
  11740. isl_local_space *ls;
  11741. if (n_div == 0)
  11742. return bmap;
  11743. ls = isl_aff_get_domain_local_space(ma->u.p[0]);
  11744. n_param = isl_local_space_dim(ls, isl_dim_param);
  11745. n_set = isl_local_space_dim(ls, isl_dim_set);
  11746. if (n_param < 0 || n_set < 0)
  11747. return isl_basic_map_free(bmap);
  11748. for (i = 0; i < n_div; ++i) {
  11749. int o_bmap = 0, o_ls = 0;
  11750. isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param);
  11751. o_bmap += 1 + 1 + n_param;
  11752. o_ls += 1 + 1 + n_param;
  11753. isl_seq_clr(bmap->div[i] + o_bmap, n_before);
  11754. o_bmap += n_before;
  11755. isl_seq_cpy(bmap->div[i] + o_bmap,
  11756. ls->div->row[i] + o_ls, n_set);
  11757. o_bmap += n_set;
  11758. o_ls += n_set;
  11759. isl_seq_clr(bmap->div[i] + o_bmap, n_after);
  11760. o_bmap += n_after;
  11761. isl_seq_cpy(bmap->div[i] + o_bmap,
  11762. ls->div->row[i] + o_ls, n_div);
  11763. o_bmap += n_div;
  11764. o_ls += n_div;
  11765. isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div);
  11766. bmap = isl_basic_map_add_div_constraints(bmap, i);
  11767. if (!bmap)
  11768. goto error;
  11769. }
  11770. isl_local_space_free(ls);
  11771. return bmap;
  11772. error:
  11773. isl_local_space_free(ls);
  11774. return isl_basic_map_free(bmap);
  11775. }
  11776. /* How many stride constraints does "ma" enforce?
  11777. * That is, how many of the affine expressions have a denominator
  11778. * different from one?
  11779. */
  11780. static int multi_aff_strides(__isl_keep isl_multi_aff *ma)
  11781. {
  11782. int i;
  11783. int strides = 0;
  11784. for (i = 0; i < ma->n; ++i)
  11785. if (!isl_int_is_one(ma->u.p[i]->v->el[0]))
  11786. strides++;
  11787. return strides;
  11788. }
  11789. /* For each affine expression in ma of the form
  11790. *
  11791. * x_i = (f_i y + h_i)/m_i
  11792. *
  11793. * with m_i different from one, add a constraint to "bmap"
  11794. * of the form
  11795. *
  11796. * f_i y + h_i = m_i alpha_i
  11797. *
  11798. * with alpha_i an additional existentially quantified variable.
  11799. *
  11800. * The input variables of "ma" correspond to a subset of the variables
  11801. * of "bmap". There are "n_before" variables in "bmap" before this
  11802. * subset and "n_after" variables after this subset.
  11803. * The integer divisions of the affine expressions in "ma" are assumed
  11804. * to have been aligned. There are "n_div_ma" of them and
  11805. * they appear first in "bmap", straight after the "n_after" variables.
  11806. */
  11807. static __isl_give isl_basic_map *add_ma_strides(
  11808. __isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma,
  11809. int n_before, int n_after, int n_div_ma)
  11810. {
  11811. int i, k;
  11812. int div;
  11813. isl_size total;
  11814. isl_size n_param;
  11815. isl_size n_in;
  11816. total = isl_basic_map_dim(bmap, isl_dim_all);
  11817. n_param = isl_multi_aff_dim(ma, isl_dim_param);
  11818. n_in = isl_multi_aff_dim(ma, isl_dim_in);
  11819. if (total < 0 || n_param < 0 || n_in < 0)
  11820. return isl_basic_map_free(bmap);
  11821. for (i = 0; i < ma->n; ++i) {
  11822. int o_bmap = 0, o_ma = 1;
  11823. if (isl_int_is_one(ma->u.p[i]->v->el[0]))
  11824. continue;
  11825. div = isl_basic_map_alloc_div(bmap);
  11826. k = isl_basic_map_alloc_equality(bmap);
  11827. if (div < 0 || k < 0)
  11828. goto error;
  11829. isl_int_set_si(bmap->div[div][0], 0);
  11830. isl_seq_cpy(bmap->eq[k] + o_bmap,
  11831. ma->u.p[i]->v->el + o_ma, 1 + n_param);
  11832. o_bmap += 1 + n_param;
  11833. o_ma += 1 + n_param;
  11834. isl_seq_clr(bmap->eq[k] + o_bmap, n_before);
  11835. o_bmap += n_before;
  11836. isl_seq_cpy(bmap->eq[k] + o_bmap,
  11837. ma->u.p[i]->v->el + o_ma, n_in);
  11838. o_bmap += n_in;
  11839. o_ma += n_in;
  11840. isl_seq_clr(bmap->eq[k] + o_bmap, n_after);
  11841. o_bmap += n_after;
  11842. isl_seq_cpy(bmap->eq[k] + o_bmap,
  11843. ma->u.p[i]->v->el + o_ma, n_div_ma);
  11844. o_bmap += n_div_ma;
  11845. o_ma += n_div_ma;
  11846. isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap);
  11847. isl_int_neg(bmap->eq[k][1 + total], ma->u.p[i]->v->el[0]);
  11848. total++;
  11849. }
  11850. return bmap;
  11851. error:
  11852. isl_basic_map_free(bmap);
  11853. return NULL;
  11854. }
  11855. /* Replace the domain or range space (depending on "type) of "space" by "set".
  11856. */
  11857. static __isl_give isl_space *isl_space_set(__isl_take isl_space *space,
  11858. enum isl_dim_type type, __isl_take isl_space *set)
  11859. {
  11860. if (type == isl_dim_in) {
  11861. space = isl_space_range(space);
  11862. space = isl_space_map_from_domain_and_range(set, space);
  11863. } else {
  11864. space = isl_space_domain(space);
  11865. space = isl_space_map_from_domain_and_range(space, set);
  11866. }
  11867. return space;
  11868. }
  11869. /* Compute the preimage of the domain or range (depending on "type")
  11870. * of "bmap" under the function represented by "ma".
  11871. * In other words, plug in "ma" in the domain or range of "bmap".
  11872. * The result is a basic map that lives in the same space as "bmap"
  11873. * except that the domain or range has been replaced by
  11874. * the domain space of "ma".
  11875. *
  11876. * If bmap is represented by
  11877. *
  11878. * A(p) + S u + B x + T v + C(divs) >= 0,
  11879. *
  11880. * where u and x are input and output dimensions if type == isl_dim_out
  11881. * while x and v are input and output dimensions if type == isl_dim_in,
  11882. * and ma is represented by
  11883. *
  11884. * x = D(p) + F(y) + G(divs')
  11885. *
  11886. * then the result is
  11887. *
  11888. * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
  11889. *
  11890. * The divs in the input set are similarly adjusted.
  11891. * In particular
  11892. *
  11893. * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
  11894. *
  11895. * becomes
  11896. *
  11897. * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
  11898. * B_i G(divs') + c_i(divs))/n_i)
  11899. *
  11900. * If bmap is not a rational map and if F(y) involves any denominators
  11901. *
  11902. * x_i = (f_i y + h_i)/m_i
  11903. *
  11904. * then additional constraints are added to ensure that we only
  11905. * map back integer points. That is we enforce
  11906. *
  11907. * f_i y + h_i = m_i alpha_i
  11908. *
  11909. * with alpha_i an additional existentially quantified variable.
  11910. *
  11911. * We first copy over the divs from "ma".
  11912. * Then we add the modified constraints and divs from "bmap".
  11913. * Finally, we add the stride constraints, if needed.
  11914. */
  11915. __isl_give isl_basic_map *isl_basic_map_preimage_multi_aff(
  11916. __isl_take isl_basic_map *bmap, enum isl_dim_type type,
  11917. __isl_take isl_multi_aff *ma)
  11918. {
  11919. int i, k;
  11920. isl_space *space;
  11921. isl_basic_map *res = NULL;
  11922. isl_size n_before, n_after, n_div_bmap, n_div_ma;
  11923. isl_int f, c1, c2, g;
  11924. isl_bool rational;
  11925. int strides;
  11926. isl_int_init(f);
  11927. isl_int_init(c1);
  11928. isl_int_init(c2);
  11929. isl_int_init(g);
  11930. ma = isl_multi_aff_align_divs(ma);
  11931. if (!bmap || !ma)
  11932. goto error;
  11933. if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0)
  11934. goto error;
  11935. if (type == isl_dim_in) {
  11936. n_before = 0;
  11937. n_after = isl_basic_map_dim(bmap, isl_dim_out);
  11938. } else {
  11939. n_before = isl_basic_map_dim(bmap, isl_dim_in);
  11940. n_after = 0;
  11941. }
  11942. n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div);
  11943. n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
  11944. if (n_before < 0 || n_after < 0 || n_div_bmap < 0 || n_div_ma < 0)
  11945. goto error;
  11946. space = isl_multi_aff_get_domain_space(ma);
  11947. space = isl_space_set(isl_basic_map_get_space(bmap), type, space);
  11948. rational = isl_basic_map_is_rational(bmap);
  11949. strides = rational ? 0 : multi_aff_strides(ma);
  11950. res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides,
  11951. bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma);
  11952. if (rational)
  11953. res = isl_basic_map_set_rational(res);
  11954. for (i = 0; i < n_div_ma + n_div_bmap; ++i)
  11955. if (isl_basic_map_alloc_div(res) < 0)
  11956. goto error;
  11957. res = set_ma_divs(res, ma, n_before, n_after, n_div_ma);
  11958. if (!res)
  11959. goto error;
  11960. for (i = 0; i < bmap->n_eq; ++i) {
  11961. k = isl_basic_map_alloc_equality(res);
  11962. if (k < 0)
  11963. goto error;
  11964. if (isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before,
  11965. n_after, n_div_ma, n_div_bmap,
  11966. f, c1, c2, g, 0) < 0)
  11967. goto error;
  11968. }
  11969. for (i = 0; i < bmap->n_ineq; ++i) {
  11970. k = isl_basic_map_alloc_inequality(res);
  11971. if (k < 0)
  11972. goto error;
  11973. if (isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before,
  11974. n_after, n_div_ma, n_div_bmap,
  11975. f, c1, c2, g, 0) < 0)
  11976. goto error;
  11977. }
  11978. for (i = 0; i < bmap->n_div; ++i) {
  11979. if (isl_int_is_zero(bmap->div[i][0])) {
  11980. isl_int_set_si(res->div[n_div_ma + i][0], 0);
  11981. continue;
  11982. }
  11983. if (isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma,
  11984. n_before, n_after, n_div_ma, n_div_bmap,
  11985. f, c1, c2, g, 1) < 0)
  11986. goto error;
  11987. }
  11988. if (strides)
  11989. res = add_ma_strides(res, ma, n_before, n_after, n_div_ma);
  11990. isl_int_clear(f);
  11991. isl_int_clear(c1);
  11992. isl_int_clear(c2);
  11993. isl_int_clear(g);
  11994. isl_basic_map_free(bmap);
  11995. isl_multi_aff_free(ma);
  11996. res = isl_basic_map_simplify(res);
  11997. return isl_basic_map_finalize(res);
  11998. error:
  11999. isl_int_clear(f);
  12000. isl_int_clear(c1);
  12001. isl_int_clear(c2);
  12002. isl_int_clear(g);
  12003. isl_basic_map_free(bmap);
  12004. isl_multi_aff_free(ma);
  12005. isl_basic_map_free(res);
  12006. return NULL;
  12007. }
  12008. /* Compute the preimage of "bset" under the function represented by "ma".
  12009. * In other words, plug in "ma" in "bset". The result is a basic set
  12010. * that lives in the domain space of "ma".
  12011. */
  12012. __isl_give isl_basic_set *isl_basic_set_preimage_multi_aff(
  12013. __isl_take isl_basic_set *bset, __isl_take isl_multi_aff *ma)
  12014. {
  12015. return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma);
  12016. }
  12017. /* Compute the preimage of the domain of "bmap" under the function
  12018. * represented by "ma".
  12019. * In other words, plug in "ma" in the domain of "bmap".
  12020. * The result is a basic map that lives in the same space as "bmap"
  12021. * except that the domain has been replaced by the domain space of "ma".
  12022. */
  12023. __isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff(
  12024. __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
  12025. {
  12026. return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma);
  12027. }
  12028. /* Compute the preimage of the range of "bmap" under the function
  12029. * represented by "ma".
  12030. * In other words, plug in "ma" in the range of "bmap".
  12031. * The result is a basic map that lives in the same space as "bmap"
  12032. * except that the range has been replaced by the domain space of "ma".
  12033. */
  12034. __isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff(
  12035. __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
  12036. {
  12037. return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma);
  12038. }
  12039. /* Check if the range of "ma" is compatible with the domain or range
  12040. * (depending on "type") of "map".
  12041. * Return isl_stat_error if anything is wrong.
  12042. */
  12043. static isl_stat check_map_compatible_range_multi_aff(
  12044. __isl_keep isl_map *map, enum isl_dim_type type,
  12045. __isl_keep isl_multi_aff *ma)
  12046. {
  12047. isl_bool m;
  12048. isl_space *ma_space;
  12049. ma_space = isl_multi_aff_get_space(ma);
  12050. m = isl_map_space_tuple_is_equal(map, type, ma_space, isl_dim_out);
  12051. isl_space_free(ma_space);
  12052. if (m < 0)
  12053. return isl_stat_error;
  12054. if (!m)
  12055. isl_die(isl_map_get_ctx(map), isl_error_invalid,
  12056. "spaces don't match", return isl_stat_error);
  12057. return isl_stat_ok;
  12058. }
  12059. /* Compute the preimage of the domain or range (depending on "type")
  12060. * of "map" under the function represented by "ma".
  12061. * In other words, plug in "ma" in the domain or range of "map".
  12062. * The result is a map that lives in the same space as "map"
  12063. * except that the domain or range has been replaced by
  12064. * the domain space of "ma".
  12065. *
  12066. * The parameters are assumed to have been aligned.
  12067. */
  12068. static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map,
  12069. enum isl_dim_type type, __isl_take isl_multi_aff *ma)
  12070. {
  12071. int i;
  12072. isl_space *space;
  12073. map = isl_map_cow(map);
  12074. ma = isl_multi_aff_align_divs(ma);
  12075. if (!map || !ma)
  12076. goto error;
  12077. if (check_map_compatible_range_multi_aff(map, type, ma) < 0)
  12078. goto error;
  12079. for (i = 0; i < map->n; ++i) {
  12080. map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type,
  12081. isl_multi_aff_copy(ma));
  12082. if (!map->p[i])
  12083. goto error;
  12084. }
  12085. space = isl_multi_aff_get_domain_space(ma);
  12086. space = isl_space_set(isl_map_get_space(map), type, space);
  12087. isl_space_free(isl_map_take_space(map));
  12088. map = isl_map_restore_space(map, space);
  12089. if (!map)
  12090. goto error;
  12091. isl_multi_aff_free(ma);
  12092. if (map->n > 1)
  12093. ISL_F_CLR(map, ISL_MAP_DISJOINT);
  12094. ISL_F_CLR(map, ISL_SET_NORMALIZED);
  12095. return map;
  12096. error:
  12097. isl_multi_aff_free(ma);
  12098. isl_map_free(map);
  12099. return NULL;
  12100. }
  12101. /* Compute the preimage of the domain or range (depending on "type")
  12102. * of "map" under the function represented by "ma".
  12103. * In other words, plug in "ma" in the domain or range of "map".
  12104. * The result is a map that lives in the same space as "map"
  12105. * except that the domain or range has been replaced by
  12106. * the domain space of "ma".
  12107. */
  12108. __isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map,
  12109. enum isl_dim_type type, __isl_take isl_multi_aff *ma)
  12110. {
  12111. isl_bool aligned;
  12112. if (!map || !ma)
  12113. goto error;
  12114. aligned = isl_map_space_has_equal_params(map, ma->space);
  12115. if (aligned < 0)
  12116. goto error;
  12117. if (aligned)
  12118. return map_preimage_multi_aff(map, type, ma);
  12119. if (isl_map_check_named_params(map) < 0)
  12120. goto error;
  12121. if (!isl_space_has_named_params(ma->space))
  12122. isl_die(map->ctx, isl_error_invalid,
  12123. "unaligned unnamed parameters", goto error);
  12124. map = isl_map_align_params(map, isl_multi_aff_get_space(ma));
  12125. ma = isl_multi_aff_align_params(ma, isl_map_get_space(map));
  12126. return map_preimage_multi_aff(map, type, ma);
  12127. error:
  12128. isl_multi_aff_free(ma);
  12129. return isl_map_free(map);
  12130. }
  12131. /* Compute the preimage of "set" under the function represented by "ma".
  12132. * In other words, plug in "ma" in "set". The result is a set
  12133. * that lives in the domain space of "ma".
  12134. */
  12135. __isl_give isl_set *isl_set_preimage_multi_aff(__isl_take isl_set *set,
  12136. __isl_take isl_multi_aff *ma)
  12137. {
  12138. return isl_map_preimage_multi_aff(set, isl_dim_set, ma);
  12139. }
  12140. /* Compute the preimage of the domain of "map" under the function
  12141. * represented by "ma".
  12142. * In other words, plug in "ma" in the domain of "map".
  12143. * The result is a map that lives in the same space as "map"
  12144. * except that the domain has been replaced by the domain space of "ma".
  12145. */
  12146. __isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map,
  12147. __isl_take isl_multi_aff *ma)
  12148. {
  12149. return isl_map_preimage_multi_aff(map, isl_dim_in, ma);
  12150. }
  12151. /* Compute the preimage of the range of "map" under the function
  12152. * represented by "ma".
  12153. * In other words, plug in "ma" in the range of "map".
  12154. * The result is a map that lives in the same space as "map"
  12155. * except that the range has been replaced by the domain space of "ma".
  12156. */
  12157. __isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map,
  12158. __isl_take isl_multi_aff *ma)
  12159. {
  12160. return isl_map_preimage_multi_aff(map, isl_dim_out, ma);
  12161. }
  12162. /* Compute the preimage of "map" under the function represented by "pma".
  12163. * In other words, plug in "pma" in the domain or range of "map".
  12164. * The result is a map that lives in the same space as "map",
  12165. * except that the space of type "type" has been replaced by
  12166. * the domain space of "pma".
  12167. *
  12168. * The parameters of "map" and "pma" are assumed to have been aligned.
  12169. */
  12170. static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned(
  12171. __isl_take isl_map *map, enum isl_dim_type type,
  12172. __isl_take isl_pw_multi_aff *pma)
  12173. {
  12174. int i;
  12175. isl_map *res;
  12176. if (!pma)
  12177. goto error;
  12178. if (pma->n == 0) {
  12179. isl_pw_multi_aff_free(pma);
  12180. res = isl_map_empty(isl_map_get_space(map));
  12181. isl_map_free(map);
  12182. return res;
  12183. }
  12184. res = isl_map_preimage_multi_aff(isl_map_copy(map), type,
  12185. isl_multi_aff_copy(pma->p[0].maff));
  12186. if (type == isl_dim_in)
  12187. res = isl_map_intersect_domain(res,
  12188. isl_map_copy(pma->p[0].set));
  12189. else
  12190. res = isl_map_intersect_range(res,
  12191. isl_map_copy(pma->p[0].set));
  12192. for (i = 1; i < pma->n; ++i) {
  12193. isl_map *res_i;
  12194. res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type,
  12195. isl_multi_aff_copy(pma->p[i].maff));
  12196. if (type == isl_dim_in)
  12197. res_i = isl_map_intersect_domain(res_i,
  12198. isl_map_copy(pma->p[i].set));
  12199. else
  12200. res_i = isl_map_intersect_range(res_i,
  12201. isl_map_copy(pma->p[i].set));
  12202. res = isl_map_union(res, res_i);
  12203. }
  12204. isl_pw_multi_aff_free(pma);
  12205. isl_map_free(map);
  12206. return res;
  12207. error:
  12208. isl_pw_multi_aff_free(pma);
  12209. isl_map_free(map);
  12210. return NULL;
  12211. }
  12212. /* Compute the preimage of "map" under the function represented by "pma".
  12213. * In other words, plug in "pma" in the domain or range of "map".
  12214. * The result is a map that lives in the same space as "map",
  12215. * except that the space of type "type" has been replaced by
  12216. * the domain space of "pma".
  12217. */
  12218. __isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map,
  12219. enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma)
  12220. {
  12221. isl_bool aligned;
  12222. if (!map || !pma)
  12223. goto error;
  12224. aligned = isl_map_space_has_equal_params(map, pma->dim);
  12225. if (aligned < 0)
  12226. goto error;
  12227. if (aligned)
  12228. return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
  12229. if (isl_map_check_named_params(map) < 0)
  12230. goto error;
  12231. if (isl_pw_multi_aff_check_named_params(pma) < 0)
  12232. goto error;
  12233. map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma));
  12234. pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map));
  12235. return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
  12236. error:
  12237. isl_pw_multi_aff_free(pma);
  12238. return isl_map_free(map);
  12239. }
  12240. /* Compute the preimage of "set" under the function represented by "pma".
  12241. * In other words, plug in "pma" in "set". The result is a set
  12242. * that lives in the domain space of "pma".
  12243. */
  12244. __isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set,
  12245. __isl_take isl_pw_multi_aff *pma)
  12246. {
  12247. return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma);
  12248. }
  12249. /* Compute the preimage of the domain of "map" under the function
  12250. * represented by "pma".
  12251. * In other words, plug in "pma" in the domain of "map".
  12252. * The result is a map that lives in the same space as "map",
  12253. * except that domain space has been replaced by the domain space of "pma".
  12254. */
  12255. __isl_give isl_map *isl_map_preimage_domain_pw_multi_aff(
  12256. __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
  12257. {
  12258. return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma);
  12259. }
  12260. /* Compute the preimage of the range of "map" under the function
  12261. * represented by "pma".
  12262. * In other words, plug in "pma" in the range of "map".
  12263. * The result is a map that lives in the same space as "map",
  12264. * except that range space has been replaced by the domain space of "pma".
  12265. */
  12266. __isl_give isl_map *isl_map_preimage_range_pw_multi_aff(
  12267. __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
  12268. {
  12269. return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma);
  12270. }
  12271. /* Compute the preimage of "map" under the function represented by "mpa".
  12272. * In other words, plug in "mpa" in the domain or range of "map".
  12273. * The result is a map that lives in the same space as "map",
  12274. * except that the space of type "type" has been replaced by
  12275. * the domain space of "mpa".
  12276. *
  12277. * If the map does not involve any constraints that refer to the
  12278. * dimensions of the substituted space, then the only possible
  12279. * effect of "mpa" on the map is to map the space to a different space.
  12280. * We create a separate isl_multi_aff to effectuate this change
  12281. * in order to avoid spurious splitting of the map along the pieces
  12282. * of "mpa".
  12283. * If "mpa" has a non-trivial explicit domain, however,
  12284. * then the full substitution should be performed.
  12285. */
  12286. __isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map,
  12287. enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa)
  12288. {
  12289. isl_size n;
  12290. isl_bool full;
  12291. isl_pw_multi_aff *pma;
  12292. n = isl_map_dim(map, type);
  12293. if (n < 0 || !mpa)
  12294. goto error;
  12295. full = isl_map_involves_dims(map, type, 0, n);
  12296. if (full >= 0 && !full)
  12297. full = isl_multi_pw_aff_has_non_trivial_domain(mpa);
  12298. if (full < 0)
  12299. goto error;
  12300. if (!full) {
  12301. isl_space *space;
  12302. isl_multi_aff *ma;
  12303. space = isl_multi_pw_aff_get_space(mpa);
  12304. isl_multi_pw_aff_free(mpa);
  12305. ma = isl_multi_aff_zero(space);
  12306. return isl_map_preimage_multi_aff(map, type, ma);
  12307. }
  12308. pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
  12309. return isl_map_preimage_pw_multi_aff(map, type, pma);
  12310. error:
  12311. isl_map_free(map);
  12312. isl_multi_pw_aff_free(mpa);
  12313. return NULL;
  12314. }
  12315. /* Compute the preimage of "map" under the function represented by "mpa".
  12316. * In other words, plug in "mpa" in the domain "map".
  12317. * The result is a map that lives in the same space as "map",
  12318. * except that domain space has been replaced by the domain space of "mpa".
  12319. */
  12320. __isl_give isl_map *isl_map_preimage_domain_multi_pw_aff(
  12321. __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa)
  12322. {
  12323. return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa);
  12324. }
  12325. /* Compute the preimage of "set" by the function represented by "mpa".
  12326. * In other words, plug in "mpa" in "set".
  12327. */
  12328. __isl_give isl_set *isl_set_preimage_multi_pw_aff(__isl_take isl_set *set,
  12329. __isl_take isl_multi_pw_aff *mpa)
  12330. {
  12331. return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
  12332. }
  12333. /* Return a copy of the equality constraints of "bset" as a matrix.
  12334. */
  12335. __isl_give isl_mat *isl_basic_set_extract_equalities(
  12336. __isl_keep isl_basic_set *bset)
  12337. {
  12338. isl_ctx *ctx;
  12339. isl_size total;
  12340. total = isl_basic_set_dim(bset, isl_dim_all);
  12341. if (total < 0)
  12342. return NULL;
  12343. ctx = isl_basic_set_get_ctx(bset);
  12344. return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, 1 + total);
  12345. }
  12346. /* Are the "n" "coefficients" starting at "first" of the integer division
  12347. * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
  12348. * to each other?
  12349. * The "coefficient" at position 0 is the denominator.
  12350. * The "coefficient" at position 1 is the constant term.
  12351. */
  12352. isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
  12353. int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
  12354. unsigned first, unsigned n)
  12355. {
  12356. if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0)
  12357. return isl_bool_error;
  12358. if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0)
  12359. return isl_bool_error;
  12360. return isl_seq_eq(bmap1->div[pos1] + first,
  12361. bmap2->div[pos2] + first, n);
  12362. }
  12363. /* Are the integer division expressions at position "pos1" in "bmap1" and
  12364. * "pos2" in "bmap2" equal to each other, except that the constant terms
  12365. * are different?
  12366. */
  12367. isl_bool isl_basic_map_equal_div_expr_except_constant(
  12368. __isl_keep isl_basic_map *bmap1, int pos1,
  12369. __isl_keep isl_basic_map *bmap2, int pos2)
  12370. {
  12371. isl_bool equal;
  12372. isl_size total, total2;
  12373. total = isl_basic_map_dim(bmap1, isl_dim_all);
  12374. total2 = isl_basic_map_dim(bmap2, isl_dim_all);
  12375. if (total < 0 || total2 < 0)
  12376. return isl_bool_error;
  12377. if (total != total2)
  12378. isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
  12379. "incomparable div expressions", return isl_bool_error);
  12380. equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
  12381. 0, 1);
  12382. if (equal < 0 || !equal)
  12383. return equal;
  12384. equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
  12385. 1, 1);
  12386. if (equal < 0 || equal)
  12387. return isl_bool_not(equal);
  12388. return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
  12389. 2, total);
  12390. }
  12391. /* Replace the numerator of the constant term of the integer division
  12392. * expression at position "div" in "bmap" by "value".
  12393. * The caller guarantees that this does not change the meaning
  12394. * of the input.
  12395. */
  12396. __isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace(
  12397. __isl_take isl_basic_map *bmap, int div, int value)
  12398. {
  12399. if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
  12400. return isl_basic_map_free(bmap);
  12401. isl_int_set_si(bmap->div[div][1], value);
  12402. return bmap;
  12403. }
  12404. /* Is the point "inner" internal to inequality constraint "ineq"
  12405. * of "bset"?
  12406. * The point is considered to be internal to the inequality constraint,
  12407. * if it strictly lies on the positive side of the inequality constraint,
  12408. * or if it lies on the constraint and the constraint is lexico-positive.
  12409. */
  12410. static isl_bool is_internal(__isl_keep isl_vec *inner,
  12411. __isl_keep isl_basic_set *bset, int ineq)
  12412. {
  12413. isl_ctx *ctx;
  12414. int pos;
  12415. isl_size total;
  12416. if (!inner || !bset)
  12417. return isl_bool_error;
  12418. ctx = isl_basic_set_get_ctx(bset);
  12419. isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size,
  12420. &ctx->normalize_gcd);
  12421. if (!isl_int_is_zero(ctx->normalize_gcd))
  12422. return isl_int_is_nonneg(ctx->normalize_gcd);
  12423. total = isl_basic_set_dim(bset, isl_dim_all);
  12424. if (total < 0)
  12425. return isl_bool_error;
  12426. pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total);
  12427. return isl_int_is_pos(bset->ineq[ineq][1 + pos]);
  12428. }
  12429. /* Tighten the inequality constraints of "bset" that are outward with respect
  12430. * to the point "vec".
  12431. * That is, tighten the constraints that are not satisfied by "vec".
  12432. *
  12433. * "vec" is a point internal to some superset S of "bset" that is used
  12434. * to make the subsets of S disjoint, by tightening one half of the constraints
  12435. * that separate two subsets. In particular, the constraints of S
  12436. * are all satisfied by "vec" and should not be tightened.
  12437. * Of the internal constraints, those that have "vec" on the outside
  12438. * are tightened. The shared facet is included in the adjacent subset
  12439. * with the opposite constraint.
  12440. * For constraints that saturate "vec", this criterion cannot be used
  12441. * to determine which of the two sides should be tightened.
  12442. * Instead, the sign of the first non-zero coefficient is used
  12443. * to make this choice. Note that this second criterion is never used
  12444. * on the constraints of S since "vec" is interior to "S".
  12445. */
  12446. __isl_give isl_basic_set *isl_basic_set_tighten_outward(
  12447. __isl_take isl_basic_set *bset, __isl_keep isl_vec *vec)
  12448. {
  12449. int j;
  12450. bset = isl_basic_set_cow(bset);
  12451. if (!bset)
  12452. return NULL;
  12453. for (j = 0; j < bset->n_ineq; ++j) {
  12454. isl_bool internal;
  12455. internal = is_internal(vec, bset, j);
  12456. if (internal < 0)
  12457. return isl_basic_set_free(bset);
  12458. if (internal)
  12459. continue;
  12460. isl_int_sub_ui(bset->ineq[j][0], bset->ineq[j][0], 1);
  12461. }
  12462. return bset;
  12463. }
  12464. /* Replace the variables x of type "type" starting at "first" in "bmap"
  12465. * by x' with x = M x' with M the matrix trans.
  12466. * That is, replace the corresponding coefficients c by c M.
  12467. *
  12468. * The transformation matrix should be a square matrix.
  12469. */
  12470. __isl_give isl_basic_map *isl_basic_map_transform_dims(
  12471. __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first,
  12472. __isl_take isl_mat *trans)
  12473. {
  12474. unsigned pos;
  12475. bmap = isl_basic_map_cow(bmap);
  12476. if (!bmap || !trans)
  12477. goto error;
  12478. if (trans->n_row != trans->n_col)
  12479. isl_die(trans->ctx, isl_error_invalid,
  12480. "expecting square transformation matrix", goto error);
  12481. if (isl_basic_map_check_range(bmap, type, first, trans->n_row) < 0)
  12482. goto error;
  12483. pos = isl_basic_map_offset(bmap, type) + first;
  12484. if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos,
  12485. isl_mat_copy(trans)) < 0)
  12486. goto error;
  12487. if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos,
  12488. isl_mat_copy(trans)) < 0)
  12489. goto error;
  12490. if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos,
  12491. isl_mat_copy(trans)) < 0)
  12492. goto error;
  12493. ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
  12494. ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
  12495. isl_mat_free(trans);
  12496. return bmap;
  12497. error:
  12498. isl_mat_free(trans);
  12499. isl_basic_map_free(bmap);
  12500. return NULL;
  12501. }
  12502. /* Replace the variables x of type "type" starting at "first" in "bset"
  12503. * by x' with x = M x' with M the matrix trans.
  12504. * That is, replace the corresponding coefficients c by c M.
  12505. *
  12506. * The transformation matrix should be a square matrix.
  12507. */
  12508. __isl_give isl_basic_set *isl_basic_set_transform_dims(
  12509. __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned first,
  12510. __isl_take isl_mat *trans)
  12511. {
  12512. return isl_basic_map_transform_dims(bset, type, first, trans);
  12513. }