isl_tab.c 113 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259
  1. /*
  2. * Copyright 2008-2009 Katholieke Universiteit Leuven
  3. * Copyright 2013 Ecole Normale Superieure
  4. * Copyright 2014 INRIA Rocquencourt
  5. * Copyright 2016 Sven Verdoolaege
  6. *
  7. * Use of this software is governed by the MIT license
  8. *
  9. * Written by Sven Verdoolaege, K.U.Leuven, Departement
  10. * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
  11. * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
  12. * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
  13. * B.P. 105 - 78153 Le Chesnay, France
  14. */
  15. #include <isl_ctx_private.h>
  16. #include <isl_mat_private.h>
  17. #include <isl_vec_private.h>
  18. #include "isl_map_private.h"
  19. #include "isl_tab.h"
  20. #include <isl_seq.h>
  21. #include <isl_config.h>
  22. #include <bset_to_bmap.c>
  23. #include <bset_from_bmap.c>
  24. /*
  25. * The implementation of tableaus in this file was inspired by Section 8
  26. * of David Detlefs, Greg Nelson and James B. Saxe, "Simplify: a theorem
  27. * prover for program checking".
  28. */
  29. struct isl_tab *isl_tab_alloc(struct isl_ctx *ctx,
  30. unsigned n_row, unsigned n_var, unsigned M)
  31. {
  32. int i;
  33. struct isl_tab *tab;
  34. unsigned off = 2 + M;
  35. tab = isl_calloc_type(ctx, struct isl_tab);
  36. if (!tab)
  37. return NULL;
  38. tab->mat = isl_mat_alloc(ctx, n_row, off + n_var);
  39. if (!tab->mat)
  40. goto error;
  41. tab->var = isl_alloc_array(ctx, struct isl_tab_var, n_var);
  42. if (n_var && !tab->var)
  43. goto error;
  44. tab->con = isl_alloc_array(ctx, struct isl_tab_var, n_row);
  45. if (n_row && !tab->con)
  46. goto error;
  47. tab->col_var = isl_alloc_array(ctx, int, n_var);
  48. if (n_var && !tab->col_var)
  49. goto error;
  50. tab->row_var = isl_alloc_array(ctx, int, n_row);
  51. if (n_row && !tab->row_var)
  52. goto error;
  53. for (i = 0; i < n_var; ++i) {
  54. tab->var[i].index = i;
  55. tab->var[i].is_row = 0;
  56. tab->var[i].is_nonneg = 0;
  57. tab->var[i].is_zero = 0;
  58. tab->var[i].is_redundant = 0;
  59. tab->var[i].frozen = 0;
  60. tab->var[i].negated = 0;
  61. tab->col_var[i] = i;
  62. }
  63. tab->n_row = 0;
  64. tab->n_con = 0;
  65. tab->n_eq = 0;
  66. tab->max_con = n_row;
  67. tab->n_col = n_var;
  68. tab->n_var = n_var;
  69. tab->max_var = n_var;
  70. tab->n_param = 0;
  71. tab->n_div = 0;
  72. tab->n_dead = 0;
  73. tab->n_redundant = 0;
  74. tab->strict_redundant = 0;
  75. tab->need_undo = 0;
  76. tab->rational = 0;
  77. tab->empty = 0;
  78. tab->in_undo = 0;
  79. tab->M = M;
  80. tab->cone = 0;
  81. tab->bottom.type = isl_tab_undo_bottom;
  82. tab->bottom.next = NULL;
  83. tab->top = &tab->bottom;
  84. tab->n_zero = 0;
  85. tab->n_unbounded = 0;
  86. tab->basis = NULL;
  87. return tab;
  88. error:
  89. isl_tab_free(tab);
  90. return NULL;
  91. }
  92. isl_ctx *isl_tab_get_ctx(struct isl_tab *tab)
  93. {
  94. return tab ? isl_mat_get_ctx(tab->mat) : NULL;
  95. }
  96. int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new)
  97. {
  98. unsigned off;
  99. if (!tab)
  100. return -1;
  101. off = 2 + tab->M;
  102. if (tab->max_con < tab->n_con + n_new) {
  103. struct isl_tab_var *con;
  104. con = isl_realloc_array(tab->mat->ctx, tab->con,
  105. struct isl_tab_var, tab->max_con + n_new);
  106. if (!con)
  107. return -1;
  108. tab->con = con;
  109. tab->max_con += n_new;
  110. }
  111. if (tab->mat->n_row < tab->n_row + n_new) {
  112. int *row_var;
  113. tab->mat = isl_mat_extend(tab->mat,
  114. tab->n_row + n_new, off + tab->n_col);
  115. if (!tab->mat)
  116. return -1;
  117. row_var = isl_realloc_array(tab->mat->ctx, tab->row_var,
  118. int, tab->mat->n_row);
  119. if (!row_var)
  120. return -1;
  121. tab->row_var = row_var;
  122. if (tab->row_sign) {
  123. enum isl_tab_row_sign *s;
  124. s = isl_realloc_array(tab->mat->ctx, tab->row_sign,
  125. enum isl_tab_row_sign, tab->mat->n_row);
  126. if (!s)
  127. return -1;
  128. tab->row_sign = s;
  129. }
  130. }
  131. return 0;
  132. }
  133. /* Make room for at least n_new extra variables.
  134. * Return -1 if anything went wrong.
  135. */
  136. int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new)
  137. {
  138. struct isl_tab_var *var;
  139. unsigned off = 2 + tab->M;
  140. if (tab->max_var < tab->n_var + n_new) {
  141. var = isl_realloc_array(tab->mat->ctx, tab->var,
  142. struct isl_tab_var, tab->n_var + n_new);
  143. if (!var)
  144. return -1;
  145. tab->var = var;
  146. tab->max_var = tab->n_var + n_new;
  147. }
  148. if (tab->mat->n_col < off + tab->n_col + n_new) {
  149. int *p;
  150. tab->mat = isl_mat_extend(tab->mat,
  151. tab->mat->n_row, off + tab->n_col + n_new);
  152. if (!tab->mat)
  153. return -1;
  154. p = isl_realloc_array(tab->mat->ctx, tab->col_var,
  155. int, tab->n_col + n_new);
  156. if (!p)
  157. return -1;
  158. tab->col_var = p;
  159. }
  160. return 0;
  161. }
  162. static void free_undo_record(struct isl_tab_undo *undo)
  163. {
  164. switch (undo->type) {
  165. case isl_tab_undo_saved_basis:
  166. free(undo->u.col_var);
  167. break;
  168. default:;
  169. }
  170. free(undo);
  171. }
  172. static void free_undo(struct isl_tab *tab)
  173. {
  174. struct isl_tab_undo *undo, *next;
  175. for (undo = tab->top; undo && undo != &tab->bottom; undo = next) {
  176. next = undo->next;
  177. free_undo_record(undo);
  178. }
  179. tab->top = undo;
  180. }
  181. void isl_tab_free(struct isl_tab *tab)
  182. {
  183. if (!tab)
  184. return;
  185. free_undo(tab);
  186. isl_mat_free(tab->mat);
  187. isl_vec_free(tab->dual);
  188. isl_basic_map_free(tab->bmap);
  189. free(tab->var);
  190. free(tab->con);
  191. free(tab->row_var);
  192. free(tab->col_var);
  193. free(tab->row_sign);
  194. isl_mat_free(tab->samples);
  195. free(tab->sample_index);
  196. isl_mat_free(tab->basis);
  197. free(tab);
  198. }
  199. struct isl_tab *isl_tab_dup(struct isl_tab *tab)
  200. {
  201. int i;
  202. struct isl_tab *dup;
  203. unsigned off;
  204. if (!tab)
  205. return NULL;
  206. off = 2 + tab->M;
  207. dup = isl_calloc_type(tab->mat->ctx, struct isl_tab);
  208. if (!dup)
  209. return NULL;
  210. dup->mat = isl_mat_dup(tab->mat);
  211. if (!dup->mat)
  212. goto error;
  213. dup->var = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_var);
  214. if (tab->max_var && !dup->var)
  215. goto error;
  216. for (i = 0; i < tab->n_var; ++i)
  217. dup->var[i] = tab->var[i];
  218. dup->con = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_con);
  219. if (tab->max_con && !dup->con)
  220. goto error;
  221. for (i = 0; i < tab->n_con; ++i)
  222. dup->con[i] = tab->con[i];
  223. dup->col_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_col - off);
  224. if ((tab->mat->n_col - off) && !dup->col_var)
  225. goto error;
  226. for (i = 0; i < tab->n_col; ++i)
  227. dup->col_var[i] = tab->col_var[i];
  228. dup->row_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_row);
  229. if (tab->mat->n_row && !dup->row_var)
  230. goto error;
  231. for (i = 0; i < tab->n_row; ++i)
  232. dup->row_var[i] = tab->row_var[i];
  233. if (tab->row_sign) {
  234. dup->row_sign = isl_alloc_array(tab->mat->ctx, enum isl_tab_row_sign,
  235. tab->mat->n_row);
  236. if (tab->mat->n_row && !dup->row_sign)
  237. goto error;
  238. for (i = 0; i < tab->n_row; ++i)
  239. dup->row_sign[i] = tab->row_sign[i];
  240. }
  241. if (tab->samples) {
  242. dup->samples = isl_mat_dup(tab->samples);
  243. if (!dup->samples)
  244. goto error;
  245. dup->sample_index = isl_alloc_array(tab->mat->ctx, int,
  246. tab->samples->n_row);
  247. if (tab->samples->n_row && !dup->sample_index)
  248. goto error;
  249. dup->n_sample = tab->n_sample;
  250. dup->n_outside = tab->n_outside;
  251. }
  252. dup->n_row = tab->n_row;
  253. dup->n_con = tab->n_con;
  254. dup->n_eq = tab->n_eq;
  255. dup->max_con = tab->max_con;
  256. dup->n_col = tab->n_col;
  257. dup->n_var = tab->n_var;
  258. dup->max_var = tab->max_var;
  259. dup->n_param = tab->n_param;
  260. dup->n_div = tab->n_div;
  261. dup->n_dead = tab->n_dead;
  262. dup->n_redundant = tab->n_redundant;
  263. dup->rational = tab->rational;
  264. dup->empty = tab->empty;
  265. dup->strict_redundant = 0;
  266. dup->need_undo = 0;
  267. dup->in_undo = 0;
  268. dup->M = tab->M;
  269. dup->cone = tab->cone;
  270. dup->bottom.type = isl_tab_undo_bottom;
  271. dup->bottom.next = NULL;
  272. dup->top = &dup->bottom;
  273. dup->n_zero = tab->n_zero;
  274. dup->n_unbounded = tab->n_unbounded;
  275. dup->basis = isl_mat_dup(tab->basis);
  276. return dup;
  277. error:
  278. isl_tab_free(dup);
  279. return NULL;
  280. }
  281. /* Construct the coefficient matrix of the product tableau
  282. * of two tableaus.
  283. * mat{1,2} is the coefficient matrix of tableau {1,2}
  284. * row{1,2} is the number of rows in tableau {1,2}
  285. * col{1,2} is the number of columns in tableau {1,2}
  286. * off is the offset to the coefficient column (skipping the
  287. * denominator, the constant term and the big parameter if any)
  288. * r{1,2} is the number of redundant rows in tableau {1,2}
  289. * d{1,2} is the number of dead columns in tableau {1,2}
  290. *
  291. * The order of the rows and columns in the result is as explained
  292. * in isl_tab_product.
  293. */
  294. static __isl_give isl_mat *tab_mat_product(__isl_keep isl_mat *mat1,
  295. __isl_keep isl_mat *mat2, unsigned row1, unsigned row2,
  296. unsigned col1, unsigned col2,
  297. unsigned off, unsigned r1, unsigned r2, unsigned d1, unsigned d2)
  298. {
  299. int i;
  300. struct isl_mat *prod;
  301. unsigned n;
  302. prod = isl_mat_alloc(mat1->ctx, mat1->n_row + mat2->n_row,
  303. off + col1 + col2);
  304. if (!prod)
  305. return NULL;
  306. n = 0;
  307. for (i = 0; i < r1; ++i) {
  308. isl_seq_cpy(prod->row[n + i], mat1->row[i], off + d1);
  309. isl_seq_clr(prod->row[n + i] + off + d1, d2);
  310. isl_seq_cpy(prod->row[n + i] + off + d1 + d2,
  311. mat1->row[i] + off + d1, col1 - d1);
  312. isl_seq_clr(prod->row[n + i] + off + col1 + d1, col2 - d2);
  313. }
  314. n += r1;
  315. for (i = 0; i < r2; ++i) {
  316. isl_seq_cpy(prod->row[n + i], mat2->row[i], off);
  317. isl_seq_clr(prod->row[n + i] + off, d1);
  318. isl_seq_cpy(prod->row[n + i] + off + d1,
  319. mat2->row[i] + off, d2);
  320. isl_seq_clr(prod->row[n + i] + off + d1 + d2, col1 - d1);
  321. isl_seq_cpy(prod->row[n + i] + off + col1 + d1,
  322. mat2->row[i] + off + d2, col2 - d2);
  323. }
  324. n += r2;
  325. for (i = 0; i < row1 - r1; ++i) {
  326. isl_seq_cpy(prod->row[n + i], mat1->row[r1 + i], off + d1);
  327. isl_seq_clr(prod->row[n + i] + off + d1, d2);
  328. isl_seq_cpy(prod->row[n + i] + off + d1 + d2,
  329. mat1->row[r1 + i] + off + d1, col1 - d1);
  330. isl_seq_clr(prod->row[n + i] + off + col1 + d1, col2 - d2);
  331. }
  332. n += row1 - r1;
  333. for (i = 0; i < row2 - r2; ++i) {
  334. isl_seq_cpy(prod->row[n + i], mat2->row[r2 + i], off);
  335. isl_seq_clr(prod->row[n + i] + off, d1);
  336. isl_seq_cpy(prod->row[n + i] + off + d1,
  337. mat2->row[r2 + i] + off, d2);
  338. isl_seq_clr(prod->row[n + i] + off + d1 + d2, col1 - d1);
  339. isl_seq_cpy(prod->row[n + i] + off + col1 + d1,
  340. mat2->row[r2 + i] + off + d2, col2 - d2);
  341. }
  342. return prod;
  343. }
  344. /* Update the row or column index of a variable that corresponds
  345. * to a variable in the first input tableau.
  346. */
  347. static void update_index1(struct isl_tab_var *var,
  348. unsigned r1, unsigned r2, unsigned d1, unsigned d2)
  349. {
  350. if (var->index == -1)
  351. return;
  352. if (var->is_row && var->index >= r1)
  353. var->index += r2;
  354. if (!var->is_row && var->index >= d1)
  355. var->index += d2;
  356. }
  357. /* Update the row or column index of a variable that corresponds
  358. * to a variable in the second input tableau.
  359. */
  360. static void update_index2(struct isl_tab_var *var,
  361. unsigned row1, unsigned col1,
  362. unsigned r1, unsigned r2, unsigned d1, unsigned d2)
  363. {
  364. if (var->index == -1)
  365. return;
  366. if (var->is_row) {
  367. if (var->index < r2)
  368. var->index += r1;
  369. else
  370. var->index += row1;
  371. } else {
  372. if (var->index < d2)
  373. var->index += d1;
  374. else
  375. var->index += col1;
  376. }
  377. }
  378. /* Create a tableau that represents the Cartesian product of the sets
  379. * represented by tableaus tab1 and tab2.
  380. * The order of the rows in the product is
  381. * - redundant rows of tab1
  382. * - redundant rows of tab2
  383. * - non-redundant rows of tab1
  384. * - non-redundant rows of tab2
  385. * The order of the columns is
  386. * - denominator
  387. * - constant term
  388. * - coefficient of big parameter, if any
  389. * - dead columns of tab1
  390. * - dead columns of tab2
  391. * - live columns of tab1
  392. * - live columns of tab2
  393. * The order of the variables and the constraints is a concatenation
  394. * of order in the two input tableaus.
  395. */
  396. struct isl_tab *isl_tab_product(struct isl_tab *tab1, struct isl_tab *tab2)
  397. {
  398. int i;
  399. struct isl_tab *prod;
  400. unsigned off;
  401. unsigned r1, r2, d1, d2;
  402. if (!tab1 || !tab2)
  403. return NULL;
  404. isl_assert(tab1->mat->ctx, tab1->M == tab2->M, return NULL);
  405. isl_assert(tab1->mat->ctx, tab1->rational == tab2->rational, return NULL);
  406. isl_assert(tab1->mat->ctx, tab1->cone == tab2->cone, return NULL);
  407. isl_assert(tab1->mat->ctx, !tab1->row_sign, return NULL);
  408. isl_assert(tab1->mat->ctx, !tab2->row_sign, return NULL);
  409. isl_assert(tab1->mat->ctx, tab1->n_param == 0, return NULL);
  410. isl_assert(tab1->mat->ctx, tab2->n_param == 0, return NULL);
  411. isl_assert(tab1->mat->ctx, tab1->n_div == 0, return NULL);
  412. isl_assert(tab1->mat->ctx, tab2->n_div == 0, return NULL);
  413. off = 2 + tab1->M;
  414. r1 = tab1->n_redundant;
  415. r2 = tab2->n_redundant;
  416. d1 = tab1->n_dead;
  417. d2 = tab2->n_dead;
  418. prod = isl_calloc_type(tab1->mat->ctx, struct isl_tab);
  419. if (!prod)
  420. return NULL;
  421. prod->mat = tab_mat_product(tab1->mat, tab2->mat,
  422. tab1->n_row, tab2->n_row,
  423. tab1->n_col, tab2->n_col, off, r1, r2, d1, d2);
  424. if (!prod->mat)
  425. goto error;
  426. prod->var = isl_alloc_array(tab1->mat->ctx, struct isl_tab_var,
  427. tab1->max_var + tab2->max_var);
  428. if ((tab1->max_var + tab2->max_var) && !prod->var)
  429. goto error;
  430. for (i = 0; i < tab1->n_var; ++i) {
  431. prod->var[i] = tab1->var[i];
  432. update_index1(&prod->var[i], r1, r2, d1, d2);
  433. }
  434. for (i = 0; i < tab2->n_var; ++i) {
  435. prod->var[tab1->n_var + i] = tab2->var[i];
  436. update_index2(&prod->var[tab1->n_var + i],
  437. tab1->n_row, tab1->n_col,
  438. r1, r2, d1, d2);
  439. }
  440. prod->con = isl_alloc_array(tab1->mat->ctx, struct isl_tab_var,
  441. tab1->max_con + tab2->max_con);
  442. if ((tab1->max_con + tab2->max_con) && !prod->con)
  443. goto error;
  444. for (i = 0; i < tab1->n_con; ++i) {
  445. prod->con[i] = tab1->con[i];
  446. update_index1(&prod->con[i], r1, r2, d1, d2);
  447. }
  448. for (i = 0; i < tab2->n_con; ++i) {
  449. prod->con[tab1->n_con + i] = tab2->con[i];
  450. update_index2(&prod->con[tab1->n_con + i],
  451. tab1->n_row, tab1->n_col,
  452. r1, r2, d1, d2);
  453. }
  454. prod->col_var = isl_alloc_array(tab1->mat->ctx, int,
  455. tab1->n_col + tab2->n_col);
  456. if ((tab1->n_col + tab2->n_col) && !prod->col_var)
  457. goto error;
  458. for (i = 0; i < tab1->n_col; ++i) {
  459. int pos = i < d1 ? i : i + d2;
  460. prod->col_var[pos] = tab1->col_var[i];
  461. }
  462. for (i = 0; i < tab2->n_col; ++i) {
  463. int pos = i < d2 ? d1 + i : tab1->n_col + i;
  464. int t = tab2->col_var[i];
  465. if (t >= 0)
  466. t += tab1->n_var;
  467. else
  468. t -= tab1->n_con;
  469. prod->col_var[pos] = t;
  470. }
  471. prod->row_var = isl_alloc_array(tab1->mat->ctx, int,
  472. tab1->mat->n_row + tab2->mat->n_row);
  473. if ((tab1->mat->n_row + tab2->mat->n_row) && !prod->row_var)
  474. goto error;
  475. for (i = 0; i < tab1->n_row; ++i) {
  476. int pos = i < r1 ? i : i + r2;
  477. prod->row_var[pos] = tab1->row_var[i];
  478. }
  479. for (i = 0; i < tab2->n_row; ++i) {
  480. int pos = i < r2 ? r1 + i : tab1->n_row + i;
  481. int t = tab2->row_var[i];
  482. if (t >= 0)
  483. t += tab1->n_var;
  484. else
  485. t -= tab1->n_con;
  486. prod->row_var[pos] = t;
  487. }
  488. prod->samples = NULL;
  489. prod->sample_index = NULL;
  490. prod->n_row = tab1->n_row + tab2->n_row;
  491. prod->n_con = tab1->n_con + tab2->n_con;
  492. prod->n_eq = 0;
  493. prod->max_con = tab1->max_con + tab2->max_con;
  494. prod->n_col = tab1->n_col + tab2->n_col;
  495. prod->n_var = tab1->n_var + tab2->n_var;
  496. prod->max_var = tab1->max_var + tab2->max_var;
  497. prod->n_param = 0;
  498. prod->n_div = 0;
  499. prod->n_dead = tab1->n_dead + tab2->n_dead;
  500. prod->n_redundant = tab1->n_redundant + tab2->n_redundant;
  501. prod->rational = tab1->rational;
  502. prod->empty = tab1->empty || tab2->empty;
  503. prod->strict_redundant = tab1->strict_redundant || tab2->strict_redundant;
  504. prod->need_undo = 0;
  505. prod->in_undo = 0;
  506. prod->M = tab1->M;
  507. prod->cone = tab1->cone;
  508. prod->bottom.type = isl_tab_undo_bottom;
  509. prod->bottom.next = NULL;
  510. prod->top = &prod->bottom;
  511. prod->n_zero = 0;
  512. prod->n_unbounded = 0;
  513. prod->basis = NULL;
  514. return prod;
  515. error:
  516. isl_tab_free(prod);
  517. return NULL;
  518. }
  519. static struct isl_tab_var *var_from_index(struct isl_tab *tab, int i)
  520. {
  521. if (i >= 0)
  522. return &tab->var[i];
  523. else
  524. return &tab->con[~i];
  525. }
  526. struct isl_tab_var *isl_tab_var_from_row(struct isl_tab *tab, int i)
  527. {
  528. return var_from_index(tab, tab->row_var[i]);
  529. }
  530. static struct isl_tab_var *var_from_col(struct isl_tab *tab, int i)
  531. {
  532. return var_from_index(tab, tab->col_var[i]);
  533. }
  534. /* Check if there are any upper bounds on column variable "var",
  535. * i.e., non-negative rows where var appears with a negative coefficient.
  536. * Return 1 if there are no such bounds.
  537. */
  538. static int max_is_manifestly_unbounded(struct isl_tab *tab,
  539. struct isl_tab_var *var)
  540. {
  541. int i;
  542. unsigned off = 2 + tab->M;
  543. if (var->is_row)
  544. return 0;
  545. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  546. if (!isl_int_is_neg(tab->mat->row[i][off + var->index]))
  547. continue;
  548. if (isl_tab_var_from_row(tab, i)->is_nonneg)
  549. return 0;
  550. }
  551. return 1;
  552. }
  553. /* Check if there are any lower bounds on column variable "var",
  554. * i.e., non-negative rows where var appears with a positive coefficient.
  555. * Return 1 if there are no such bounds.
  556. */
  557. static int min_is_manifestly_unbounded(struct isl_tab *tab,
  558. struct isl_tab_var *var)
  559. {
  560. int i;
  561. unsigned off = 2 + tab->M;
  562. if (var->is_row)
  563. return 0;
  564. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  565. if (!isl_int_is_pos(tab->mat->row[i][off + var->index]))
  566. continue;
  567. if (isl_tab_var_from_row(tab, i)->is_nonneg)
  568. return 0;
  569. }
  570. return 1;
  571. }
  572. static int row_cmp(struct isl_tab *tab, int r1, int r2, int c, isl_int *t)
  573. {
  574. unsigned off = 2 + tab->M;
  575. if (tab->M) {
  576. int s;
  577. isl_int_mul(*t, tab->mat->row[r1][2], tab->mat->row[r2][off+c]);
  578. isl_int_submul(*t, tab->mat->row[r2][2], tab->mat->row[r1][off+c]);
  579. s = isl_int_sgn(*t);
  580. if (s)
  581. return s;
  582. }
  583. isl_int_mul(*t, tab->mat->row[r1][1], tab->mat->row[r2][off + c]);
  584. isl_int_submul(*t, tab->mat->row[r2][1], tab->mat->row[r1][off + c]);
  585. return isl_int_sgn(*t);
  586. }
  587. /* Given the index of a column "c", return the index of a row
  588. * that can be used to pivot the column in, with either an increase
  589. * (sgn > 0) or a decrease (sgn < 0) of the corresponding variable.
  590. * If "var" is not NULL, then the row returned will be different from
  591. * the one associated with "var".
  592. *
  593. * Each row in the tableau is of the form
  594. *
  595. * x_r = a_r0 + \sum_i a_ri x_i
  596. *
  597. * Only rows with x_r >= 0 and with the sign of a_ri opposite to "sgn"
  598. * impose any limit on the increase or decrease in the value of x_c
  599. * and this bound is equal to a_r0 / |a_rc|. We are therefore looking
  600. * for the row with the smallest (most stringent) such bound.
  601. * Note that the common denominator of each row drops out of the fraction.
  602. * To check if row j has a smaller bound than row r, i.e.,
  603. * a_j0 / |a_jc| < a_r0 / |a_rc| or a_j0 |a_rc| < a_r0 |a_jc|,
  604. * we check if -sign(a_jc) (a_j0 a_rc - a_r0 a_jc) < 0,
  605. * where -sign(a_jc) is equal to "sgn".
  606. */
  607. static int pivot_row(struct isl_tab *tab,
  608. struct isl_tab_var *var, int sgn, int c)
  609. {
  610. int j, r, tsgn;
  611. isl_int t;
  612. unsigned off = 2 + tab->M;
  613. isl_int_init(t);
  614. r = -1;
  615. for (j = tab->n_redundant; j < tab->n_row; ++j) {
  616. if (var && j == var->index)
  617. continue;
  618. if (!isl_tab_var_from_row(tab, j)->is_nonneg)
  619. continue;
  620. if (sgn * isl_int_sgn(tab->mat->row[j][off + c]) >= 0)
  621. continue;
  622. if (r < 0) {
  623. r = j;
  624. continue;
  625. }
  626. tsgn = sgn * row_cmp(tab, r, j, c, &t);
  627. if (tsgn < 0 || (tsgn == 0 &&
  628. tab->row_var[j] < tab->row_var[r]))
  629. r = j;
  630. }
  631. isl_int_clear(t);
  632. return r;
  633. }
  634. /* Find a pivot (row and col) that will increase (sgn > 0) or decrease
  635. * (sgn < 0) the value of row variable var.
  636. * If not NULL, then skip_var is a row variable that should be ignored
  637. * while looking for a pivot row. It is usually equal to var.
  638. *
  639. * As the given row in the tableau is of the form
  640. *
  641. * x_r = a_r0 + \sum_i a_ri x_i
  642. *
  643. * we need to find a column such that the sign of a_ri is equal to "sgn"
  644. * (such that an increase in x_i will have the desired effect) or a
  645. * column with a variable that may attain negative values.
  646. * If a_ri is positive, then we need to move x_i in the same direction
  647. * to obtain the desired effect. Otherwise, x_i has to move in the
  648. * opposite direction.
  649. */
  650. static void find_pivot(struct isl_tab *tab,
  651. struct isl_tab_var *var, struct isl_tab_var *skip_var,
  652. int sgn, int *row, int *col)
  653. {
  654. int j, r, c;
  655. isl_int *tr;
  656. *row = *col = -1;
  657. isl_assert(tab->mat->ctx, var->is_row, return);
  658. tr = tab->mat->row[var->index] + 2 + tab->M;
  659. c = -1;
  660. for (j = tab->n_dead; j < tab->n_col; ++j) {
  661. if (isl_int_is_zero(tr[j]))
  662. continue;
  663. if (isl_int_sgn(tr[j]) != sgn &&
  664. var_from_col(tab, j)->is_nonneg)
  665. continue;
  666. if (c < 0 || tab->col_var[j] < tab->col_var[c])
  667. c = j;
  668. }
  669. if (c < 0)
  670. return;
  671. sgn *= isl_int_sgn(tr[c]);
  672. r = pivot_row(tab, skip_var, sgn, c);
  673. *row = r < 0 ? var->index : r;
  674. *col = c;
  675. }
  676. /* Return 1 if row "row" represents an obviously redundant inequality.
  677. * This means
  678. * - it represents an inequality or a variable
  679. * - that is the sum of a non-negative sample value and a positive
  680. * combination of zero or more non-negative constraints.
  681. */
  682. int isl_tab_row_is_redundant(struct isl_tab *tab, int row)
  683. {
  684. int i;
  685. unsigned off = 2 + tab->M;
  686. if (tab->row_var[row] < 0 && !isl_tab_var_from_row(tab, row)->is_nonneg)
  687. return 0;
  688. if (isl_int_is_neg(tab->mat->row[row][1]))
  689. return 0;
  690. if (tab->strict_redundant && isl_int_is_zero(tab->mat->row[row][1]))
  691. return 0;
  692. if (tab->M && isl_int_is_neg(tab->mat->row[row][2]))
  693. return 0;
  694. for (i = tab->n_dead; i < tab->n_col; ++i) {
  695. if (isl_int_is_zero(tab->mat->row[row][off + i]))
  696. continue;
  697. if (tab->col_var[i] >= 0)
  698. return 0;
  699. if (isl_int_is_neg(tab->mat->row[row][off + i]))
  700. return 0;
  701. if (!var_from_col(tab, i)->is_nonneg)
  702. return 0;
  703. }
  704. return 1;
  705. }
  706. static void swap_rows(struct isl_tab *tab, int row1, int row2)
  707. {
  708. int t;
  709. enum isl_tab_row_sign s;
  710. t = tab->row_var[row1];
  711. tab->row_var[row1] = tab->row_var[row2];
  712. tab->row_var[row2] = t;
  713. isl_tab_var_from_row(tab, row1)->index = row1;
  714. isl_tab_var_from_row(tab, row2)->index = row2;
  715. tab->mat = isl_mat_swap_rows(tab->mat, row1, row2);
  716. if (!tab->row_sign)
  717. return;
  718. s = tab->row_sign[row1];
  719. tab->row_sign[row1] = tab->row_sign[row2];
  720. tab->row_sign[row2] = s;
  721. }
  722. static isl_stat push_union(struct isl_tab *tab,
  723. enum isl_tab_undo_type type, union isl_tab_undo_val u) WARN_UNUSED;
  724. /* Push record "u" onto the undo stack of "tab", provided "tab"
  725. * keeps track of undo information.
  726. *
  727. * If the record cannot be pushed, then mark the undo stack as invalid
  728. * such that a later rollback attempt will not try to undo earlier
  729. * records without having been able to undo the current record.
  730. */
  731. static isl_stat push_union(struct isl_tab *tab,
  732. enum isl_tab_undo_type type, union isl_tab_undo_val u)
  733. {
  734. struct isl_tab_undo *undo;
  735. if (!tab)
  736. return isl_stat_error;
  737. if (!tab->need_undo)
  738. return isl_stat_ok;
  739. undo = isl_alloc_type(tab->mat->ctx, struct isl_tab_undo);
  740. if (!undo)
  741. goto error;
  742. undo->type = type;
  743. undo->u = u;
  744. undo->next = tab->top;
  745. tab->top = undo;
  746. return isl_stat_ok;
  747. error:
  748. free_undo(tab);
  749. tab->top = NULL;
  750. return isl_stat_error;
  751. }
  752. isl_stat isl_tab_push_var(struct isl_tab *tab,
  753. enum isl_tab_undo_type type, struct isl_tab_var *var)
  754. {
  755. union isl_tab_undo_val u;
  756. if (var->is_row)
  757. u.var_index = tab->row_var[var->index];
  758. else
  759. u.var_index = tab->col_var[var->index];
  760. return push_union(tab, type, u);
  761. }
  762. isl_stat isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type)
  763. {
  764. union isl_tab_undo_val u = { 0 };
  765. return push_union(tab, type, u);
  766. }
  767. /* Push a record on the undo stack describing the current basic
  768. * variables, so that the this state can be restored during rollback.
  769. */
  770. isl_stat isl_tab_push_basis(struct isl_tab *tab)
  771. {
  772. int i;
  773. union isl_tab_undo_val u;
  774. u.col_var = isl_alloc_array(tab->mat->ctx, int, tab->n_col);
  775. if (tab->n_col && !u.col_var)
  776. return isl_stat_error;
  777. for (i = 0; i < tab->n_col; ++i)
  778. u.col_var[i] = tab->col_var[i];
  779. return push_union(tab, isl_tab_undo_saved_basis, u);
  780. }
  781. isl_stat isl_tab_push_callback(struct isl_tab *tab,
  782. struct isl_tab_callback *callback)
  783. {
  784. union isl_tab_undo_val u;
  785. u.callback = callback;
  786. return push_union(tab, isl_tab_undo_callback, u);
  787. }
  788. struct isl_tab *isl_tab_init_samples(struct isl_tab *tab)
  789. {
  790. if (!tab)
  791. return NULL;
  792. tab->n_sample = 0;
  793. tab->n_outside = 0;
  794. tab->samples = isl_mat_alloc(tab->mat->ctx, 1, 1 + tab->n_var);
  795. if (!tab->samples)
  796. goto error;
  797. tab->sample_index = isl_alloc_array(tab->mat->ctx, int, 1);
  798. if (!tab->sample_index)
  799. goto error;
  800. return tab;
  801. error:
  802. isl_tab_free(tab);
  803. return NULL;
  804. }
  805. int isl_tab_add_sample(struct isl_tab *tab, __isl_take isl_vec *sample)
  806. {
  807. if (!tab || !sample)
  808. goto error;
  809. if (tab->n_sample + 1 > tab->samples->n_row) {
  810. int *t = isl_realloc_array(tab->mat->ctx,
  811. tab->sample_index, int, tab->n_sample + 1);
  812. if (!t)
  813. goto error;
  814. tab->sample_index = t;
  815. }
  816. tab->samples = isl_mat_extend(tab->samples,
  817. tab->n_sample + 1, tab->samples->n_col);
  818. if (!tab->samples)
  819. goto error;
  820. isl_seq_cpy(tab->samples->row[tab->n_sample], sample->el, sample->size);
  821. isl_vec_free(sample);
  822. tab->sample_index[tab->n_sample] = tab->n_sample;
  823. tab->n_sample++;
  824. return 0;
  825. error:
  826. isl_vec_free(sample);
  827. return -1;
  828. }
  829. struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s)
  830. {
  831. if (s != tab->n_outside) {
  832. int t = tab->sample_index[tab->n_outside];
  833. tab->sample_index[tab->n_outside] = tab->sample_index[s];
  834. tab->sample_index[s] = t;
  835. isl_mat_swap_rows(tab->samples, tab->n_outside, s);
  836. }
  837. tab->n_outside++;
  838. if (isl_tab_push(tab, isl_tab_undo_drop_sample) < 0) {
  839. isl_tab_free(tab);
  840. return NULL;
  841. }
  842. return tab;
  843. }
  844. /* Record the current number of samples so that we can remove newer
  845. * samples during a rollback.
  846. */
  847. isl_stat isl_tab_save_samples(struct isl_tab *tab)
  848. {
  849. union isl_tab_undo_val u;
  850. if (!tab)
  851. return isl_stat_error;
  852. u.n = tab->n_sample;
  853. return push_union(tab, isl_tab_undo_saved_samples, u);
  854. }
  855. /* Mark row with index "row" as being redundant.
  856. * If we may need to undo the operation or if the row represents
  857. * a variable of the original problem, the row is kept,
  858. * but no longer considered when looking for a pivot row.
  859. * Otherwise, the row is simply removed.
  860. *
  861. * The row may be interchanged with some other row. If it
  862. * is interchanged with a later row, return 1. Otherwise return 0.
  863. * If the rows are checked in order in the calling function,
  864. * then a return value of 1 means that the row with the given
  865. * row number may now contain a different row that hasn't been checked yet.
  866. */
  867. int isl_tab_mark_redundant(struct isl_tab *tab, int row)
  868. {
  869. struct isl_tab_var *var = isl_tab_var_from_row(tab, row);
  870. var->is_redundant = 1;
  871. isl_assert(tab->mat->ctx, row >= tab->n_redundant, return -1);
  872. if (tab->preserve || tab->need_undo || tab->row_var[row] >= 0) {
  873. if (tab->row_var[row] >= 0 && !var->is_nonneg) {
  874. var->is_nonneg = 1;
  875. if (isl_tab_push_var(tab, isl_tab_undo_nonneg, var) < 0)
  876. return -1;
  877. }
  878. if (row != tab->n_redundant)
  879. swap_rows(tab, row, tab->n_redundant);
  880. tab->n_redundant++;
  881. return isl_tab_push_var(tab, isl_tab_undo_redundant, var);
  882. } else {
  883. if (row != tab->n_row - 1)
  884. swap_rows(tab, row, tab->n_row - 1);
  885. isl_tab_var_from_row(tab, tab->n_row - 1)->index = -1;
  886. tab->n_row--;
  887. return 1;
  888. }
  889. }
  890. /* Mark "tab" as a rational tableau.
  891. * If it wasn't marked as a rational tableau already and if we may
  892. * need to undo changes, then arrange for the marking to be undone
  893. * during the undo.
  894. */
  895. int isl_tab_mark_rational(struct isl_tab *tab)
  896. {
  897. if (!tab)
  898. return -1;
  899. if (!tab->rational && tab->need_undo)
  900. if (isl_tab_push(tab, isl_tab_undo_rational) < 0)
  901. return -1;
  902. tab->rational = 1;
  903. return 0;
  904. }
  905. isl_stat isl_tab_mark_empty(struct isl_tab *tab)
  906. {
  907. if (!tab)
  908. return isl_stat_error;
  909. if (!tab->empty && tab->need_undo)
  910. if (isl_tab_push(tab, isl_tab_undo_empty) < 0)
  911. return isl_stat_error;
  912. tab->empty = 1;
  913. return isl_stat_ok;
  914. }
  915. int isl_tab_freeze_constraint(struct isl_tab *tab, int con)
  916. {
  917. struct isl_tab_var *var;
  918. if (!tab)
  919. return -1;
  920. var = &tab->con[con];
  921. if (var->frozen)
  922. return 0;
  923. if (var->index < 0)
  924. return 0;
  925. var->frozen = 1;
  926. if (tab->need_undo)
  927. return isl_tab_push_var(tab, isl_tab_undo_freeze, var);
  928. return 0;
  929. }
  930. /* Update the rows signs after a pivot of "row" and "col", with "row_sgn"
  931. * the original sign of the pivot element.
  932. * We only keep track of row signs during PILP solving and in this case
  933. * we only pivot a row with negative sign (meaning the value is always
  934. * non-positive) using a positive pivot element.
  935. *
  936. * For each row j, the new value of the parametric constant is equal to
  937. *
  938. * a_j0 - a_jc a_r0/a_rc
  939. *
  940. * where a_j0 is the original parametric constant, a_rc is the pivot element,
  941. * a_r0 is the parametric constant of the pivot row and a_jc is the
  942. * pivot column entry of the row j.
  943. * Since a_r0 is non-positive and a_rc is positive, the sign of row j
  944. * remains the same if a_jc has the same sign as the row j or if
  945. * a_jc is zero. In all other cases, we reset the sign to "unknown".
  946. */
  947. static void update_row_sign(struct isl_tab *tab, int row, int col, int row_sgn)
  948. {
  949. int i;
  950. struct isl_mat *mat = tab->mat;
  951. unsigned off = 2 + tab->M;
  952. if (!tab->row_sign)
  953. return;
  954. if (tab->row_sign[row] == 0)
  955. return;
  956. isl_assert(mat->ctx, row_sgn > 0, return);
  957. isl_assert(mat->ctx, tab->row_sign[row] == isl_tab_row_neg, return);
  958. tab->row_sign[row] = isl_tab_row_pos;
  959. for (i = 0; i < tab->n_row; ++i) {
  960. int s;
  961. if (i == row)
  962. continue;
  963. s = isl_int_sgn(mat->row[i][off + col]);
  964. if (!s)
  965. continue;
  966. if (!tab->row_sign[i])
  967. continue;
  968. if (s < 0 && tab->row_sign[i] == isl_tab_row_neg)
  969. continue;
  970. if (s > 0 && tab->row_sign[i] == isl_tab_row_pos)
  971. continue;
  972. tab->row_sign[i] = isl_tab_row_unknown;
  973. }
  974. }
  975. /* Given a row number "row" and a column number "col", pivot the tableau
  976. * such that the associated variables are interchanged.
  977. * The given row in the tableau expresses
  978. *
  979. * x_r = a_r0 + \sum_i a_ri x_i
  980. *
  981. * or
  982. *
  983. * x_c = 1/a_rc x_r - a_r0/a_rc + sum_{i \ne r} -a_ri/a_rc
  984. *
  985. * Substituting this equality into the other rows
  986. *
  987. * x_j = a_j0 + \sum_i a_ji x_i
  988. *
  989. * with a_jc \ne 0, we obtain
  990. *
  991. * x_j = a_jc/a_rc x_r + a_j0 - a_jc a_r0/a_rc + sum a_ji - a_jc a_ri/a_rc
  992. *
  993. * The tableau
  994. *
  995. * n_rc/d_r n_ri/d_r
  996. * n_jc/d_j n_ji/d_j
  997. *
  998. * where i is any other column and j is any other row,
  999. * is therefore transformed into
  1000. *
  1001. * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc|
  1002. * s(n_rc)d_r n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j)
  1003. *
  1004. * The transformation is performed along the following steps
  1005. *
  1006. * d_r/n_rc n_ri/n_rc
  1007. * n_jc/d_j n_ji/d_j
  1008. *
  1009. * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc|
  1010. * n_jc/d_j n_ji/d_j
  1011. *
  1012. * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc|
  1013. * n_jc/(|n_rc| d_j) n_ji/(|n_rc| d_j)
  1014. *
  1015. * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc|
  1016. * n_jc/(|n_rc| d_j) (n_ji |n_rc|)/(|n_rc| d_j)
  1017. *
  1018. * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc|
  1019. * n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j)
  1020. *
  1021. * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc|
  1022. * s(n_rc)d_r n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j)
  1023. *
  1024. */
  1025. int isl_tab_pivot(struct isl_tab *tab, int row, int col)
  1026. {
  1027. int i, j;
  1028. int sgn;
  1029. int t;
  1030. isl_ctx *ctx;
  1031. struct isl_mat *mat = tab->mat;
  1032. struct isl_tab_var *var;
  1033. unsigned off = 2 + tab->M;
  1034. ctx = isl_tab_get_ctx(tab);
  1035. if (isl_ctx_next_operation(ctx) < 0)
  1036. return -1;
  1037. isl_int_swap(mat->row[row][0], mat->row[row][off + col]);
  1038. sgn = isl_int_sgn(mat->row[row][0]);
  1039. if (sgn < 0) {
  1040. isl_int_neg(mat->row[row][0], mat->row[row][0]);
  1041. isl_int_neg(mat->row[row][off + col], mat->row[row][off + col]);
  1042. } else
  1043. for (j = 0; j < off - 1 + tab->n_col; ++j) {
  1044. if (j == off - 1 + col)
  1045. continue;
  1046. isl_int_neg(mat->row[row][1 + j], mat->row[row][1 + j]);
  1047. }
  1048. if (!isl_int_is_one(mat->row[row][0]))
  1049. isl_seq_normalize(mat->ctx, mat->row[row], off + tab->n_col);
  1050. for (i = 0; i < tab->n_row; ++i) {
  1051. if (i == row)
  1052. continue;
  1053. if (isl_int_is_zero(mat->row[i][off + col]))
  1054. continue;
  1055. isl_int_mul(mat->row[i][0], mat->row[i][0], mat->row[row][0]);
  1056. for (j = 0; j < off - 1 + tab->n_col; ++j) {
  1057. if (j == off - 1 + col)
  1058. continue;
  1059. isl_int_mul(mat->row[i][1 + j],
  1060. mat->row[i][1 + j], mat->row[row][0]);
  1061. isl_int_addmul(mat->row[i][1 + j],
  1062. mat->row[i][off + col], mat->row[row][1 + j]);
  1063. }
  1064. isl_int_mul(mat->row[i][off + col],
  1065. mat->row[i][off + col], mat->row[row][off + col]);
  1066. if (!isl_int_is_one(mat->row[i][0]))
  1067. isl_seq_normalize(mat->ctx, mat->row[i], off + tab->n_col);
  1068. }
  1069. t = tab->row_var[row];
  1070. tab->row_var[row] = tab->col_var[col];
  1071. tab->col_var[col] = t;
  1072. var = isl_tab_var_from_row(tab, row);
  1073. var->is_row = 1;
  1074. var->index = row;
  1075. var = var_from_col(tab, col);
  1076. var->is_row = 0;
  1077. var->index = col;
  1078. update_row_sign(tab, row, col, sgn);
  1079. if (tab->in_undo)
  1080. return 0;
  1081. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  1082. if (isl_int_is_zero(mat->row[i][off + col]))
  1083. continue;
  1084. if (!isl_tab_var_from_row(tab, i)->frozen &&
  1085. isl_tab_row_is_redundant(tab, i)) {
  1086. int redo = isl_tab_mark_redundant(tab, i);
  1087. if (redo < 0)
  1088. return -1;
  1089. if (redo)
  1090. --i;
  1091. }
  1092. }
  1093. return 0;
  1094. }
  1095. /* If "var" represents a column variable, then pivot is up (sgn > 0)
  1096. * or down (sgn < 0) to a row. The variable is assumed not to be
  1097. * unbounded in the specified direction.
  1098. * If sgn = 0, then the variable is unbounded in both directions,
  1099. * and we pivot with any row we can find.
  1100. */
  1101. static int to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign) WARN_UNUSED;
  1102. static int to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign)
  1103. {
  1104. int r;
  1105. unsigned off = 2 + tab->M;
  1106. if (var->is_row)
  1107. return 0;
  1108. if (sign == 0) {
  1109. for (r = tab->n_redundant; r < tab->n_row; ++r)
  1110. if (!isl_int_is_zero(tab->mat->row[r][off+var->index]))
  1111. break;
  1112. isl_assert(tab->mat->ctx, r < tab->n_row, return -1);
  1113. } else {
  1114. r = pivot_row(tab, NULL, sign, var->index);
  1115. isl_assert(tab->mat->ctx, r >= 0, return -1);
  1116. }
  1117. return isl_tab_pivot(tab, r, var->index);
  1118. }
  1119. /* Check whether all variables that are marked as non-negative
  1120. * also have a non-negative sample value. This function is not
  1121. * called from the current code but is useful during debugging.
  1122. */
  1123. static void check_table(struct isl_tab *tab) __attribute__ ((unused));
  1124. static void check_table(struct isl_tab *tab)
  1125. {
  1126. int i;
  1127. if (tab->empty)
  1128. return;
  1129. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  1130. struct isl_tab_var *var;
  1131. var = isl_tab_var_from_row(tab, i);
  1132. if (!var->is_nonneg)
  1133. continue;
  1134. if (tab->M) {
  1135. isl_assert(tab->mat->ctx,
  1136. !isl_int_is_neg(tab->mat->row[i][2]), abort());
  1137. if (isl_int_is_pos(tab->mat->row[i][2]))
  1138. continue;
  1139. }
  1140. isl_assert(tab->mat->ctx, !isl_int_is_neg(tab->mat->row[i][1]),
  1141. abort());
  1142. }
  1143. }
  1144. /* Return the sign of the maximal value of "var".
  1145. * If the sign is not negative, then on return from this function,
  1146. * the sample value will also be non-negative.
  1147. *
  1148. * If "var" is manifestly unbounded wrt positive values, we are done.
  1149. * Otherwise, we pivot the variable up to a row if needed
  1150. * Then we continue pivoting down until either
  1151. * - no more down pivots can be performed
  1152. * - the sample value is positive
  1153. * - the variable is pivoted into a manifestly unbounded column
  1154. */
  1155. static int sign_of_max(struct isl_tab *tab, struct isl_tab_var *var)
  1156. {
  1157. int row, col;
  1158. if (max_is_manifestly_unbounded(tab, var))
  1159. return 1;
  1160. if (to_row(tab, var, 1) < 0)
  1161. return -2;
  1162. while (!isl_int_is_pos(tab->mat->row[var->index][1])) {
  1163. find_pivot(tab, var, var, 1, &row, &col);
  1164. if (row == -1)
  1165. return isl_int_sgn(tab->mat->row[var->index][1]);
  1166. if (isl_tab_pivot(tab, row, col) < 0)
  1167. return -2;
  1168. if (!var->is_row) /* manifestly unbounded */
  1169. return 1;
  1170. }
  1171. return 1;
  1172. }
  1173. int isl_tab_sign_of_max(struct isl_tab *tab, int con)
  1174. {
  1175. struct isl_tab_var *var;
  1176. if (!tab)
  1177. return -2;
  1178. var = &tab->con[con];
  1179. isl_assert(tab->mat->ctx, !var->is_redundant, return -2);
  1180. isl_assert(tab->mat->ctx, !var->is_zero, return -2);
  1181. return sign_of_max(tab, var);
  1182. }
  1183. static int row_is_neg(struct isl_tab *tab, int row)
  1184. {
  1185. if (!tab->M)
  1186. return isl_int_is_neg(tab->mat->row[row][1]);
  1187. if (isl_int_is_pos(tab->mat->row[row][2]))
  1188. return 0;
  1189. if (isl_int_is_neg(tab->mat->row[row][2]))
  1190. return 1;
  1191. return isl_int_is_neg(tab->mat->row[row][1]);
  1192. }
  1193. static int row_sgn(struct isl_tab *tab, int row)
  1194. {
  1195. if (!tab->M)
  1196. return isl_int_sgn(tab->mat->row[row][1]);
  1197. if (!isl_int_is_zero(tab->mat->row[row][2]))
  1198. return isl_int_sgn(tab->mat->row[row][2]);
  1199. else
  1200. return isl_int_sgn(tab->mat->row[row][1]);
  1201. }
  1202. /* Perform pivots until the row variable "var" has a non-negative
  1203. * sample value or until no more upward pivots can be performed.
  1204. * Return the sign of the sample value after the pivots have been
  1205. * performed.
  1206. */
  1207. static int restore_row(struct isl_tab *tab, struct isl_tab_var *var)
  1208. {
  1209. int row, col;
  1210. while (row_is_neg(tab, var->index)) {
  1211. find_pivot(tab, var, var, 1, &row, &col);
  1212. if (row == -1)
  1213. break;
  1214. if (isl_tab_pivot(tab, row, col) < 0)
  1215. return -2;
  1216. if (!var->is_row) /* manifestly unbounded */
  1217. return 1;
  1218. }
  1219. return row_sgn(tab, var->index);
  1220. }
  1221. /* Perform pivots until we are sure that the row variable "var"
  1222. * can attain non-negative values. After return from this
  1223. * function, "var" is still a row variable, but its sample
  1224. * value may not be non-negative, even if the function returns 1.
  1225. */
  1226. static int at_least_zero(struct isl_tab *tab, struct isl_tab_var *var)
  1227. {
  1228. int row, col;
  1229. while (isl_int_is_neg(tab->mat->row[var->index][1])) {
  1230. find_pivot(tab, var, var, 1, &row, &col);
  1231. if (row == -1)
  1232. break;
  1233. if (row == var->index) /* manifestly unbounded */
  1234. return 1;
  1235. if (isl_tab_pivot(tab, row, col) < 0)
  1236. return -1;
  1237. }
  1238. return !isl_int_is_neg(tab->mat->row[var->index][1]);
  1239. }
  1240. /* Return a negative value if "var" can attain negative values.
  1241. * Return a non-negative value otherwise.
  1242. *
  1243. * If "var" is manifestly unbounded wrt negative values, we are done.
  1244. * Otherwise, if var is in a column, we can pivot it down to a row.
  1245. * Then we continue pivoting down until either
  1246. * - the pivot would result in a manifestly unbounded column
  1247. * => we don't perform the pivot, but simply return -1
  1248. * - no more down pivots can be performed
  1249. * - the sample value is negative
  1250. * If the sample value becomes negative and the variable is supposed
  1251. * to be nonnegative, then we undo the last pivot.
  1252. * However, if the last pivot has made the pivoting variable
  1253. * obviously redundant, then it may have moved to another row.
  1254. * In that case we look for upward pivots until we reach a non-negative
  1255. * value again.
  1256. */
  1257. static int sign_of_min(struct isl_tab *tab, struct isl_tab_var *var)
  1258. {
  1259. int row, col;
  1260. struct isl_tab_var *pivot_var = NULL;
  1261. if (min_is_manifestly_unbounded(tab, var))
  1262. return -1;
  1263. if (!var->is_row) {
  1264. col = var->index;
  1265. row = pivot_row(tab, NULL, -1, col);
  1266. pivot_var = var_from_col(tab, col);
  1267. if (isl_tab_pivot(tab, row, col) < 0)
  1268. return -2;
  1269. if (var->is_redundant)
  1270. return 0;
  1271. if (isl_int_is_neg(tab->mat->row[var->index][1])) {
  1272. if (var->is_nonneg) {
  1273. if (!pivot_var->is_redundant &&
  1274. pivot_var->index == row) {
  1275. if (isl_tab_pivot(tab, row, col) < 0)
  1276. return -2;
  1277. } else
  1278. if (restore_row(tab, var) < -1)
  1279. return -2;
  1280. }
  1281. return -1;
  1282. }
  1283. }
  1284. if (var->is_redundant)
  1285. return 0;
  1286. while (!isl_int_is_neg(tab->mat->row[var->index][1])) {
  1287. find_pivot(tab, var, var, -1, &row, &col);
  1288. if (row == var->index)
  1289. return -1;
  1290. if (row == -1)
  1291. return isl_int_sgn(tab->mat->row[var->index][1]);
  1292. pivot_var = var_from_col(tab, col);
  1293. if (isl_tab_pivot(tab, row, col) < 0)
  1294. return -2;
  1295. if (var->is_redundant)
  1296. return 0;
  1297. }
  1298. if (pivot_var && var->is_nonneg) {
  1299. /* pivot back to non-negative value */
  1300. if (!pivot_var->is_redundant && pivot_var->index == row) {
  1301. if (isl_tab_pivot(tab, row, col) < 0)
  1302. return -2;
  1303. } else
  1304. if (restore_row(tab, var) < -1)
  1305. return -2;
  1306. }
  1307. return -1;
  1308. }
  1309. static int row_at_most_neg_one(struct isl_tab *tab, int row)
  1310. {
  1311. if (tab->M) {
  1312. if (isl_int_is_pos(tab->mat->row[row][2]))
  1313. return 0;
  1314. if (isl_int_is_neg(tab->mat->row[row][2]))
  1315. return 1;
  1316. }
  1317. return isl_int_is_neg(tab->mat->row[row][1]) &&
  1318. isl_int_abs_ge(tab->mat->row[row][1],
  1319. tab->mat->row[row][0]);
  1320. }
  1321. /* Return 1 if "var" can attain values <= -1.
  1322. * Return 0 otherwise.
  1323. *
  1324. * If the variable "var" is supposed to be non-negative (is_nonneg is set),
  1325. * then the sample value of "var" is assumed to be non-negative when the
  1326. * the function is called. If 1 is returned then the constraint
  1327. * is not redundant and the sample value is made non-negative again before
  1328. * the function returns.
  1329. */
  1330. int isl_tab_min_at_most_neg_one(struct isl_tab *tab, struct isl_tab_var *var)
  1331. {
  1332. int row, col;
  1333. struct isl_tab_var *pivot_var;
  1334. if (min_is_manifestly_unbounded(tab, var))
  1335. return 1;
  1336. if (!var->is_row) {
  1337. col = var->index;
  1338. row = pivot_row(tab, NULL, -1, col);
  1339. pivot_var = var_from_col(tab, col);
  1340. if (isl_tab_pivot(tab, row, col) < 0)
  1341. return -1;
  1342. if (var->is_redundant)
  1343. return 0;
  1344. if (row_at_most_neg_one(tab, var->index)) {
  1345. if (var->is_nonneg) {
  1346. if (!pivot_var->is_redundant &&
  1347. pivot_var->index == row) {
  1348. if (isl_tab_pivot(tab, row, col) < 0)
  1349. return -1;
  1350. } else
  1351. if (restore_row(tab, var) < -1)
  1352. return -1;
  1353. }
  1354. return 1;
  1355. }
  1356. }
  1357. if (var->is_redundant)
  1358. return 0;
  1359. do {
  1360. find_pivot(tab, var, var, -1, &row, &col);
  1361. if (row == var->index) {
  1362. if (var->is_nonneg && restore_row(tab, var) < -1)
  1363. return -1;
  1364. return 1;
  1365. }
  1366. if (row == -1)
  1367. return 0;
  1368. pivot_var = var_from_col(tab, col);
  1369. if (isl_tab_pivot(tab, row, col) < 0)
  1370. return -1;
  1371. if (var->is_redundant)
  1372. return 0;
  1373. } while (!row_at_most_neg_one(tab, var->index));
  1374. if (var->is_nonneg) {
  1375. /* pivot back to non-negative value */
  1376. if (!pivot_var->is_redundant && pivot_var->index == row)
  1377. if (isl_tab_pivot(tab, row, col) < 0)
  1378. return -1;
  1379. if (restore_row(tab, var) < -1)
  1380. return -1;
  1381. }
  1382. return 1;
  1383. }
  1384. /* Return 1 if "var" can attain values >= 1.
  1385. * Return 0 otherwise.
  1386. */
  1387. static int at_least_one(struct isl_tab *tab, struct isl_tab_var *var)
  1388. {
  1389. int row, col;
  1390. isl_int *r;
  1391. if (max_is_manifestly_unbounded(tab, var))
  1392. return 1;
  1393. if (to_row(tab, var, 1) < 0)
  1394. return -1;
  1395. r = tab->mat->row[var->index];
  1396. while (isl_int_lt(r[1], r[0])) {
  1397. find_pivot(tab, var, var, 1, &row, &col);
  1398. if (row == -1)
  1399. return isl_int_ge(r[1], r[0]);
  1400. if (row == var->index) /* manifestly unbounded */
  1401. return 1;
  1402. if (isl_tab_pivot(tab, row, col) < 0)
  1403. return -1;
  1404. }
  1405. return 1;
  1406. }
  1407. static void swap_cols(struct isl_tab *tab, int col1, int col2)
  1408. {
  1409. int t;
  1410. unsigned off = 2 + tab->M;
  1411. t = tab->col_var[col1];
  1412. tab->col_var[col1] = tab->col_var[col2];
  1413. tab->col_var[col2] = t;
  1414. var_from_col(tab, col1)->index = col1;
  1415. var_from_col(tab, col2)->index = col2;
  1416. tab->mat = isl_mat_swap_cols(tab->mat, off + col1, off + col2);
  1417. }
  1418. /* Mark column with index "col" as representing a zero variable.
  1419. * If we may need to undo the operation the column is kept,
  1420. * but no longer considered.
  1421. * Otherwise, the column is simply removed.
  1422. *
  1423. * The column may be interchanged with some other column. If it
  1424. * is interchanged with a later column, return 1. Otherwise return 0.
  1425. * If the columns are checked in order in the calling function,
  1426. * then a return value of 1 means that the column with the given
  1427. * column number may now contain a different column that
  1428. * hasn't been checked yet.
  1429. */
  1430. int isl_tab_kill_col(struct isl_tab *tab, int col)
  1431. {
  1432. var_from_col(tab, col)->is_zero = 1;
  1433. if (tab->need_undo) {
  1434. if (isl_tab_push_var(tab, isl_tab_undo_zero,
  1435. var_from_col(tab, col)) < 0)
  1436. return -1;
  1437. if (col != tab->n_dead)
  1438. swap_cols(tab, col, tab->n_dead);
  1439. tab->n_dead++;
  1440. return 0;
  1441. } else {
  1442. if (col != tab->n_col - 1)
  1443. swap_cols(tab, col, tab->n_col - 1);
  1444. var_from_col(tab, tab->n_col - 1)->index = -1;
  1445. tab->n_col--;
  1446. return 1;
  1447. }
  1448. }
  1449. static int row_is_manifestly_non_integral(struct isl_tab *tab, int row)
  1450. {
  1451. unsigned off = 2 + tab->M;
  1452. if (tab->M && !isl_int_eq(tab->mat->row[row][2],
  1453. tab->mat->row[row][0]))
  1454. return 0;
  1455. if (isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
  1456. tab->n_col - tab->n_dead) != -1)
  1457. return 0;
  1458. return !isl_int_is_divisible_by(tab->mat->row[row][1],
  1459. tab->mat->row[row][0]);
  1460. }
  1461. /* For integer tableaus, check if any of the coordinates are stuck
  1462. * at a non-integral value.
  1463. */
  1464. static int tab_is_manifestly_empty(struct isl_tab *tab)
  1465. {
  1466. int i;
  1467. if (tab->empty)
  1468. return 1;
  1469. if (tab->rational)
  1470. return 0;
  1471. for (i = 0; i < tab->n_var; ++i) {
  1472. if (!tab->var[i].is_row)
  1473. continue;
  1474. if (row_is_manifestly_non_integral(tab, tab->var[i].index))
  1475. return 1;
  1476. }
  1477. return 0;
  1478. }
  1479. /* Row variable "var" is non-negative and cannot attain any values
  1480. * larger than zero. This means that the coefficients of the unrestricted
  1481. * column variables are zero and that the coefficients of the non-negative
  1482. * column variables are zero or negative.
  1483. * Each of the non-negative variables with a negative coefficient can
  1484. * then also be written as the negative sum of non-negative variables
  1485. * and must therefore also be zero.
  1486. *
  1487. * If "temp_var" is set, then "var" is a temporary variable that
  1488. * will be removed after this function returns and for which
  1489. * no information is recorded on the undo stack.
  1490. * Do not add any undo records involving this variable in this case
  1491. * since the variable will have been removed before any future undo
  1492. * operations. Also avoid marking the variable as redundant,
  1493. * since that either adds an undo record or needlessly removes the row
  1494. * (the caller will take care of removing the row).
  1495. */
  1496. static isl_stat close_row(struct isl_tab *tab, struct isl_tab_var *var,
  1497. int temp_var) WARN_UNUSED;
  1498. static isl_stat close_row(struct isl_tab *tab, struct isl_tab_var *var,
  1499. int temp_var)
  1500. {
  1501. int j;
  1502. struct isl_mat *mat = tab->mat;
  1503. unsigned off = 2 + tab->M;
  1504. if (!var->is_nonneg)
  1505. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  1506. "expecting non-negative variable",
  1507. return isl_stat_error);
  1508. var->is_zero = 1;
  1509. if (!temp_var && tab->need_undo)
  1510. if (isl_tab_push_var(tab, isl_tab_undo_zero, var) < 0)
  1511. return isl_stat_error;
  1512. for (j = tab->n_dead; j < tab->n_col; ++j) {
  1513. int recheck;
  1514. if (isl_int_is_zero(mat->row[var->index][off + j]))
  1515. continue;
  1516. if (isl_int_is_pos(mat->row[var->index][off + j]))
  1517. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  1518. "row cannot have positive coefficients",
  1519. return isl_stat_error);
  1520. recheck = isl_tab_kill_col(tab, j);
  1521. if (recheck < 0)
  1522. return isl_stat_error;
  1523. if (recheck)
  1524. --j;
  1525. }
  1526. if (!temp_var && isl_tab_mark_redundant(tab, var->index) < 0)
  1527. return isl_stat_error;
  1528. if (tab_is_manifestly_empty(tab) && isl_tab_mark_empty(tab) < 0)
  1529. return isl_stat_error;
  1530. return isl_stat_ok;
  1531. }
  1532. /* Add a constraint to the tableau and allocate a row for it.
  1533. * Return the index into the constraint array "con".
  1534. *
  1535. * This function assumes that at least one more row and at least
  1536. * one more element in the constraint array are available in the tableau.
  1537. */
  1538. int isl_tab_allocate_con(struct isl_tab *tab)
  1539. {
  1540. int r;
  1541. isl_assert(tab->mat->ctx, tab->n_row < tab->mat->n_row, return -1);
  1542. isl_assert(tab->mat->ctx, tab->n_con < tab->max_con, return -1);
  1543. r = tab->n_con;
  1544. tab->con[r].index = tab->n_row;
  1545. tab->con[r].is_row = 1;
  1546. tab->con[r].is_nonneg = 0;
  1547. tab->con[r].is_zero = 0;
  1548. tab->con[r].is_redundant = 0;
  1549. tab->con[r].frozen = 0;
  1550. tab->con[r].negated = 0;
  1551. tab->row_var[tab->n_row] = ~r;
  1552. tab->n_row++;
  1553. tab->n_con++;
  1554. if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->con[r]) < 0)
  1555. return -1;
  1556. return r;
  1557. }
  1558. /* Move the entries in tab->var up one position, starting at "first",
  1559. * creating room for an extra entry at position "first".
  1560. * Since some of the entries of tab->row_var and tab->col_var contain
  1561. * indices into this array, they have to be updated accordingly.
  1562. */
  1563. static int var_insert_entry(struct isl_tab *tab, int first)
  1564. {
  1565. int i;
  1566. if (tab->n_var >= tab->max_var)
  1567. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  1568. "not enough room for new variable", return -1);
  1569. if (first > tab->n_var)
  1570. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  1571. "invalid initial position", return -1);
  1572. for (i = tab->n_var - 1; i >= first; --i) {
  1573. tab->var[i + 1] = tab->var[i];
  1574. if (tab->var[i + 1].is_row)
  1575. tab->row_var[tab->var[i + 1].index]++;
  1576. else
  1577. tab->col_var[tab->var[i + 1].index]++;
  1578. }
  1579. tab->n_var++;
  1580. return 0;
  1581. }
  1582. /* Drop the entry at position "first" in tab->var, moving all
  1583. * subsequent entries down.
  1584. * Since some of the entries of tab->row_var and tab->col_var contain
  1585. * indices into this array, they have to be updated accordingly.
  1586. */
  1587. static int var_drop_entry(struct isl_tab *tab, int first)
  1588. {
  1589. int i;
  1590. if (first >= tab->n_var)
  1591. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  1592. "invalid initial position", return -1);
  1593. tab->n_var--;
  1594. for (i = first; i < tab->n_var; ++i) {
  1595. tab->var[i] = tab->var[i + 1];
  1596. if (tab->var[i + 1].is_row)
  1597. tab->row_var[tab->var[i].index]--;
  1598. else
  1599. tab->col_var[tab->var[i].index]--;
  1600. }
  1601. return 0;
  1602. }
  1603. /* Add a variable to the tableau at position "r" and allocate a column for it.
  1604. * Return the index into the variable array "var", i.e., "r",
  1605. * or -1 on error.
  1606. */
  1607. int isl_tab_insert_var(struct isl_tab *tab, int r)
  1608. {
  1609. int i;
  1610. unsigned off = 2 + tab->M;
  1611. isl_assert(tab->mat->ctx, tab->n_col < tab->mat->n_col, return -1);
  1612. if (var_insert_entry(tab, r) < 0)
  1613. return -1;
  1614. tab->var[r].index = tab->n_col;
  1615. tab->var[r].is_row = 0;
  1616. tab->var[r].is_nonneg = 0;
  1617. tab->var[r].is_zero = 0;
  1618. tab->var[r].is_redundant = 0;
  1619. tab->var[r].frozen = 0;
  1620. tab->var[r].negated = 0;
  1621. tab->col_var[tab->n_col] = r;
  1622. for (i = 0; i < tab->n_row; ++i)
  1623. isl_int_set_si(tab->mat->row[i][off + tab->n_col], 0);
  1624. tab->n_col++;
  1625. if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->var[r]) < 0)
  1626. return -1;
  1627. return r;
  1628. }
  1629. /* Add a row to the tableau. The row is given as an affine combination
  1630. * of the original variables and needs to be expressed in terms of the
  1631. * column variables.
  1632. *
  1633. * This function assumes that at least one more row and at least
  1634. * one more element in the constraint array are available in the tableau.
  1635. *
  1636. * We add each term in turn.
  1637. * If r = n/d_r is the current sum and we need to add k x, then
  1638. * if x is a column variable, we increase the numerator of
  1639. * this column by k d_r
  1640. * if x = f/d_x is a row variable, then the new representation of r is
  1641. *
  1642. * n k f d_x/g n + d_r/g k f m/d_r n + m/d_g k f
  1643. * --- + --- = ------------------- = -------------------
  1644. * d_r d_r d_r d_x/g m
  1645. *
  1646. * with g the gcd of d_r and d_x and m the lcm of d_r and d_x.
  1647. *
  1648. * If tab->M is set, then, internally, each variable x is represented
  1649. * as x' - M. We then also need no subtract k d_r from the coefficient of M.
  1650. */
  1651. int isl_tab_add_row(struct isl_tab *tab, isl_int *line)
  1652. {
  1653. int i;
  1654. int r;
  1655. isl_int *row;
  1656. isl_int a, b;
  1657. unsigned off = 2 + tab->M;
  1658. r = isl_tab_allocate_con(tab);
  1659. if (r < 0)
  1660. return -1;
  1661. isl_int_init(a);
  1662. isl_int_init(b);
  1663. row = tab->mat->row[tab->con[r].index];
  1664. isl_int_set_si(row[0], 1);
  1665. isl_int_set(row[1], line[0]);
  1666. isl_seq_clr(row + 2, tab->M + tab->n_col);
  1667. for (i = 0; i < tab->n_var; ++i) {
  1668. if (tab->var[i].is_zero)
  1669. continue;
  1670. if (tab->var[i].is_row) {
  1671. isl_int_lcm(a,
  1672. row[0], tab->mat->row[tab->var[i].index][0]);
  1673. isl_int_swap(a, row[0]);
  1674. isl_int_divexact(a, row[0], a);
  1675. isl_int_divexact(b,
  1676. row[0], tab->mat->row[tab->var[i].index][0]);
  1677. isl_int_mul(b, b, line[1 + i]);
  1678. isl_seq_combine(row + 1, a, row + 1,
  1679. b, tab->mat->row[tab->var[i].index] + 1,
  1680. 1 + tab->M + tab->n_col);
  1681. } else
  1682. isl_int_addmul(row[off + tab->var[i].index],
  1683. line[1 + i], row[0]);
  1684. if (tab->M && i >= tab->n_param && i < tab->n_var - tab->n_div)
  1685. isl_int_submul(row[2], line[1 + i], row[0]);
  1686. }
  1687. isl_seq_normalize(tab->mat->ctx, row, off + tab->n_col);
  1688. isl_int_clear(a);
  1689. isl_int_clear(b);
  1690. if (tab->row_sign)
  1691. tab->row_sign[tab->con[r].index] = isl_tab_row_unknown;
  1692. return r;
  1693. }
  1694. static isl_stat drop_row(struct isl_tab *tab, int row)
  1695. {
  1696. isl_assert(tab->mat->ctx, ~tab->row_var[row] == tab->n_con - 1,
  1697. return isl_stat_error);
  1698. if (row != tab->n_row - 1)
  1699. swap_rows(tab, row, tab->n_row - 1);
  1700. tab->n_row--;
  1701. tab->n_con--;
  1702. return isl_stat_ok;
  1703. }
  1704. /* Drop the variable in column "col" along with the column.
  1705. * The column is removed first because it may need to be moved
  1706. * into the last position and this process requires
  1707. * the contents of the col_var array in a state
  1708. * before the removal of the variable.
  1709. */
  1710. static isl_stat drop_col(struct isl_tab *tab, int col)
  1711. {
  1712. int var;
  1713. var = tab->col_var[col];
  1714. if (col != tab->n_col - 1)
  1715. swap_cols(tab, col, tab->n_col - 1);
  1716. tab->n_col--;
  1717. if (var_drop_entry(tab, var) < 0)
  1718. return isl_stat_error;
  1719. return isl_stat_ok;
  1720. }
  1721. /* Add inequality "ineq" and check if it conflicts with the
  1722. * previously added constraints or if it is obviously redundant.
  1723. *
  1724. * This function assumes that at least one more row and at least
  1725. * one more element in the constraint array are available in the tableau.
  1726. */
  1727. isl_stat isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq)
  1728. {
  1729. int r;
  1730. int sgn;
  1731. isl_int cst;
  1732. if (!tab)
  1733. return isl_stat_error;
  1734. if (tab->bmap) {
  1735. struct isl_basic_map *bmap = tab->bmap;
  1736. isl_assert(tab->mat->ctx, tab->n_eq == bmap->n_eq,
  1737. return isl_stat_error);
  1738. isl_assert(tab->mat->ctx,
  1739. tab->n_con == bmap->n_eq + bmap->n_ineq,
  1740. return isl_stat_error);
  1741. tab->bmap = isl_basic_map_add_ineq(tab->bmap, ineq);
  1742. if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
  1743. return isl_stat_error;
  1744. if (!tab->bmap)
  1745. return isl_stat_error;
  1746. }
  1747. if (tab->cone) {
  1748. isl_int_init(cst);
  1749. isl_int_set_si(cst, 0);
  1750. isl_int_swap(ineq[0], cst);
  1751. }
  1752. r = isl_tab_add_row(tab, ineq);
  1753. if (tab->cone) {
  1754. isl_int_swap(ineq[0], cst);
  1755. isl_int_clear(cst);
  1756. }
  1757. if (r < 0)
  1758. return isl_stat_error;
  1759. tab->con[r].is_nonneg = 1;
  1760. if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
  1761. return isl_stat_error;
  1762. if (isl_tab_row_is_redundant(tab, tab->con[r].index)) {
  1763. if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
  1764. return isl_stat_error;
  1765. return isl_stat_ok;
  1766. }
  1767. sgn = restore_row(tab, &tab->con[r]);
  1768. if (sgn < -1)
  1769. return isl_stat_error;
  1770. if (sgn < 0)
  1771. return isl_tab_mark_empty(tab);
  1772. if (tab->con[r].is_row && isl_tab_row_is_redundant(tab, tab->con[r].index))
  1773. if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
  1774. return isl_stat_error;
  1775. return isl_stat_ok;
  1776. }
  1777. /* Pivot a non-negative variable down until it reaches the value zero
  1778. * and then pivot the variable into a column position.
  1779. */
  1780. static int to_col(struct isl_tab *tab, struct isl_tab_var *var) WARN_UNUSED;
  1781. static int to_col(struct isl_tab *tab, struct isl_tab_var *var)
  1782. {
  1783. int i;
  1784. int row, col;
  1785. unsigned off = 2 + tab->M;
  1786. if (!var->is_row)
  1787. return 0;
  1788. while (isl_int_is_pos(tab->mat->row[var->index][1])) {
  1789. find_pivot(tab, var, NULL, -1, &row, &col);
  1790. isl_assert(tab->mat->ctx, row != -1, return -1);
  1791. if (isl_tab_pivot(tab, row, col) < 0)
  1792. return -1;
  1793. if (!var->is_row)
  1794. return 0;
  1795. }
  1796. for (i = tab->n_dead; i < tab->n_col; ++i)
  1797. if (!isl_int_is_zero(tab->mat->row[var->index][off + i]))
  1798. break;
  1799. isl_assert(tab->mat->ctx, i < tab->n_col, return -1);
  1800. if (isl_tab_pivot(tab, var->index, i) < 0)
  1801. return -1;
  1802. return 0;
  1803. }
  1804. /* We assume Gaussian elimination has been performed on the equalities.
  1805. * The equalities can therefore never conflict.
  1806. * Adding the equalities is currently only really useful for a later call
  1807. * to isl_tab_ineq_type.
  1808. *
  1809. * This function assumes that at least one more row and at least
  1810. * one more element in the constraint array are available in the tableau.
  1811. */
  1812. static struct isl_tab *add_eq(struct isl_tab *tab, isl_int *eq)
  1813. {
  1814. int i;
  1815. int r;
  1816. if (!tab)
  1817. return NULL;
  1818. r = isl_tab_add_row(tab, eq);
  1819. if (r < 0)
  1820. goto error;
  1821. r = tab->con[r].index;
  1822. i = isl_seq_first_non_zero(tab->mat->row[r] + 2 + tab->M + tab->n_dead,
  1823. tab->n_col - tab->n_dead);
  1824. isl_assert(tab->mat->ctx, i >= 0, goto error);
  1825. i += tab->n_dead;
  1826. if (isl_tab_pivot(tab, r, i) < 0)
  1827. goto error;
  1828. if (isl_tab_kill_col(tab, i) < 0)
  1829. goto error;
  1830. tab->n_eq++;
  1831. return tab;
  1832. error:
  1833. isl_tab_free(tab);
  1834. return NULL;
  1835. }
  1836. /* Does the sample value of row "row" of "tab" involve the big parameter,
  1837. * if any?
  1838. */
  1839. static int row_is_big(struct isl_tab *tab, int row)
  1840. {
  1841. return tab->M && !isl_int_is_zero(tab->mat->row[row][2]);
  1842. }
  1843. static int row_is_manifestly_zero(struct isl_tab *tab, int row)
  1844. {
  1845. unsigned off = 2 + tab->M;
  1846. if (!isl_int_is_zero(tab->mat->row[row][1]))
  1847. return 0;
  1848. if (row_is_big(tab, row))
  1849. return 0;
  1850. return isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
  1851. tab->n_col - tab->n_dead) == -1;
  1852. }
  1853. /* Add an equality that is known to be valid for the given tableau.
  1854. *
  1855. * This function assumes that at least one more row and at least
  1856. * one more element in the constraint array are available in the tableau.
  1857. */
  1858. int isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq)
  1859. {
  1860. struct isl_tab_var *var;
  1861. int r;
  1862. if (!tab)
  1863. return -1;
  1864. r = isl_tab_add_row(tab, eq);
  1865. if (r < 0)
  1866. return -1;
  1867. var = &tab->con[r];
  1868. r = var->index;
  1869. if (row_is_manifestly_zero(tab, r)) {
  1870. var->is_zero = 1;
  1871. if (isl_tab_mark_redundant(tab, r) < 0)
  1872. return -1;
  1873. return 0;
  1874. }
  1875. if (isl_int_is_neg(tab->mat->row[r][1])) {
  1876. isl_seq_neg(tab->mat->row[r] + 1, tab->mat->row[r] + 1,
  1877. 1 + tab->n_col);
  1878. var->negated = 1;
  1879. }
  1880. var->is_nonneg = 1;
  1881. if (to_col(tab, var) < 0)
  1882. return -1;
  1883. var->is_nonneg = 0;
  1884. if (isl_tab_kill_col(tab, var->index) < 0)
  1885. return -1;
  1886. return 0;
  1887. }
  1888. /* Add a zero row to "tab" and return the corresponding index
  1889. * in the constraint array.
  1890. *
  1891. * This function assumes that at least one more row and at least
  1892. * one more element in the constraint array are available in the tableau.
  1893. */
  1894. static int add_zero_row(struct isl_tab *tab)
  1895. {
  1896. int r;
  1897. isl_int *row;
  1898. r = isl_tab_allocate_con(tab);
  1899. if (r < 0)
  1900. return -1;
  1901. row = tab->mat->row[tab->con[r].index];
  1902. isl_seq_clr(row + 1, 1 + tab->M + tab->n_col);
  1903. isl_int_set_si(row[0], 1);
  1904. return r;
  1905. }
  1906. /* Add equality "eq" and check if it conflicts with the
  1907. * previously added constraints or if it is obviously redundant.
  1908. *
  1909. * This function assumes that at least one more row and at least
  1910. * one more element in the constraint array are available in the tableau.
  1911. * If tab->bmap is set, then two rows are needed instead of one.
  1912. */
  1913. isl_stat isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
  1914. {
  1915. struct isl_tab_undo *snap = NULL;
  1916. struct isl_tab_var *var;
  1917. int r;
  1918. int row;
  1919. int sgn;
  1920. isl_int cst;
  1921. if (!tab)
  1922. return isl_stat_error;
  1923. isl_assert(tab->mat->ctx, !tab->M, return isl_stat_error);
  1924. if (tab->need_undo)
  1925. snap = isl_tab_snap(tab);
  1926. if (tab->cone) {
  1927. isl_int_init(cst);
  1928. isl_int_set_si(cst, 0);
  1929. isl_int_swap(eq[0], cst);
  1930. }
  1931. r = isl_tab_add_row(tab, eq);
  1932. if (tab->cone) {
  1933. isl_int_swap(eq[0], cst);
  1934. isl_int_clear(cst);
  1935. }
  1936. if (r < 0)
  1937. return isl_stat_error;
  1938. var = &tab->con[r];
  1939. row = var->index;
  1940. if (row_is_manifestly_zero(tab, row)) {
  1941. if (snap)
  1942. return isl_tab_rollback(tab, snap);
  1943. return drop_row(tab, row);
  1944. }
  1945. if (tab->bmap) {
  1946. tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
  1947. if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
  1948. return isl_stat_error;
  1949. isl_seq_neg(eq, eq, 1 + tab->n_var);
  1950. tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
  1951. isl_seq_neg(eq, eq, 1 + tab->n_var);
  1952. if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
  1953. return isl_stat_error;
  1954. if (!tab->bmap)
  1955. return isl_stat_error;
  1956. if (add_zero_row(tab) < 0)
  1957. return isl_stat_error;
  1958. }
  1959. sgn = isl_int_sgn(tab->mat->row[row][1]);
  1960. if (sgn > 0) {
  1961. isl_seq_neg(tab->mat->row[row] + 1, tab->mat->row[row] + 1,
  1962. 1 + tab->n_col);
  1963. var->negated = 1;
  1964. sgn = -1;
  1965. }
  1966. if (sgn < 0) {
  1967. sgn = sign_of_max(tab, var);
  1968. if (sgn < -1)
  1969. return isl_stat_error;
  1970. if (sgn < 0) {
  1971. if (isl_tab_mark_empty(tab) < 0)
  1972. return isl_stat_error;
  1973. return isl_stat_ok;
  1974. }
  1975. }
  1976. var->is_nonneg = 1;
  1977. if (to_col(tab, var) < 0)
  1978. return isl_stat_error;
  1979. var->is_nonneg = 0;
  1980. if (isl_tab_kill_col(tab, var->index) < 0)
  1981. return isl_stat_error;
  1982. return isl_stat_ok;
  1983. }
  1984. /* Construct and return an inequality that expresses an upper bound
  1985. * on the given div.
  1986. * In particular, if the div is given by
  1987. *
  1988. * d = floor(e/m)
  1989. *
  1990. * then the inequality expresses
  1991. *
  1992. * m d <= e
  1993. */
  1994. static __isl_give isl_vec *ineq_for_div(__isl_keep isl_basic_map *bmap,
  1995. unsigned div)
  1996. {
  1997. isl_size total;
  1998. unsigned div_pos;
  1999. struct isl_vec *ineq;
  2000. total = isl_basic_map_dim(bmap, isl_dim_all);
  2001. if (total < 0)
  2002. return NULL;
  2003. div_pos = 1 + total - bmap->n_div + div;
  2004. ineq = isl_vec_alloc(bmap->ctx, 1 + total);
  2005. if (!ineq)
  2006. return NULL;
  2007. isl_seq_cpy(ineq->el, bmap->div[div] + 1, 1 + total);
  2008. isl_int_neg(ineq->el[div_pos], bmap->div[div][0]);
  2009. return ineq;
  2010. }
  2011. /* For a div d = floor(f/m), add the constraints
  2012. *
  2013. * f - m d >= 0
  2014. * -(f-(m-1)) + m d >= 0
  2015. *
  2016. * Note that the second constraint is the negation of
  2017. *
  2018. * f - m d >= m
  2019. *
  2020. * If add_ineq is not NULL, then this function is used
  2021. * instead of isl_tab_add_ineq to effectively add the inequalities.
  2022. *
  2023. * This function assumes that at least two more rows and at least
  2024. * two more elements in the constraint array are available in the tableau.
  2025. */
  2026. static isl_stat add_div_constraints(struct isl_tab *tab, unsigned div,
  2027. isl_stat (*add_ineq)(void *user, isl_int *), void *user)
  2028. {
  2029. isl_size total;
  2030. unsigned div_pos;
  2031. struct isl_vec *ineq;
  2032. total = isl_basic_map_dim(tab->bmap, isl_dim_all);
  2033. if (total < 0)
  2034. return isl_stat_error;
  2035. div_pos = 1 + total - tab->bmap->n_div + div;
  2036. ineq = ineq_for_div(tab->bmap, div);
  2037. if (!ineq)
  2038. goto error;
  2039. if (add_ineq) {
  2040. if (add_ineq(user, ineq->el) < 0)
  2041. goto error;
  2042. } else {
  2043. if (isl_tab_add_ineq(tab, ineq->el) < 0)
  2044. goto error;
  2045. }
  2046. isl_seq_neg(ineq->el, tab->bmap->div[div] + 1, 1 + total);
  2047. isl_int_set(ineq->el[div_pos], tab->bmap->div[div][0]);
  2048. isl_int_add(ineq->el[0], ineq->el[0], ineq->el[div_pos]);
  2049. isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
  2050. if (add_ineq) {
  2051. if (add_ineq(user, ineq->el) < 0)
  2052. goto error;
  2053. } else {
  2054. if (isl_tab_add_ineq(tab, ineq->el) < 0)
  2055. goto error;
  2056. }
  2057. isl_vec_free(ineq);
  2058. return isl_stat_ok;
  2059. error:
  2060. isl_vec_free(ineq);
  2061. return isl_stat_error;
  2062. }
  2063. /* Check whether the div described by "div" is obviously non-negative.
  2064. * If we are using a big parameter, then we will encode the div
  2065. * as div' = M + div, which is always non-negative.
  2066. * Otherwise, we check whether div is a non-negative affine combination
  2067. * of non-negative variables.
  2068. */
  2069. static int div_is_nonneg(struct isl_tab *tab, __isl_keep isl_vec *div)
  2070. {
  2071. int i;
  2072. if (tab->M)
  2073. return 1;
  2074. if (isl_int_is_neg(div->el[1]))
  2075. return 0;
  2076. for (i = 0; i < tab->n_var; ++i) {
  2077. if (isl_int_is_neg(div->el[2 + i]))
  2078. return 0;
  2079. if (isl_int_is_zero(div->el[2 + i]))
  2080. continue;
  2081. if (!tab->var[i].is_nonneg)
  2082. return 0;
  2083. }
  2084. return 1;
  2085. }
  2086. /* Insert an extra div, prescribed by "div", to the tableau and
  2087. * the associated bmap (which is assumed to be non-NULL).
  2088. * The extra integer division is inserted at (tableau) position "pos".
  2089. * Return "pos" or -1 if an error occurred.
  2090. *
  2091. * If add_ineq is not NULL, then this function is used instead
  2092. * of isl_tab_add_ineq to add the div constraints.
  2093. * This complication is needed because the code in isl_tab_pip
  2094. * wants to perform some extra processing when an inequality
  2095. * is added to the tableau.
  2096. */
  2097. int isl_tab_insert_div(struct isl_tab *tab, int pos, __isl_keep isl_vec *div,
  2098. isl_stat (*add_ineq)(void *user, isl_int *), void *user)
  2099. {
  2100. int r;
  2101. int nonneg;
  2102. isl_size n_div;
  2103. int o_div;
  2104. if (!tab || !div)
  2105. return -1;
  2106. if (div->size != 1 + 1 + tab->n_var)
  2107. isl_die(isl_tab_get_ctx(tab), isl_error_invalid,
  2108. "unexpected size", return -1);
  2109. n_div = isl_basic_map_dim(tab->bmap, isl_dim_div);
  2110. if (n_div < 0)
  2111. return -1;
  2112. o_div = tab->n_var - n_div;
  2113. if (pos < o_div || pos > tab->n_var)
  2114. isl_die(isl_tab_get_ctx(tab), isl_error_invalid,
  2115. "invalid position", return -1);
  2116. nonneg = div_is_nonneg(tab, div);
  2117. if (isl_tab_extend_cons(tab, 3) < 0)
  2118. return -1;
  2119. if (isl_tab_extend_vars(tab, 1) < 0)
  2120. return -1;
  2121. r = isl_tab_insert_var(tab, pos);
  2122. if (r < 0)
  2123. return -1;
  2124. if (nonneg)
  2125. tab->var[r].is_nonneg = 1;
  2126. tab->bmap = isl_basic_map_insert_div(tab->bmap, pos - o_div, div);
  2127. if (!tab->bmap)
  2128. return -1;
  2129. if (isl_tab_push_var(tab, isl_tab_undo_bmap_div, &tab->var[r]) < 0)
  2130. return -1;
  2131. if (add_div_constraints(tab, pos - o_div, add_ineq, user) < 0)
  2132. return -1;
  2133. return r;
  2134. }
  2135. /* Add an extra div, prescribed by "div", to the tableau and
  2136. * the associated bmap (which is assumed to be non-NULL).
  2137. */
  2138. int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div)
  2139. {
  2140. if (!tab)
  2141. return -1;
  2142. return isl_tab_insert_div(tab, tab->n_var, div, NULL, NULL);
  2143. }
  2144. /* If "track" is set, then we want to keep track of all constraints in tab
  2145. * in its bmap field. This field is initialized from a copy of "bmap",
  2146. * so we need to make sure that all constraints in "bmap" also appear
  2147. * in the constructed tab.
  2148. */
  2149. __isl_give struct isl_tab *isl_tab_from_basic_map(
  2150. __isl_keep isl_basic_map *bmap, int track)
  2151. {
  2152. int i;
  2153. struct isl_tab *tab;
  2154. isl_size total;
  2155. total = isl_basic_map_dim(bmap, isl_dim_all);
  2156. if (total < 0)
  2157. return NULL;
  2158. tab = isl_tab_alloc(bmap->ctx, total + bmap->n_ineq + 1, total, 0);
  2159. if (!tab)
  2160. return NULL;
  2161. tab->preserve = track;
  2162. tab->rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
  2163. if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) {
  2164. if (isl_tab_mark_empty(tab) < 0)
  2165. goto error;
  2166. goto done;
  2167. }
  2168. for (i = 0; i < bmap->n_eq; ++i) {
  2169. tab = add_eq(tab, bmap->eq[i]);
  2170. if (!tab)
  2171. return tab;
  2172. }
  2173. for (i = 0; i < bmap->n_ineq; ++i) {
  2174. if (isl_tab_add_ineq(tab, bmap->ineq[i]) < 0)
  2175. goto error;
  2176. if (tab->empty)
  2177. goto done;
  2178. }
  2179. done:
  2180. if (track && isl_tab_track_bmap(tab, isl_basic_map_copy(bmap)) < 0)
  2181. goto error;
  2182. return tab;
  2183. error:
  2184. isl_tab_free(tab);
  2185. return NULL;
  2186. }
  2187. __isl_give struct isl_tab *isl_tab_from_basic_set(
  2188. __isl_keep isl_basic_set *bset, int track)
  2189. {
  2190. return isl_tab_from_basic_map(bset, track);
  2191. }
  2192. /* Construct a tableau corresponding to the recession cone of "bset".
  2193. */
  2194. struct isl_tab *isl_tab_from_recession_cone(__isl_keep isl_basic_set *bset,
  2195. int parametric)
  2196. {
  2197. isl_int cst;
  2198. int i;
  2199. struct isl_tab *tab;
  2200. isl_size offset = 0;
  2201. isl_size total;
  2202. total = isl_basic_set_dim(bset, isl_dim_all);
  2203. if (parametric)
  2204. offset = isl_basic_set_dim(bset, isl_dim_param);
  2205. if (total < 0 || offset < 0)
  2206. return NULL;
  2207. tab = isl_tab_alloc(bset->ctx, bset->n_eq + bset->n_ineq,
  2208. total - offset, 0);
  2209. if (!tab)
  2210. return NULL;
  2211. tab->rational = ISL_F_ISSET(bset, ISL_BASIC_SET_RATIONAL);
  2212. tab->cone = 1;
  2213. isl_int_init(cst);
  2214. isl_int_set_si(cst, 0);
  2215. for (i = 0; i < bset->n_eq; ++i) {
  2216. isl_int_swap(bset->eq[i][offset], cst);
  2217. if (offset > 0) {
  2218. if (isl_tab_add_eq(tab, bset->eq[i] + offset) < 0)
  2219. goto error;
  2220. } else
  2221. tab = add_eq(tab, bset->eq[i]);
  2222. isl_int_swap(bset->eq[i][offset], cst);
  2223. if (!tab)
  2224. goto done;
  2225. }
  2226. for (i = 0; i < bset->n_ineq; ++i) {
  2227. int r;
  2228. isl_int_swap(bset->ineq[i][offset], cst);
  2229. r = isl_tab_add_row(tab, bset->ineq[i] + offset);
  2230. isl_int_swap(bset->ineq[i][offset], cst);
  2231. if (r < 0)
  2232. goto error;
  2233. tab->con[r].is_nonneg = 1;
  2234. if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
  2235. goto error;
  2236. }
  2237. done:
  2238. isl_int_clear(cst);
  2239. return tab;
  2240. error:
  2241. isl_int_clear(cst);
  2242. isl_tab_free(tab);
  2243. return NULL;
  2244. }
  2245. /* Assuming "tab" is the tableau of a cone, check if the cone is
  2246. * bounded, i.e., if it is empty or only contains the origin.
  2247. */
  2248. isl_bool isl_tab_cone_is_bounded(struct isl_tab *tab)
  2249. {
  2250. int i;
  2251. if (!tab)
  2252. return isl_bool_error;
  2253. if (tab->empty)
  2254. return isl_bool_true;
  2255. if (tab->n_dead == tab->n_col)
  2256. return isl_bool_true;
  2257. for (;;) {
  2258. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  2259. struct isl_tab_var *var;
  2260. int sgn;
  2261. var = isl_tab_var_from_row(tab, i);
  2262. if (!var->is_nonneg)
  2263. continue;
  2264. sgn = sign_of_max(tab, var);
  2265. if (sgn < -1)
  2266. return isl_bool_error;
  2267. if (sgn != 0)
  2268. return isl_bool_false;
  2269. if (close_row(tab, var, 0) < 0)
  2270. return isl_bool_error;
  2271. break;
  2272. }
  2273. if (tab->n_dead == tab->n_col)
  2274. return isl_bool_true;
  2275. if (i == tab->n_row)
  2276. return isl_bool_false;
  2277. }
  2278. }
  2279. int isl_tab_sample_is_integer(struct isl_tab *tab)
  2280. {
  2281. int i;
  2282. if (!tab)
  2283. return -1;
  2284. for (i = 0; i < tab->n_var; ++i) {
  2285. int row;
  2286. if (!tab->var[i].is_row)
  2287. continue;
  2288. row = tab->var[i].index;
  2289. if (!isl_int_is_divisible_by(tab->mat->row[row][1],
  2290. tab->mat->row[row][0]))
  2291. return 0;
  2292. }
  2293. return 1;
  2294. }
  2295. static struct isl_vec *extract_integer_sample(struct isl_tab *tab)
  2296. {
  2297. int i;
  2298. struct isl_vec *vec;
  2299. vec = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var);
  2300. if (!vec)
  2301. return NULL;
  2302. isl_int_set_si(vec->block.data[0], 1);
  2303. for (i = 0; i < tab->n_var; ++i) {
  2304. if (!tab->var[i].is_row)
  2305. isl_int_set_si(vec->block.data[1 + i], 0);
  2306. else {
  2307. int row = tab->var[i].index;
  2308. isl_int_divexact(vec->block.data[1 + i],
  2309. tab->mat->row[row][1], tab->mat->row[row][0]);
  2310. }
  2311. }
  2312. return vec;
  2313. }
  2314. __isl_give isl_vec *isl_tab_get_sample_value(struct isl_tab *tab)
  2315. {
  2316. int i;
  2317. struct isl_vec *vec;
  2318. isl_int m;
  2319. if (!tab)
  2320. return NULL;
  2321. vec = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var);
  2322. if (!vec)
  2323. return NULL;
  2324. isl_int_init(m);
  2325. isl_int_set_si(vec->block.data[0], 1);
  2326. for (i = 0; i < tab->n_var; ++i) {
  2327. int row;
  2328. if (!tab->var[i].is_row) {
  2329. isl_int_set_si(vec->block.data[1 + i], 0);
  2330. continue;
  2331. }
  2332. row = tab->var[i].index;
  2333. isl_int_gcd(m, vec->block.data[0], tab->mat->row[row][0]);
  2334. isl_int_divexact(m, tab->mat->row[row][0], m);
  2335. isl_seq_scale(vec->block.data, vec->block.data, m, 1 + i);
  2336. isl_int_divexact(m, vec->block.data[0], tab->mat->row[row][0]);
  2337. isl_int_mul(vec->block.data[1 + i], m, tab->mat->row[row][1]);
  2338. }
  2339. vec = isl_vec_normalize(vec);
  2340. isl_int_clear(m);
  2341. return vec;
  2342. }
  2343. /* Store the sample value of "var" of "tab" rounded up (if sgn > 0)
  2344. * or down (if sgn < 0) to the nearest integer in *v.
  2345. */
  2346. static void get_rounded_sample_value(struct isl_tab *tab,
  2347. struct isl_tab_var *var, int sgn, isl_int *v)
  2348. {
  2349. if (!var->is_row)
  2350. isl_int_set_si(*v, 0);
  2351. else if (sgn > 0)
  2352. isl_int_cdiv_q(*v, tab->mat->row[var->index][1],
  2353. tab->mat->row[var->index][0]);
  2354. else
  2355. isl_int_fdiv_q(*v, tab->mat->row[var->index][1],
  2356. tab->mat->row[var->index][0]);
  2357. }
  2358. /* Update "bmap" based on the results of the tableau "tab".
  2359. * In particular, implicit equalities are made explicit, redundant constraints
  2360. * are removed and if the sample value happens to be integer, it is stored
  2361. * in "bmap" (unless "bmap" already had an integer sample).
  2362. *
  2363. * The tableau is assumed to have been created from "bmap" using
  2364. * isl_tab_from_basic_map.
  2365. */
  2366. __isl_give isl_basic_map *isl_basic_map_update_from_tab(
  2367. __isl_take isl_basic_map *bmap, struct isl_tab *tab)
  2368. {
  2369. int i;
  2370. unsigned n_eq;
  2371. if (!bmap)
  2372. return NULL;
  2373. if (!tab)
  2374. return bmap;
  2375. n_eq = tab->n_eq;
  2376. if (tab->empty)
  2377. bmap = isl_basic_map_set_to_empty(bmap);
  2378. else
  2379. for (i = bmap->n_ineq - 1; i >= 0; --i) {
  2380. if (isl_tab_is_equality(tab, n_eq + i))
  2381. isl_basic_map_inequality_to_equality(bmap, i);
  2382. else if (isl_tab_is_redundant(tab, n_eq + i))
  2383. isl_basic_map_drop_inequality(bmap, i);
  2384. }
  2385. if (bmap->n_eq != n_eq)
  2386. bmap = isl_basic_map_gauss(bmap, NULL);
  2387. if (!tab->rational &&
  2388. bmap && !bmap->sample && isl_tab_sample_is_integer(tab))
  2389. bmap->sample = extract_integer_sample(tab);
  2390. return bmap;
  2391. }
  2392. __isl_give isl_basic_set *isl_basic_set_update_from_tab(
  2393. __isl_take isl_basic_set *bset, struct isl_tab *tab)
  2394. {
  2395. return bset_from_bmap(isl_basic_map_update_from_tab(bset_to_bmap(bset),
  2396. tab));
  2397. }
  2398. /* Drop the last constraint added to "tab" in position "r".
  2399. * The constraint is expected to have remained in a row.
  2400. */
  2401. static isl_stat drop_last_con_in_row(struct isl_tab *tab, int r)
  2402. {
  2403. if (!tab->con[r].is_row)
  2404. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  2405. "row unexpectedly moved to column",
  2406. return isl_stat_error);
  2407. if (r + 1 != tab->n_con)
  2408. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  2409. "additional constraints added", return isl_stat_error);
  2410. if (drop_row(tab, tab->con[r].index) < 0)
  2411. return isl_stat_error;
  2412. return isl_stat_ok;
  2413. }
  2414. /* Given a non-negative variable "var", temporarily add a new non-negative
  2415. * variable that is the opposite of "var", ensuring that "var" can only attain
  2416. * the value zero. The new variable is removed again before this function
  2417. * returns. However, the effect of forcing "var" to be zero remains.
  2418. * If var = n/d is a row variable, then the new variable = -n/d.
  2419. * If var is a column variables, then the new variable = -var.
  2420. * If the new variable cannot attain non-negative values, then
  2421. * the resulting tableau is empty.
  2422. * Otherwise, we know the value will be zero and we close the row.
  2423. */
  2424. static isl_stat cut_to_hyperplane(struct isl_tab *tab, struct isl_tab_var *var)
  2425. {
  2426. unsigned r;
  2427. isl_int *row;
  2428. int sgn;
  2429. unsigned off = 2 + tab->M;
  2430. if (var->is_zero)
  2431. return isl_stat_ok;
  2432. if (var->is_redundant || !var->is_nonneg)
  2433. isl_die(isl_tab_get_ctx(tab), isl_error_invalid,
  2434. "expecting non-redundant non-negative variable",
  2435. return isl_stat_error);
  2436. if (isl_tab_extend_cons(tab, 1) < 0)
  2437. return isl_stat_error;
  2438. r = tab->n_con;
  2439. tab->con[r].index = tab->n_row;
  2440. tab->con[r].is_row = 1;
  2441. tab->con[r].is_nonneg = 0;
  2442. tab->con[r].is_zero = 0;
  2443. tab->con[r].is_redundant = 0;
  2444. tab->con[r].frozen = 0;
  2445. tab->con[r].negated = 0;
  2446. tab->row_var[tab->n_row] = ~r;
  2447. row = tab->mat->row[tab->n_row];
  2448. if (var->is_row) {
  2449. isl_int_set(row[0], tab->mat->row[var->index][0]);
  2450. isl_seq_neg(row + 1,
  2451. tab->mat->row[var->index] + 1, 1 + tab->n_col);
  2452. } else {
  2453. isl_int_set_si(row[0], 1);
  2454. isl_seq_clr(row + 1, 1 + tab->n_col);
  2455. isl_int_set_si(row[off + var->index], -1);
  2456. }
  2457. tab->n_row++;
  2458. tab->n_con++;
  2459. sgn = sign_of_max(tab, &tab->con[r]);
  2460. if (sgn < -1)
  2461. return isl_stat_error;
  2462. if (sgn < 0) {
  2463. if (drop_last_con_in_row(tab, r) < 0)
  2464. return isl_stat_error;
  2465. if (isl_tab_mark_empty(tab) < 0)
  2466. return isl_stat_error;
  2467. return isl_stat_ok;
  2468. }
  2469. tab->con[r].is_nonneg = 1;
  2470. /* sgn == 0 */
  2471. if (close_row(tab, &tab->con[r], 1) < 0)
  2472. return isl_stat_error;
  2473. if (drop_last_con_in_row(tab, r) < 0)
  2474. return isl_stat_error;
  2475. return isl_stat_ok;
  2476. }
  2477. /* Check that "con" is a valid constraint position for "tab".
  2478. */
  2479. static isl_stat isl_tab_check_con(struct isl_tab *tab, int con)
  2480. {
  2481. if (!tab)
  2482. return isl_stat_error;
  2483. if (con < 0 || con >= tab->n_con)
  2484. isl_die(isl_tab_get_ctx(tab), isl_error_invalid,
  2485. "position out of bounds", return isl_stat_error);
  2486. return isl_stat_ok;
  2487. }
  2488. /* Given a tableau "tab" and an inequality constraint "con" of the tableau,
  2489. * relax the inequality by one. That is, the inequality r >= 0 is replaced
  2490. * by r' = r + 1 >= 0.
  2491. * If r is a row variable, we simply increase the constant term by one
  2492. * (taking into account the denominator).
  2493. * If r is a column variable, then we need to modify each row that
  2494. * refers to r = r' - 1 by substituting this equality, effectively
  2495. * subtracting the coefficient of the column from the constant.
  2496. * We should only do this if the minimum is manifestly unbounded,
  2497. * however. Otherwise, we may end up with negative sample values
  2498. * for non-negative variables.
  2499. * So, if r is a column variable with a minimum that is not
  2500. * manifestly unbounded, then we need to move it to a row.
  2501. * However, the sample value of this row may be negative,
  2502. * even after the relaxation, so we need to restore it.
  2503. * We therefore prefer to pivot a column up to a row, if possible.
  2504. */
  2505. int isl_tab_relax(struct isl_tab *tab, int con)
  2506. {
  2507. struct isl_tab_var *var;
  2508. if (!tab)
  2509. return -1;
  2510. var = &tab->con[con];
  2511. if (var->is_row && (var->index < 0 || var->index < tab->n_redundant))
  2512. isl_die(tab->mat->ctx, isl_error_invalid,
  2513. "cannot relax redundant constraint", return -1);
  2514. if (!var->is_row && (var->index < 0 || var->index < tab->n_dead))
  2515. isl_die(tab->mat->ctx, isl_error_invalid,
  2516. "cannot relax dead constraint", return -1);
  2517. if (!var->is_row && !max_is_manifestly_unbounded(tab, var))
  2518. if (to_row(tab, var, 1) < 0)
  2519. return -1;
  2520. if (!var->is_row && !min_is_manifestly_unbounded(tab, var))
  2521. if (to_row(tab, var, -1) < 0)
  2522. return -1;
  2523. if (var->is_row) {
  2524. isl_int_add(tab->mat->row[var->index][1],
  2525. tab->mat->row[var->index][1], tab->mat->row[var->index][0]);
  2526. if (restore_row(tab, var) < 0)
  2527. return -1;
  2528. } else {
  2529. int i;
  2530. unsigned off = 2 + tab->M;
  2531. for (i = 0; i < tab->n_row; ++i) {
  2532. if (isl_int_is_zero(tab->mat->row[i][off + var->index]))
  2533. continue;
  2534. isl_int_sub(tab->mat->row[i][1], tab->mat->row[i][1],
  2535. tab->mat->row[i][off + var->index]);
  2536. }
  2537. }
  2538. if (isl_tab_push_var(tab, isl_tab_undo_relax, var) < 0)
  2539. return -1;
  2540. return 0;
  2541. }
  2542. /* Replace the variable v at position "pos" in the tableau "tab"
  2543. * by v' = v + shift.
  2544. *
  2545. * If the variable is in a column, then we first check if we can
  2546. * simply plug in v = v' - shift. The effect on a row with
  2547. * coefficient f/d for variable v is that the constant term c/d
  2548. * is replaced by (c - f * shift)/d. If shift is positive and
  2549. * f is negative for each row that needs to remain non-negative,
  2550. * then this is clearly safe. In other words, if the minimum of v
  2551. * is manifestly unbounded, then we can keep v in a column position.
  2552. * Otherwise, we can pivot it down to a row.
  2553. * Similarly, if shift is negative, we need to check if the maximum
  2554. * of is manifestly unbounded.
  2555. *
  2556. * If the variable is in a row (from the start or after pivoting),
  2557. * then the constant term c/d is replaced by (c + d * shift)/d.
  2558. */
  2559. int isl_tab_shift_var(struct isl_tab *tab, int pos, isl_int shift)
  2560. {
  2561. struct isl_tab_var *var;
  2562. if (!tab)
  2563. return -1;
  2564. if (isl_int_is_zero(shift))
  2565. return 0;
  2566. var = &tab->var[pos];
  2567. if (!var->is_row) {
  2568. if (isl_int_is_neg(shift)) {
  2569. if (!max_is_manifestly_unbounded(tab, var))
  2570. if (to_row(tab, var, 1) < 0)
  2571. return -1;
  2572. } else {
  2573. if (!min_is_manifestly_unbounded(tab, var))
  2574. if (to_row(tab, var, -1) < 0)
  2575. return -1;
  2576. }
  2577. }
  2578. if (var->is_row) {
  2579. isl_int_addmul(tab->mat->row[var->index][1],
  2580. shift, tab->mat->row[var->index][0]);
  2581. } else {
  2582. int i;
  2583. unsigned off = 2 + tab->M;
  2584. for (i = 0; i < tab->n_row; ++i) {
  2585. if (isl_int_is_zero(tab->mat->row[i][off + var->index]))
  2586. continue;
  2587. isl_int_submul(tab->mat->row[i][1],
  2588. shift, tab->mat->row[i][off + var->index]);
  2589. }
  2590. }
  2591. return 0;
  2592. }
  2593. /* Remove the sign constraint from constraint "con".
  2594. *
  2595. * If the constraint variable was originally marked non-negative,
  2596. * then we make sure we mark it non-negative again during rollback.
  2597. */
  2598. int isl_tab_unrestrict(struct isl_tab *tab, int con)
  2599. {
  2600. struct isl_tab_var *var;
  2601. if (!tab)
  2602. return -1;
  2603. var = &tab->con[con];
  2604. if (!var->is_nonneg)
  2605. return 0;
  2606. var->is_nonneg = 0;
  2607. if (isl_tab_push_var(tab, isl_tab_undo_unrestrict, var) < 0)
  2608. return -1;
  2609. return 0;
  2610. }
  2611. int isl_tab_select_facet(struct isl_tab *tab, int con)
  2612. {
  2613. if (!tab)
  2614. return -1;
  2615. return cut_to_hyperplane(tab, &tab->con[con]);
  2616. }
  2617. static int may_be_equality(struct isl_tab *tab, int row)
  2618. {
  2619. return tab->rational ? isl_int_is_zero(tab->mat->row[row][1])
  2620. : isl_int_lt(tab->mat->row[row][1],
  2621. tab->mat->row[row][0]);
  2622. }
  2623. /* Return an isl_tab_var that has been marked or NULL if no such
  2624. * variable can be found.
  2625. * The marked field has only been set for variables that
  2626. * appear in non-redundant rows or non-dead columns.
  2627. *
  2628. * Pick the last constraint variable that is marked and
  2629. * that appears in either a non-redundant row or a non-dead columns.
  2630. * Since the returned variable is tested for being a redundant constraint or
  2631. * an implicit equality, there is no need to return any tab variable that
  2632. * corresponds to a variable.
  2633. */
  2634. static struct isl_tab_var *select_marked(struct isl_tab *tab)
  2635. {
  2636. int i;
  2637. struct isl_tab_var *var;
  2638. for (i = tab->n_con - 1; i >= 0; --i) {
  2639. var = &tab->con[i];
  2640. if (var->index < 0)
  2641. continue;
  2642. if (var->is_row && var->index < tab->n_redundant)
  2643. continue;
  2644. if (!var->is_row && var->index < tab->n_dead)
  2645. continue;
  2646. if (var->marked)
  2647. return var;
  2648. }
  2649. return NULL;
  2650. }
  2651. /* Check for (near) equalities among the constraints.
  2652. * A constraint is an equality if it is non-negative and if
  2653. * its maximal value is either
  2654. * - zero (in case of rational tableaus), or
  2655. * - strictly less than 1 (in case of integer tableaus)
  2656. *
  2657. * We first mark all non-redundant and non-dead variables that
  2658. * are not frozen and not obviously not an equality.
  2659. * Then we iterate over all marked variables if they can attain
  2660. * any values larger than zero or at least one.
  2661. * If the maximal value is zero, we mark any column variables
  2662. * that appear in the row as being zero and mark the row as being redundant.
  2663. * Otherwise, if the maximal value is strictly less than one (and the
  2664. * tableau is integer), then we restrict the value to being zero
  2665. * by adding an opposite non-negative variable.
  2666. * The order in which the variables are considered is not important.
  2667. */
  2668. int isl_tab_detect_implicit_equalities(struct isl_tab *tab)
  2669. {
  2670. int i;
  2671. unsigned n_marked;
  2672. if (!tab)
  2673. return -1;
  2674. if (tab->empty)
  2675. return 0;
  2676. if (tab->n_dead == tab->n_col)
  2677. return 0;
  2678. n_marked = 0;
  2679. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  2680. struct isl_tab_var *var = isl_tab_var_from_row(tab, i);
  2681. var->marked = !var->frozen && var->is_nonneg &&
  2682. may_be_equality(tab, i);
  2683. if (var->marked)
  2684. n_marked++;
  2685. }
  2686. for (i = tab->n_dead; i < tab->n_col; ++i) {
  2687. struct isl_tab_var *var = var_from_col(tab, i);
  2688. var->marked = !var->frozen && var->is_nonneg;
  2689. if (var->marked)
  2690. n_marked++;
  2691. }
  2692. while (n_marked) {
  2693. struct isl_tab_var *var;
  2694. int sgn;
  2695. var = select_marked(tab);
  2696. if (!var)
  2697. break;
  2698. var->marked = 0;
  2699. n_marked--;
  2700. sgn = sign_of_max(tab, var);
  2701. if (sgn < 0)
  2702. return -1;
  2703. if (sgn == 0) {
  2704. if (close_row(tab, var, 0) < 0)
  2705. return -1;
  2706. } else if (!tab->rational && !at_least_one(tab, var)) {
  2707. if (cut_to_hyperplane(tab, var) < 0)
  2708. return -1;
  2709. return isl_tab_detect_implicit_equalities(tab);
  2710. }
  2711. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  2712. var = isl_tab_var_from_row(tab, i);
  2713. if (!var->marked)
  2714. continue;
  2715. if (may_be_equality(tab, i))
  2716. continue;
  2717. var->marked = 0;
  2718. n_marked--;
  2719. }
  2720. }
  2721. return 0;
  2722. }
  2723. /* Update the element of row_var or col_var that corresponds to
  2724. * constraint tab->con[i] to a move from position "old" to position "i".
  2725. */
  2726. static int update_con_after_move(struct isl_tab *tab, int i, int old)
  2727. {
  2728. int *p;
  2729. int index;
  2730. index = tab->con[i].index;
  2731. if (index == -1)
  2732. return 0;
  2733. p = tab->con[i].is_row ? tab->row_var : tab->col_var;
  2734. if (p[index] != ~old)
  2735. isl_die(tab->mat->ctx, isl_error_internal,
  2736. "broken internal state", return -1);
  2737. p[index] = ~i;
  2738. return 0;
  2739. }
  2740. /* Interchange constraints "con1" and "con2" in "tab".
  2741. * In particular, interchange the contents of these entries in tab->con.
  2742. * Since tab->col_var and tab->row_var point back into this array,
  2743. * they need to be updated accordingly.
  2744. */
  2745. isl_stat isl_tab_swap_constraints(struct isl_tab *tab, int con1, int con2)
  2746. {
  2747. struct isl_tab_var var;
  2748. if (isl_tab_check_con(tab, con1) < 0 ||
  2749. isl_tab_check_con(tab, con2) < 0)
  2750. return isl_stat_error;
  2751. var = tab->con[con1];
  2752. tab->con[con1] = tab->con[con2];
  2753. if (update_con_after_move(tab, con1, con2) < 0)
  2754. return isl_stat_error;
  2755. tab->con[con2] = var;
  2756. if (update_con_after_move(tab, con2, con1) < 0)
  2757. return isl_stat_error;
  2758. return isl_stat_ok;
  2759. }
  2760. /* Rotate the "n" constraints starting at "first" to the right,
  2761. * putting the last constraint in the position of the first constraint.
  2762. */
  2763. static int rotate_constraints(struct isl_tab *tab, int first, int n)
  2764. {
  2765. int i, last;
  2766. struct isl_tab_var var;
  2767. if (n <= 1)
  2768. return 0;
  2769. last = first + n - 1;
  2770. var = tab->con[last];
  2771. for (i = last; i > first; --i) {
  2772. tab->con[i] = tab->con[i - 1];
  2773. if (update_con_after_move(tab, i, i - 1) < 0)
  2774. return -1;
  2775. }
  2776. tab->con[first] = var;
  2777. if (update_con_after_move(tab, first, last) < 0)
  2778. return -1;
  2779. return 0;
  2780. }
  2781. /* Drop the "n" entries starting at position "first" in tab->con, moving all
  2782. * subsequent entries down.
  2783. * Since some of the entries of tab->row_var and tab->col_var contain
  2784. * indices into this array, they have to be updated accordingly.
  2785. */
  2786. static isl_stat con_drop_entries(struct isl_tab *tab,
  2787. unsigned first, unsigned n)
  2788. {
  2789. int i;
  2790. if (first + n > tab->n_con || first + n < first)
  2791. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  2792. "invalid range", return isl_stat_error);
  2793. tab->n_con -= n;
  2794. for (i = first; i < tab->n_con; ++i) {
  2795. tab->con[i] = tab->con[i + n];
  2796. if (update_con_after_move(tab, i, i + n) < 0)
  2797. return isl_stat_error;
  2798. }
  2799. return isl_stat_ok;
  2800. }
  2801. /* isl_basic_map_gauss5 callback that gets called when
  2802. * two (equality) constraints "a" and "b" get interchanged
  2803. * in the basic map. Perform the same interchange in "tab".
  2804. */
  2805. static isl_stat swap_eq(unsigned a, unsigned b, void *user)
  2806. {
  2807. struct isl_tab *tab = user;
  2808. return isl_tab_swap_constraints(tab, a, b);
  2809. }
  2810. /* isl_basic_map_gauss5 callback that gets called when
  2811. * the final "n" equality constraints get removed.
  2812. * As a special case, if "n" is equal to the total number
  2813. * of equality constraints, then this means the basic map
  2814. * turned out to be empty.
  2815. * Drop the same number of equality constraints from "tab" or
  2816. * mark it empty in the special case.
  2817. */
  2818. static isl_stat drop_eq(unsigned n, void *user)
  2819. {
  2820. struct isl_tab *tab = user;
  2821. if (tab->n_eq == n)
  2822. return isl_tab_mark_empty(tab);
  2823. tab->n_eq -= n;
  2824. return con_drop_entries(tab, tab->n_eq, n);
  2825. }
  2826. /* If "bmap" has more than a single reference, then call
  2827. * isl_basic_map_gauss on it, updating "tab" accordingly.
  2828. */
  2829. static __isl_give isl_basic_map *gauss_if_shared(__isl_take isl_basic_map *bmap,
  2830. struct isl_tab *tab)
  2831. {
  2832. isl_bool single;
  2833. single = isl_basic_map_has_single_reference(bmap);
  2834. if (single < 0)
  2835. return isl_basic_map_free(bmap);
  2836. if (single)
  2837. return bmap;
  2838. return isl_basic_map_gauss5(bmap, NULL, &swap_eq, &drop_eq, tab);
  2839. }
  2840. /* Make the equalities that are implicit in "bmap" but that have been
  2841. * detected in the corresponding "tab" explicit in "bmap" and update
  2842. * "tab" to reflect the new order of the constraints.
  2843. *
  2844. * In particular, if inequality i is an implicit equality then
  2845. * isl_basic_map_inequality_to_equality will move the inequality
  2846. * in front of the other equality and it will move the last inequality
  2847. * in the position of inequality i.
  2848. * In the tableau, the inequalities of "bmap" are stored after the equalities
  2849. * and so the original order
  2850. *
  2851. * E E E E E A A A I B B B B L
  2852. *
  2853. * is changed into
  2854. *
  2855. * I E E E E E A A A L B B B B
  2856. *
  2857. * where I is the implicit equality, the E are equalities,
  2858. * the A inequalities before I, the B inequalities after I and
  2859. * L the last inequality.
  2860. * We therefore need to rotate to the right two sets of constraints,
  2861. * those up to and including I and those after I.
  2862. *
  2863. * If "tab" contains any constraints that are not in "bmap" then they
  2864. * appear after those in "bmap" and they should be left untouched.
  2865. *
  2866. * Note that this function only calls isl_basic_map_gauss
  2867. * (in case some equality constraints got detected)
  2868. * if "bmap" has more than one reference.
  2869. * If it only has a single reference, then it is left in a temporary state,
  2870. * because the caller may require this state.
  2871. * Calling isl_basic_map_gauss is then the responsibility of the caller.
  2872. */
  2873. __isl_give isl_basic_map *isl_tab_make_equalities_explicit(struct isl_tab *tab,
  2874. __isl_take isl_basic_map *bmap)
  2875. {
  2876. int i;
  2877. unsigned n_eq;
  2878. if (!tab || !bmap)
  2879. return isl_basic_map_free(bmap);
  2880. if (tab->empty)
  2881. return bmap;
  2882. n_eq = tab->n_eq;
  2883. for (i = bmap->n_ineq - 1; i >= 0; --i) {
  2884. if (!isl_tab_is_equality(tab, bmap->n_eq + i))
  2885. continue;
  2886. isl_basic_map_inequality_to_equality(bmap, i);
  2887. if (rotate_constraints(tab, 0, tab->n_eq + i + 1) < 0)
  2888. return isl_basic_map_free(bmap);
  2889. if (rotate_constraints(tab, tab->n_eq + i + 1,
  2890. bmap->n_ineq - i) < 0)
  2891. return isl_basic_map_free(bmap);
  2892. tab->n_eq++;
  2893. }
  2894. if (n_eq != tab->n_eq)
  2895. bmap = gauss_if_shared(bmap, tab);
  2896. return bmap;
  2897. }
  2898. static int con_is_redundant(struct isl_tab *tab, struct isl_tab_var *var)
  2899. {
  2900. if (!tab)
  2901. return -1;
  2902. if (tab->rational) {
  2903. int sgn = sign_of_min(tab, var);
  2904. if (sgn < -1)
  2905. return -1;
  2906. return sgn >= 0;
  2907. } else {
  2908. int irred = isl_tab_min_at_most_neg_one(tab, var);
  2909. if (irred < 0)
  2910. return -1;
  2911. return !irred;
  2912. }
  2913. }
  2914. /* Check for (near) redundant constraints.
  2915. * A constraint is redundant if it is non-negative and if
  2916. * its minimal value (temporarily ignoring the non-negativity) is either
  2917. * - zero (in case of rational tableaus), or
  2918. * - strictly larger than -1 (in case of integer tableaus)
  2919. *
  2920. * We first mark all non-redundant and non-dead variables that
  2921. * are not frozen and not obviously negatively unbounded.
  2922. * Then we iterate over all marked variables if they can attain
  2923. * any values smaller than zero or at most negative one.
  2924. * If not, we mark the row as being redundant (assuming it hasn't
  2925. * been detected as being obviously redundant in the mean time).
  2926. */
  2927. int isl_tab_detect_redundant(struct isl_tab *tab)
  2928. {
  2929. int i;
  2930. unsigned n_marked;
  2931. if (!tab)
  2932. return -1;
  2933. if (tab->empty)
  2934. return 0;
  2935. if (tab->n_redundant == tab->n_row)
  2936. return 0;
  2937. n_marked = 0;
  2938. for (i = tab->n_redundant; i < tab->n_row; ++i) {
  2939. struct isl_tab_var *var = isl_tab_var_from_row(tab, i);
  2940. var->marked = !var->frozen && var->is_nonneg;
  2941. if (var->marked)
  2942. n_marked++;
  2943. }
  2944. for (i = tab->n_dead; i < tab->n_col; ++i) {
  2945. struct isl_tab_var *var = var_from_col(tab, i);
  2946. var->marked = !var->frozen && var->is_nonneg &&
  2947. !min_is_manifestly_unbounded(tab, var);
  2948. if (var->marked)
  2949. n_marked++;
  2950. }
  2951. while (n_marked) {
  2952. struct isl_tab_var *var;
  2953. int red;
  2954. var = select_marked(tab);
  2955. if (!var)
  2956. break;
  2957. var->marked = 0;
  2958. n_marked--;
  2959. red = con_is_redundant(tab, var);
  2960. if (red < 0)
  2961. return -1;
  2962. if (red && !var->is_redundant)
  2963. if (isl_tab_mark_redundant(tab, var->index) < 0)
  2964. return -1;
  2965. for (i = tab->n_dead; i < tab->n_col; ++i) {
  2966. var = var_from_col(tab, i);
  2967. if (!var->marked)
  2968. continue;
  2969. if (!min_is_manifestly_unbounded(tab, var))
  2970. continue;
  2971. var->marked = 0;
  2972. n_marked--;
  2973. }
  2974. }
  2975. return 0;
  2976. }
  2977. int isl_tab_is_equality(struct isl_tab *tab, int con)
  2978. {
  2979. int row;
  2980. unsigned off;
  2981. if (!tab)
  2982. return -1;
  2983. if (tab->con[con].is_zero)
  2984. return 1;
  2985. if (tab->con[con].is_redundant)
  2986. return 0;
  2987. if (!tab->con[con].is_row)
  2988. return tab->con[con].index < tab->n_dead;
  2989. row = tab->con[con].index;
  2990. off = 2 + tab->M;
  2991. return isl_int_is_zero(tab->mat->row[row][1]) &&
  2992. !row_is_big(tab, row) &&
  2993. isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
  2994. tab->n_col - tab->n_dead) == -1;
  2995. }
  2996. /* Return the minimal value of the affine expression "f" with denominator
  2997. * "denom" in *opt, *opt_denom, assuming the tableau is not empty and
  2998. * the expression cannot attain arbitrarily small values.
  2999. * If opt_denom is NULL, then *opt is rounded up to the nearest integer.
  3000. * The return value reflects the nature of the result (empty, unbounded,
  3001. * minimal value returned in *opt).
  3002. *
  3003. * This function assumes that at least one more row and at least
  3004. * one more element in the constraint array are available in the tableau.
  3005. */
  3006. enum isl_lp_result isl_tab_min(struct isl_tab *tab,
  3007. isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom,
  3008. unsigned flags)
  3009. {
  3010. int r;
  3011. enum isl_lp_result res = isl_lp_ok;
  3012. struct isl_tab_var *var;
  3013. struct isl_tab_undo *snap;
  3014. if (!tab)
  3015. return isl_lp_error;
  3016. if (tab->empty)
  3017. return isl_lp_empty;
  3018. snap = isl_tab_snap(tab);
  3019. r = isl_tab_add_row(tab, f);
  3020. if (r < 0)
  3021. return isl_lp_error;
  3022. var = &tab->con[r];
  3023. for (;;) {
  3024. int row, col;
  3025. find_pivot(tab, var, var, -1, &row, &col);
  3026. if (row == var->index) {
  3027. res = isl_lp_unbounded;
  3028. break;
  3029. }
  3030. if (row == -1)
  3031. break;
  3032. if (isl_tab_pivot(tab, row, col) < 0)
  3033. return isl_lp_error;
  3034. }
  3035. isl_int_mul(tab->mat->row[var->index][0],
  3036. tab->mat->row[var->index][0], denom);
  3037. if (ISL_FL_ISSET(flags, ISL_TAB_SAVE_DUAL)) {
  3038. int i;
  3039. isl_vec_free(tab->dual);
  3040. tab->dual = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_con);
  3041. if (!tab->dual)
  3042. return isl_lp_error;
  3043. isl_int_set(tab->dual->el[0], tab->mat->row[var->index][0]);
  3044. for (i = 0; i < tab->n_con; ++i) {
  3045. int pos;
  3046. if (tab->con[i].is_row) {
  3047. isl_int_set_si(tab->dual->el[1 + i], 0);
  3048. continue;
  3049. }
  3050. pos = 2 + tab->M + tab->con[i].index;
  3051. if (tab->con[i].negated)
  3052. isl_int_neg(tab->dual->el[1 + i],
  3053. tab->mat->row[var->index][pos]);
  3054. else
  3055. isl_int_set(tab->dual->el[1 + i],
  3056. tab->mat->row[var->index][pos]);
  3057. }
  3058. }
  3059. if (opt && res == isl_lp_ok) {
  3060. if (opt_denom) {
  3061. isl_int_set(*opt, tab->mat->row[var->index][1]);
  3062. isl_int_set(*opt_denom, tab->mat->row[var->index][0]);
  3063. } else
  3064. get_rounded_sample_value(tab, var, 1, opt);
  3065. }
  3066. if (isl_tab_rollback(tab, snap) < 0)
  3067. return isl_lp_error;
  3068. return res;
  3069. }
  3070. /* Is the constraint at position "con" marked as being redundant?
  3071. * If it is marked as representing an equality, then it is not
  3072. * considered to be redundant.
  3073. * Note that isl_tab_mark_redundant marks both the isl_tab_var as
  3074. * redundant and moves the corresponding row into the first
  3075. * tab->n_redundant positions (or removes the row, assigning it index -1),
  3076. * so the final test is actually redundant itself.
  3077. */
  3078. int isl_tab_is_redundant(struct isl_tab *tab, int con)
  3079. {
  3080. if (isl_tab_check_con(tab, con) < 0)
  3081. return -1;
  3082. if (tab->con[con].is_zero)
  3083. return 0;
  3084. if (tab->con[con].is_redundant)
  3085. return 1;
  3086. return tab->con[con].is_row && tab->con[con].index < tab->n_redundant;
  3087. }
  3088. /* Is variable "var" of "tab" fixed to a constant value by its row
  3089. * in the tableau?
  3090. * If so and if "value" is not NULL, then store this constant value
  3091. * in "value".
  3092. *
  3093. * That is, is it a row variable that only has non-zero coefficients
  3094. * for dead columns?
  3095. */
  3096. static isl_bool is_constant(struct isl_tab *tab, struct isl_tab_var *var,
  3097. isl_int *value)
  3098. {
  3099. unsigned off = 2 + tab->M;
  3100. isl_mat *mat = tab->mat;
  3101. int n;
  3102. int row;
  3103. int pos;
  3104. if (!var->is_row)
  3105. return isl_bool_false;
  3106. row = var->index;
  3107. if (row_is_big(tab, row))
  3108. return isl_bool_false;
  3109. n = tab->n_col - tab->n_dead;
  3110. pos = isl_seq_first_non_zero(mat->row[row] + off + tab->n_dead, n);
  3111. if (pos != -1)
  3112. return isl_bool_false;
  3113. if (value)
  3114. isl_int_divexact(*value, mat->row[row][1], mat->row[row][0]);
  3115. return isl_bool_true;
  3116. }
  3117. /* Has the variable "var' of "tab" reached a value that is greater than
  3118. * or equal (if sgn > 0) or smaller than or equal (if sgn < 0) to "target"?
  3119. * "tmp" has been initialized by the caller and can be used
  3120. * to perform local computations.
  3121. *
  3122. * If the sample value involves the big parameter, then any value
  3123. * is reached.
  3124. * Otherwise check if n/d >= t, i.e., n >= d * t (if sgn > 0)
  3125. * or n/d <= t, i.e., n <= d * t (if sgn < 0).
  3126. */
  3127. static int reached(struct isl_tab *tab, struct isl_tab_var *var, int sgn,
  3128. isl_int target, isl_int *tmp)
  3129. {
  3130. if (row_is_big(tab, var->index))
  3131. return 1;
  3132. isl_int_mul(*tmp, tab->mat->row[var->index][0], target);
  3133. if (sgn > 0)
  3134. return isl_int_ge(tab->mat->row[var->index][1], *tmp);
  3135. else
  3136. return isl_int_le(tab->mat->row[var->index][1], *tmp);
  3137. }
  3138. /* Can variable "var" of "tab" attain the value "target" by
  3139. * pivoting up (if sgn > 0) or down (if sgn < 0)?
  3140. * If not, then pivot up [down] to the greatest [smallest]
  3141. * rational value.
  3142. * "tmp" has been initialized by the caller and can be used
  3143. * to perform local computations.
  3144. *
  3145. * If the variable is manifestly unbounded in the desired direction,
  3146. * then it can attain any value.
  3147. * Otherwise, it can be moved to a row.
  3148. * Continue pivoting until the target is reached.
  3149. * If no more pivoting can be performed, the maximal [minimal]
  3150. * rational value has been reached and the target cannot be reached.
  3151. * If the variable would be pivoted into a manifestly unbounded column,
  3152. * then the target can be reached.
  3153. */
  3154. static isl_bool var_reaches(struct isl_tab *tab, struct isl_tab_var *var,
  3155. int sgn, isl_int target, isl_int *tmp)
  3156. {
  3157. int row, col;
  3158. if (sgn < 0 && min_is_manifestly_unbounded(tab, var))
  3159. return isl_bool_true;
  3160. if (sgn > 0 && max_is_manifestly_unbounded(tab, var))
  3161. return isl_bool_true;
  3162. if (to_row(tab, var, sgn) < 0)
  3163. return isl_bool_error;
  3164. while (!reached(tab, var, sgn, target, tmp)) {
  3165. find_pivot(tab, var, var, sgn, &row, &col);
  3166. if (row == -1)
  3167. return isl_bool_false;
  3168. if (row == var->index)
  3169. return isl_bool_true;
  3170. if (isl_tab_pivot(tab, row, col) < 0)
  3171. return isl_bool_error;
  3172. }
  3173. return isl_bool_true;
  3174. }
  3175. /* Check if variable "var" of "tab" can only attain a single (integer)
  3176. * value, and, if so, add an equality constraint to fix the variable
  3177. * to this single value and store the result in "target".
  3178. * "target" and "tmp" have been initialized by the caller.
  3179. *
  3180. * Given the current sample value, round it down and check
  3181. * whether it is possible to attain a strictly smaller integer value.
  3182. * If so, the variable is not restricted to a single integer value.
  3183. * Otherwise, the search stops at the smallest rational value.
  3184. * Round up this value and check whether it is possible to attain
  3185. * a strictly greater integer value.
  3186. * If so, the variable is not restricted to a single integer value.
  3187. * Otherwise, the search stops at the greatest rational value.
  3188. * If rounding down this value yields a value that is different
  3189. * from rounding up the smallest rational value, then the variable
  3190. * cannot attain any integer value. Mark the tableau empty.
  3191. * Otherwise, add an equality constraint that fixes the variable
  3192. * to the single integer value found.
  3193. */
  3194. static isl_bool detect_constant_with_tmp(struct isl_tab *tab,
  3195. struct isl_tab_var *var, isl_int *target, isl_int *tmp)
  3196. {
  3197. isl_bool reached;
  3198. isl_vec *eq;
  3199. int pos;
  3200. isl_stat r;
  3201. get_rounded_sample_value(tab, var, -1, target);
  3202. isl_int_sub_ui(*target, *target, 1);
  3203. reached = var_reaches(tab, var, -1, *target, tmp);
  3204. if (reached < 0 || reached)
  3205. return isl_bool_not(reached);
  3206. get_rounded_sample_value(tab, var, 1, target);
  3207. isl_int_add_ui(*target, *target, 1);
  3208. reached = var_reaches(tab, var, 1, *target, tmp);
  3209. if (reached < 0 || reached)
  3210. return isl_bool_not(reached);
  3211. get_rounded_sample_value(tab, var, -1, tmp);
  3212. isl_int_sub_ui(*target, *target, 1);
  3213. if (isl_int_ne(*target, *tmp)) {
  3214. if (isl_tab_mark_empty(tab) < 0)
  3215. return isl_bool_error;
  3216. return isl_bool_false;
  3217. }
  3218. if (isl_tab_extend_cons(tab, 1) < 0)
  3219. return isl_bool_error;
  3220. eq = isl_vec_alloc(isl_tab_get_ctx(tab), 1 + tab->n_var);
  3221. if (!eq)
  3222. return isl_bool_error;
  3223. pos = var - tab->var;
  3224. isl_seq_clr(eq->el + 1, tab->n_var);
  3225. isl_int_set_si(eq->el[1 + pos], -1);
  3226. isl_int_set(eq->el[0], *target);
  3227. r = isl_tab_add_eq(tab, eq->el);
  3228. isl_vec_free(eq);
  3229. return r < 0 ? isl_bool_error : isl_bool_true;
  3230. }
  3231. /* Check if variable "var" of "tab" can only attain a single (integer)
  3232. * value, and, if so, add an equality constraint to fix the variable
  3233. * to this single value and store the result in "value" (if "value"
  3234. * is not NULL).
  3235. *
  3236. * If the current sample value involves the big parameter,
  3237. * then the variable cannot have a fixed integer value.
  3238. * If the variable is already fixed to a single value by its row, then
  3239. * there is no need to add another equality constraint.
  3240. *
  3241. * Otherwise, allocate some temporary variables and continue
  3242. * with detect_constant_with_tmp.
  3243. */
  3244. static isl_bool get_constant(struct isl_tab *tab, struct isl_tab_var *var,
  3245. isl_int *value)
  3246. {
  3247. isl_int target, tmp;
  3248. isl_bool is_cst;
  3249. if (var->is_row && row_is_big(tab, var->index))
  3250. return isl_bool_false;
  3251. is_cst = is_constant(tab, var, value);
  3252. if (is_cst < 0 || is_cst)
  3253. return is_cst;
  3254. if (!value)
  3255. isl_int_init(target);
  3256. isl_int_init(tmp);
  3257. is_cst = detect_constant_with_tmp(tab, var,
  3258. value ? value : &target, &tmp);
  3259. isl_int_clear(tmp);
  3260. if (!value)
  3261. isl_int_clear(target);
  3262. return is_cst;
  3263. }
  3264. /* Check if variable "var" of "tab" can only attain a single (integer)
  3265. * value, and, if so, add an equality constraint to fix the variable
  3266. * to this single value and store the result in "value" (if "value"
  3267. * is not NULL).
  3268. *
  3269. * For rational tableaus, nothing needs to be done.
  3270. */
  3271. isl_bool isl_tab_is_constant(struct isl_tab *tab, int var, isl_int *value)
  3272. {
  3273. if (!tab)
  3274. return isl_bool_error;
  3275. if (var < 0 || var >= tab->n_var)
  3276. isl_die(isl_tab_get_ctx(tab), isl_error_invalid,
  3277. "position out of bounds", return isl_bool_error);
  3278. if (tab->rational)
  3279. return isl_bool_false;
  3280. return get_constant(tab, &tab->var[var], value);
  3281. }
  3282. /* Check if any of the variables of "tab" can only attain a single (integer)
  3283. * value, and, if so, add equality constraints to fix those variables
  3284. * to these single values.
  3285. *
  3286. * For rational tableaus, nothing needs to be done.
  3287. */
  3288. isl_stat isl_tab_detect_constants(struct isl_tab *tab)
  3289. {
  3290. int i;
  3291. if (!tab)
  3292. return isl_stat_error;
  3293. if (tab->rational)
  3294. return isl_stat_ok;
  3295. for (i = 0; i < tab->n_var; ++i) {
  3296. if (get_constant(tab, &tab->var[i], NULL) < 0)
  3297. return isl_stat_error;
  3298. }
  3299. return isl_stat_ok;
  3300. }
  3301. /* Take a snapshot of the tableau that can be restored by a call to
  3302. * isl_tab_rollback.
  3303. */
  3304. struct isl_tab_undo *isl_tab_snap(struct isl_tab *tab)
  3305. {
  3306. if (!tab)
  3307. return NULL;
  3308. tab->need_undo = 1;
  3309. return tab->top;
  3310. }
  3311. /* Does "tab" need to keep track of undo information?
  3312. * That is, was a snapshot taken that may need to be restored?
  3313. */
  3314. isl_bool isl_tab_need_undo(struct isl_tab *tab)
  3315. {
  3316. if (!tab)
  3317. return isl_bool_error;
  3318. return isl_bool_ok(tab->need_undo);
  3319. }
  3320. /* Remove all tracking of undo information from "tab", invalidating
  3321. * any snapshots that may have been taken of the tableau.
  3322. * Since all snapshots have been invalidated, there is also
  3323. * no need to start keeping track of undo information again.
  3324. */
  3325. void isl_tab_clear_undo(struct isl_tab *tab)
  3326. {
  3327. if (!tab)
  3328. return;
  3329. free_undo(tab);
  3330. tab->need_undo = 0;
  3331. }
  3332. /* Undo the operation performed by isl_tab_relax.
  3333. */
  3334. static isl_stat unrelax(struct isl_tab *tab, struct isl_tab_var *var)
  3335. WARN_UNUSED;
  3336. static isl_stat unrelax(struct isl_tab *tab, struct isl_tab_var *var)
  3337. {
  3338. unsigned off = 2 + tab->M;
  3339. if (!var->is_row && !max_is_manifestly_unbounded(tab, var))
  3340. if (to_row(tab, var, 1) < 0)
  3341. return isl_stat_error;
  3342. if (var->is_row) {
  3343. isl_int_sub(tab->mat->row[var->index][1],
  3344. tab->mat->row[var->index][1], tab->mat->row[var->index][0]);
  3345. if (var->is_nonneg) {
  3346. int sgn = restore_row(tab, var);
  3347. isl_assert(tab->mat->ctx, sgn >= 0,
  3348. return isl_stat_error);
  3349. }
  3350. } else {
  3351. int i;
  3352. for (i = 0; i < tab->n_row; ++i) {
  3353. if (isl_int_is_zero(tab->mat->row[i][off + var->index]))
  3354. continue;
  3355. isl_int_add(tab->mat->row[i][1], tab->mat->row[i][1],
  3356. tab->mat->row[i][off + var->index]);
  3357. }
  3358. }
  3359. return isl_stat_ok;
  3360. }
  3361. /* Undo the operation performed by isl_tab_unrestrict.
  3362. *
  3363. * In particular, mark the variable as being non-negative and make
  3364. * sure the sample value respects this constraint.
  3365. */
  3366. static isl_stat ununrestrict(struct isl_tab *tab, struct isl_tab_var *var)
  3367. {
  3368. var->is_nonneg = 1;
  3369. if (var->is_row && restore_row(tab, var) < -1)
  3370. return isl_stat_error;
  3371. return isl_stat_ok;
  3372. }
  3373. /* Unmark the last redundant row in "tab" as being redundant.
  3374. * This undoes part of the modifications performed by isl_tab_mark_redundant.
  3375. * In particular, remove the redundant mark and make
  3376. * sure the sample value respects the constraint again.
  3377. * A variable that is marked non-negative by isl_tab_mark_redundant
  3378. * is covered by a separate undo record.
  3379. */
  3380. static isl_stat restore_last_redundant(struct isl_tab *tab)
  3381. {
  3382. struct isl_tab_var *var;
  3383. if (tab->n_redundant < 1)
  3384. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  3385. "no redundant rows", return isl_stat_error);
  3386. var = isl_tab_var_from_row(tab, tab->n_redundant - 1);
  3387. var->is_redundant = 0;
  3388. tab->n_redundant--;
  3389. restore_row(tab, var);
  3390. return isl_stat_ok;
  3391. }
  3392. static isl_stat perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo)
  3393. WARN_UNUSED;
  3394. static isl_stat perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo)
  3395. {
  3396. struct isl_tab_var *var = var_from_index(tab, undo->u.var_index);
  3397. switch (undo->type) {
  3398. case isl_tab_undo_nonneg:
  3399. var->is_nonneg = 0;
  3400. break;
  3401. case isl_tab_undo_redundant:
  3402. if (!var->is_row || var->index != tab->n_redundant - 1)
  3403. isl_die(isl_tab_get_ctx(tab), isl_error_internal,
  3404. "not undoing last redundant row",
  3405. return isl_stat_error);
  3406. return restore_last_redundant(tab);
  3407. case isl_tab_undo_freeze:
  3408. var->frozen = 0;
  3409. break;
  3410. case isl_tab_undo_zero:
  3411. var->is_zero = 0;
  3412. if (!var->is_row)
  3413. tab->n_dead--;
  3414. break;
  3415. case isl_tab_undo_allocate:
  3416. if (undo->u.var_index >= 0) {
  3417. isl_assert(tab->mat->ctx, !var->is_row,
  3418. return isl_stat_error);
  3419. return drop_col(tab, var->index);
  3420. }
  3421. if (!var->is_row) {
  3422. if (!max_is_manifestly_unbounded(tab, var)) {
  3423. if (to_row(tab, var, 1) < 0)
  3424. return isl_stat_error;
  3425. } else if (!min_is_manifestly_unbounded(tab, var)) {
  3426. if (to_row(tab, var, -1) < 0)
  3427. return isl_stat_error;
  3428. } else
  3429. if (to_row(tab, var, 0) < 0)
  3430. return isl_stat_error;
  3431. }
  3432. return drop_row(tab, var->index);
  3433. case isl_tab_undo_relax:
  3434. return unrelax(tab, var);
  3435. case isl_tab_undo_unrestrict:
  3436. return ununrestrict(tab, var);
  3437. default:
  3438. isl_die(tab->mat->ctx, isl_error_internal,
  3439. "perform_undo_var called on invalid undo record",
  3440. return isl_stat_error);
  3441. }
  3442. return isl_stat_ok;
  3443. }
  3444. /* Restore all rows that have been marked redundant by isl_tab_mark_redundant
  3445. * and that have been preserved in the tableau.
  3446. * Note that isl_tab_mark_redundant may also have marked some variables
  3447. * as being non-negative before marking them redundant. These need
  3448. * to be removed as well as otherwise some constraints could end up
  3449. * getting marked redundant with respect to the variable.
  3450. */
  3451. isl_stat isl_tab_restore_redundant(struct isl_tab *tab)
  3452. {
  3453. if (!tab)
  3454. return isl_stat_error;
  3455. if (tab->need_undo)
  3456. isl_die(isl_tab_get_ctx(tab), isl_error_invalid,
  3457. "manually restoring redundant constraints "
  3458. "interferes with undo history",
  3459. return isl_stat_error);
  3460. while (tab->n_redundant > 0) {
  3461. if (tab->row_var[tab->n_redundant - 1] >= 0) {
  3462. struct isl_tab_var *var;
  3463. var = isl_tab_var_from_row(tab, tab->n_redundant - 1);
  3464. var->is_nonneg = 0;
  3465. }
  3466. restore_last_redundant(tab);
  3467. }
  3468. return isl_stat_ok;
  3469. }
  3470. /* Undo the addition of an integer division to the basic map representation
  3471. * of "tab" in position "pos".
  3472. */
  3473. static isl_stat drop_bmap_div(struct isl_tab *tab, int pos)
  3474. {
  3475. int off;
  3476. isl_size n_div;
  3477. n_div = isl_basic_map_dim(tab->bmap, isl_dim_div);
  3478. if (n_div < 0)
  3479. return isl_stat_error;
  3480. off = tab->n_var - n_div;
  3481. tab->bmap = isl_basic_map_drop_div(tab->bmap, pos - off);
  3482. if (!tab->bmap)
  3483. return isl_stat_error;
  3484. if (tab->samples) {
  3485. tab->samples = isl_mat_drop_cols(tab->samples, 1 + pos, 1);
  3486. if (!tab->samples)
  3487. return isl_stat_error;
  3488. }
  3489. return isl_stat_ok;
  3490. }
  3491. /* Restore the tableau to the state where the basic variables
  3492. * are those in "col_var".
  3493. * We first construct a list of variables that are currently in
  3494. * the basis, but shouldn't. Then we iterate over all variables
  3495. * that should be in the basis and for each one that is currently
  3496. * not in the basis, we exchange it with one of the elements of the
  3497. * list constructed before.
  3498. * We can always find an appropriate variable to pivot with because
  3499. * the current basis is mapped to the old basis by a non-singular
  3500. * matrix and so we can never end up with a zero row.
  3501. */
  3502. static int restore_basis(struct isl_tab *tab, int *col_var)
  3503. {
  3504. int i, j;
  3505. int n_extra = 0;
  3506. int *extra = NULL; /* current columns that contain bad stuff */
  3507. unsigned off = 2 + tab->M;
  3508. extra = isl_alloc_array(tab->mat->ctx, int, tab->n_col);
  3509. if (tab->n_col && !extra)
  3510. goto error;
  3511. for (i = 0; i < tab->n_col; ++i) {
  3512. for (j = 0; j < tab->n_col; ++j)
  3513. if (tab->col_var[i] == col_var[j])
  3514. break;
  3515. if (j < tab->n_col)
  3516. continue;
  3517. extra[n_extra++] = i;
  3518. }
  3519. for (i = 0; i < tab->n_col && n_extra > 0; ++i) {
  3520. struct isl_tab_var *var;
  3521. int row;
  3522. for (j = 0; j < tab->n_col; ++j)
  3523. if (col_var[i] == tab->col_var[j])
  3524. break;
  3525. if (j < tab->n_col)
  3526. continue;
  3527. var = var_from_index(tab, col_var[i]);
  3528. row = var->index;
  3529. for (j = 0; j < n_extra; ++j)
  3530. if (!isl_int_is_zero(tab->mat->row[row][off+extra[j]]))
  3531. break;
  3532. isl_assert(tab->mat->ctx, j < n_extra, goto error);
  3533. if (isl_tab_pivot(tab, row, extra[j]) < 0)
  3534. goto error;
  3535. extra[j] = extra[--n_extra];
  3536. }
  3537. free(extra);
  3538. return 0;
  3539. error:
  3540. free(extra);
  3541. return -1;
  3542. }
  3543. /* Remove all samples with index n or greater, i.e., those samples
  3544. * that were added since we saved this number of samples in
  3545. * isl_tab_save_samples.
  3546. */
  3547. static void drop_samples_since(struct isl_tab *tab, int n)
  3548. {
  3549. int i;
  3550. for (i = tab->n_sample - 1; i >= 0 && tab->n_sample > n; --i) {
  3551. if (tab->sample_index[i] < n)
  3552. continue;
  3553. if (i != tab->n_sample - 1) {
  3554. int t = tab->sample_index[tab->n_sample-1];
  3555. tab->sample_index[tab->n_sample-1] = tab->sample_index[i];
  3556. tab->sample_index[i] = t;
  3557. isl_mat_swap_rows(tab->samples, tab->n_sample-1, i);
  3558. }
  3559. tab->n_sample--;
  3560. }
  3561. }
  3562. static isl_stat perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo)
  3563. WARN_UNUSED;
  3564. static isl_stat perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo)
  3565. {
  3566. switch (undo->type) {
  3567. case isl_tab_undo_rational:
  3568. tab->rational = 0;
  3569. break;
  3570. case isl_tab_undo_empty:
  3571. tab->empty = 0;
  3572. break;
  3573. case isl_tab_undo_nonneg:
  3574. case isl_tab_undo_redundant:
  3575. case isl_tab_undo_freeze:
  3576. case isl_tab_undo_zero:
  3577. case isl_tab_undo_allocate:
  3578. case isl_tab_undo_relax:
  3579. case isl_tab_undo_unrestrict:
  3580. return perform_undo_var(tab, undo);
  3581. case isl_tab_undo_bmap_eq:
  3582. tab->bmap = isl_basic_map_free_equality(tab->bmap, 1);
  3583. return tab->bmap ? isl_stat_ok : isl_stat_error;
  3584. case isl_tab_undo_bmap_ineq:
  3585. tab->bmap = isl_basic_map_free_inequality(tab->bmap, 1);
  3586. return tab->bmap ? isl_stat_ok : isl_stat_error;
  3587. case isl_tab_undo_bmap_div:
  3588. return drop_bmap_div(tab, undo->u.var_index);
  3589. case isl_tab_undo_saved_basis:
  3590. if (restore_basis(tab, undo->u.col_var) < 0)
  3591. return isl_stat_error;
  3592. break;
  3593. case isl_tab_undo_drop_sample:
  3594. tab->n_outside--;
  3595. break;
  3596. case isl_tab_undo_saved_samples:
  3597. drop_samples_since(tab, undo->u.n);
  3598. break;
  3599. case isl_tab_undo_callback:
  3600. return undo->u.callback->run(undo->u.callback);
  3601. default:
  3602. isl_assert(tab->mat->ctx, 0, return isl_stat_error);
  3603. }
  3604. return isl_stat_ok;
  3605. }
  3606. /* Return the tableau to the state it was in when the snapshot "snap"
  3607. * was taken.
  3608. */
  3609. isl_stat isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap)
  3610. {
  3611. struct isl_tab_undo *undo, *next;
  3612. if (!tab)
  3613. return isl_stat_error;
  3614. tab->in_undo = 1;
  3615. for (undo = tab->top; undo && undo != &tab->bottom; undo = next) {
  3616. next = undo->next;
  3617. if (undo == snap)
  3618. break;
  3619. if (perform_undo(tab, undo) < 0) {
  3620. tab->top = undo;
  3621. free_undo(tab);
  3622. tab->in_undo = 0;
  3623. return isl_stat_error;
  3624. }
  3625. free_undo_record(undo);
  3626. }
  3627. tab->in_undo = 0;
  3628. tab->top = undo;
  3629. if (!undo)
  3630. return isl_stat_error;
  3631. return isl_stat_ok;
  3632. }
  3633. /* The given row "row" represents an inequality violated by all
  3634. * points in the tableau. Check for some special cases of such
  3635. * separating constraints.
  3636. * In particular, if the row has been reduced to the constant -1,
  3637. * then we know the inequality is adjacent (but opposite) to
  3638. * an equality in the tableau.
  3639. * If the row has been reduced to r = c*(-1 -r'), with r' an inequality
  3640. * of the tableau and c a positive constant, then the inequality
  3641. * is adjacent (but opposite) to the inequality r'.
  3642. */
  3643. static enum isl_ineq_type separation_type(struct isl_tab *tab, unsigned row)
  3644. {
  3645. int pos;
  3646. unsigned off = 2 + tab->M;
  3647. if (tab->rational)
  3648. return isl_ineq_separate;
  3649. if (!isl_int_is_one(tab->mat->row[row][0]))
  3650. return isl_ineq_separate;
  3651. pos = isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
  3652. tab->n_col - tab->n_dead);
  3653. if (pos == -1) {
  3654. if (isl_int_is_negone(tab->mat->row[row][1]))
  3655. return isl_ineq_adj_eq;
  3656. else
  3657. return isl_ineq_separate;
  3658. }
  3659. if (!isl_int_eq(tab->mat->row[row][1],
  3660. tab->mat->row[row][off + tab->n_dead + pos]))
  3661. return isl_ineq_separate;
  3662. pos = isl_seq_first_non_zero(
  3663. tab->mat->row[row] + off + tab->n_dead + pos + 1,
  3664. tab->n_col - tab->n_dead - pos - 1);
  3665. return pos == -1 ? isl_ineq_adj_ineq : isl_ineq_separate;
  3666. }
  3667. /* Check the effect of inequality "ineq" on the tableau "tab".
  3668. * The result may be
  3669. * isl_ineq_redundant: satisfied by all points in the tableau
  3670. * isl_ineq_separate: satisfied by no point in the tableau
  3671. * isl_ineq_cut: satisfied by some by not all points
  3672. * isl_ineq_adj_eq: adjacent to an equality
  3673. * isl_ineq_adj_ineq: adjacent to an inequality.
  3674. */
  3675. enum isl_ineq_type isl_tab_ineq_type(struct isl_tab *tab, isl_int *ineq)
  3676. {
  3677. enum isl_ineq_type type = isl_ineq_error;
  3678. struct isl_tab_undo *snap = NULL;
  3679. int con;
  3680. int row;
  3681. if (!tab)
  3682. return isl_ineq_error;
  3683. if (isl_tab_extend_cons(tab, 1) < 0)
  3684. return isl_ineq_error;
  3685. snap = isl_tab_snap(tab);
  3686. con = isl_tab_add_row(tab, ineq);
  3687. if (con < 0)
  3688. goto error;
  3689. row = tab->con[con].index;
  3690. if (isl_tab_row_is_redundant(tab, row))
  3691. type = isl_ineq_redundant;
  3692. else if (isl_int_is_neg(tab->mat->row[row][1]) &&
  3693. (tab->rational ||
  3694. isl_int_abs_ge(tab->mat->row[row][1],
  3695. tab->mat->row[row][0]))) {
  3696. int nonneg = at_least_zero(tab, &tab->con[con]);
  3697. if (nonneg < 0)
  3698. goto error;
  3699. if (nonneg)
  3700. type = isl_ineq_cut;
  3701. else
  3702. type = separation_type(tab, row);
  3703. } else {
  3704. int red = con_is_redundant(tab, &tab->con[con]);
  3705. if (red < 0)
  3706. goto error;
  3707. if (!red)
  3708. type = isl_ineq_cut;
  3709. else
  3710. type = isl_ineq_redundant;
  3711. }
  3712. if (isl_tab_rollback(tab, snap))
  3713. return isl_ineq_error;
  3714. return type;
  3715. error:
  3716. return isl_ineq_error;
  3717. }
  3718. isl_stat isl_tab_track_bmap(struct isl_tab *tab, __isl_take isl_basic_map *bmap)
  3719. {
  3720. bmap = isl_basic_map_cow(bmap);
  3721. if (!tab || !bmap)
  3722. goto error;
  3723. if (tab->empty) {
  3724. bmap = isl_basic_map_set_to_empty(bmap);
  3725. if (!bmap)
  3726. goto error;
  3727. tab->bmap = bmap;
  3728. return isl_stat_ok;
  3729. }
  3730. isl_assert(tab->mat->ctx, tab->n_eq == bmap->n_eq, goto error);
  3731. isl_assert(tab->mat->ctx,
  3732. tab->n_con == bmap->n_eq + bmap->n_ineq, goto error);
  3733. tab->bmap = bmap;
  3734. return isl_stat_ok;
  3735. error:
  3736. isl_basic_map_free(bmap);
  3737. return isl_stat_error;
  3738. }
  3739. isl_stat isl_tab_track_bset(struct isl_tab *tab, __isl_take isl_basic_set *bset)
  3740. {
  3741. return isl_tab_track_bmap(tab, bset_to_bmap(bset));
  3742. }
  3743. __isl_keep isl_basic_set *isl_tab_peek_bset(struct isl_tab *tab)
  3744. {
  3745. if (!tab)
  3746. return NULL;
  3747. return bset_from_bmap(tab->bmap);
  3748. }
  3749. static void isl_tab_print_internal(__isl_keep struct isl_tab *tab,
  3750. FILE *out, int indent)
  3751. {
  3752. unsigned r, c;
  3753. int i;
  3754. if (!tab) {
  3755. fprintf(out, "%*snull tab\n", indent, "");
  3756. return;
  3757. }
  3758. fprintf(out, "%*sn_redundant: %d, n_dead: %d", indent, "",
  3759. tab->n_redundant, tab->n_dead);
  3760. if (tab->rational)
  3761. fprintf(out, ", rational");
  3762. if (tab->empty)
  3763. fprintf(out, ", empty");
  3764. fprintf(out, "\n");
  3765. fprintf(out, "%*s[", indent, "");
  3766. for (i = 0; i < tab->n_var; ++i) {
  3767. if (i)
  3768. fprintf(out, (i == tab->n_param ||
  3769. i == tab->n_var - tab->n_div) ? "; "
  3770. : ", ");
  3771. fprintf(out, "%c%d%s", tab->var[i].is_row ? 'r' : 'c',
  3772. tab->var[i].index,
  3773. tab->var[i].is_zero ? " [=0]" :
  3774. tab->var[i].is_redundant ? " [R]" : "");
  3775. }
  3776. fprintf(out, "]\n");
  3777. fprintf(out, "%*s[", indent, "");
  3778. for (i = 0; i < tab->n_con; ++i) {
  3779. if (i)
  3780. fprintf(out, ", ");
  3781. fprintf(out, "%c%d%s", tab->con[i].is_row ? 'r' : 'c',
  3782. tab->con[i].index,
  3783. tab->con[i].is_zero ? " [=0]" :
  3784. tab->con[i].is_redundant ? " [R]" : "");
  3785. }
  3786. fprintf(out, "]\n");
  3787. fprintf(out, "%*s[", indent, "");
  3788. for (i = 0; i < tab->n_row; ++i) {
  3789. const char *sign = "";
  3790. if (i)
  3791. fprintf(out, ", ");
  3792. if (tab->row_sign) {
  3793. if (tab->row_sign[i] == isl_tab_row_unknown)
  3794. sign = "?";
  3795. else if (tab->row_sign[i] == isl_tab_row_neg)
  3796. sign = "-";
  3797. else if (tab->row_sign[i] == isl_tab_row_pos)
  3798. sign = "+";
  3799. else
  3800. sign = "+-";
  3801. }
  3802. fprintf(out, "r%d: %d%s%s", i, tab->row_var[i],
  3803. isl_tab_var_from_row(tab, i)->is_nonneg ? " [>=0]" : "", sign);
  3804. }
  3805. fprintf(out, "]\n");
  3806. fprintf(out, "%*s[", indent, "");
  3807. for (i = 0; i < tab->n_col; ++i) {
  3808. if (i)
  3809. fprintf(out, ", ");
  3810. fprintf(out, "c%d: %d%s", i, tab->col_var[i],
  3811. var_from_col(tab, i)->is_nonneg ? " [>=0]" : "");
  3812. }
  3813. fprintf(out, "]\n");
  3814. r = tab->mat->n_row;
  3815. tab->mat->n_row = tab->n_row;
  3816. c = tab->mat->n_col;
  3817. tab->mat->n_col = 2 + tab->M + tab->n_col;
  3818. isl_mat_print_internal(tab->mat, out, indent);
  3819. tab->mat->n_row = r;
  3820. tab->mat->n_col = c;
  3821. if (tab->bmap)
  3822. isl_basic_map_print_internal(tab->bmap, out, indent);
  3823. }
  3824. void isl_tab_dump(__isl_keep struct isl_tab *tab)
  3825. {
  3826. isl_tab_print_internal(tab, stderr, 0);
  3827. }