Advertisement
Guest User

Projet_mcp_5

a guest
Apr 24th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.53 KB | None | 0 0
  1. class Rectangle
  2. {
  3.  
  4. //*************************************************************************
  5. //FIELDS
  6. //*************************************************************************
  7.  
  8. var startX: int;
  9. var startY: int;
  10. var endX: int;
  11. var endY: int;
  12. var value: int;
  13.  
  14. //*************************************************************************
  15. //CLASS INVARIANTS
  16. //*************************************************************************
  17.  
  18. predicate valid()
  19. reads this
  20. {
  21. 0 <= startX < endX && 0 <= startY < endY && (value == 0 || value == 1)
  22. }
  23.  
  24. constructor(sX: int, sY: int, eX: int, eY: int, v: int)
  25. requires 0 <= sX < eX
  26. requires 0 <= sY < eY
  27. requires ( v == 0 || v == 1)
  28. ensures valid()
  29. modifies this
  30. {
  31. startX := sX;
  32. startY := sY;
  33. endX := eX;
  34. endY := eY;
  35. value := v;
  36. }
  37.  
  38. function method getStartX(): int
  39. reads this
  40. {
  41. startX
  42. }
  43.  
  44. function method getStartY(): int
  45. reads this
  46. {
  47. startY
  48. }
  49.  
  50. function method getEndX(): int
  51. reads this
  52. {
  53. endX
  54. }
  55.  
  56. function method getEndY(): int
  57. reads this
  58. {
  59. endY
  60. }
  61.  
  62. function method getValue(): int
  63. reads this
  64. {
  65. value
  66. }
  67. }
  68.  
  69. class Couverture
  70. {
  71.  
  72. //*************************************************************************
  73. //FIELDS
  74. //*************************************************************************
  75.  
  76. var couverture: array2<int>;
  77. var rectangles: seq<Rectangle>
  78.  
  79. //*************************************************************************
  80. //CLASS INVARIANTS
  81. //*************************************************************************
  82.  
  83. predicate valid()
  84. reads this, couverture, rectangles
  85. {
  86. couverture != null
  87. && couverture.Length0 > 0
  88. && couverture.Length1 > 0
  89. //&& |rectangles| > 0
  90. //&& forall i | 0 <= i < |rectangles| :: rectangles[i] != null
  91. //&& forall i | 0 <= i < |rectangles| :: rectangles[i].getStartX() <= couverture.Length0 && rectangles[i].getStartY() <= couverture.Length1
  92. }
  93.  
  94. constructor(recList: seq<Rectangle>)
  95.  
  96. // Il y a au moins un rectangle dans la list et aucun rectangle n'est null
  97. requires |recList| > 0 && forall r: Rectangle | r in recList :: r != null
  98. requires forall i | 0 <= i < |recList| :: recList[i] != null
  99. requires forall r: Rectangle | r in recList :: r.valid()
  100. requires forall i | 0 <= i < |recList| :: recList[i]!= null && 0 <= recList[i].getStartX() < recList[i].getEndX() && 0 <= recList[i].getStartY() < recList[i].getEndY()
  101.  
  102.  
  103. // modifie la couverture
  104. modifies this, couverture, rectangles
  105. ensures valid()
  106. {
  107. rectangles := recList;
  108.  
  109. // Comme recList était valide, rectangles l'est aussi
  110. assert forall r: Rectangle | r in rectangles :: r.valid();
  111. assert forall r: Rectangle | r in rectangles :: r != null;
  112. assert forall i | 0 <= i < |rectangles| :: rectangles[i] != null;
  113. assert |rectangles| > 0;
  114.  
  115. //initialise la taille de couverture
  116. setSize();
  117.  
  118. //la liste rectangles est toujours valide
  119. assert |rectangles| > 0;
  120. assert forall i | 0 <= i < |rectangles| :: rectangles[i] != null;
  121. assert forall r: Rectangle | r in rectangles :: r != null;
  122. assert forall i | 0 <= i < |rectangles| :: rectangles[i]!= null && rectangles[i].getStartX() < couverture.Length0 && rectangles[i].getStartY() < couverture.Length1;
  123.  
  124. var i := 0;
  125. var r: Rectangle;
  126. var tab:= rectangles;
  127.  
  128. assert fresh(couverture);
  129.  
  130. while(i < |rectangles|)
  131. invariant 0 <= i <= |rectangles| && couverture != null && forall i | 0 <= i < |rectangles| :: rectangles[i] != null
  132. invariant forall i | 0 <= i < |rectangles| :: rectangles[i] == tab[i];
  133. invariant forall i | 0 <= i < |rectangles| :: rectangles[i].getStartX() < couverture.Length0 && rectangles[i].getStartY() < couverture.Length1
  134. invariant forall i | 0 <= i < |rectangles| :: rectangles[i].valid()
  135. decreases |rectangles|-i
  136. modifies couverture
  137. {
  138. assert 0 <= i < |rectangles|;
  139. r := rectangles[i];
  140. assert r != null;
  141.  
  142. if (r.getValue() == 0)
  143. {
  144. assert r.getStartX() < couverture.Length0 && r.getStartY() < couverture.Length1;
  145. couverture[r.getStartX(), r.getStartY()] := 0;
  146. }
  147. else
  148. {
  149. var y := r.getStartY();
  150. while(y < r.getEndY())
  151. invariant r.getStartY() <= y <= r.getEndY()
  152. decreases r.getEndY()-y
  153. modifies couverture
  154. {
  155. var x := r.getStartX();
  156. while(x < r.getEndX()-1)
  157. invariant r.getStartX() <= x <= r.getEndX()
  158. decreases r.getEndX()-x
  159. modifies couverture
  160. {
  161. couverture[x+1, y] := couverture[x, y];
  162. x := x + 1;
  163. }
  164. y := y + 1;
  165. }
  166.  
  167. var x := r.getStartX();
  168. while(x < r.getEndX())
  169. invariant r.getStartX() <= x <= r.getEndX()
  170. decreases r.getEndX()-x
  171. modifies couverture
  172. {
  173. var y := r.getStartY();
  174. while(y < r.getEndY()-1)
  175. invariant r.getStartX() <= x <= r.getEndX()
  176. invariant r.getStartY() <= y <= r.getEndY()-1 && couverture != null
  177. decreases r.getEndY()-y
  178. modifies couverture
  179. {
  180. assert 0 <= x < couverture.Length0 && 0 <= y+1 < couverture.Length1;
  181. couverture[x, y+1] := couverture[x, y];
  182. y := y + 1;
  183. }
  184. x := x + 1;
  185. }
  186. }
  187.  
  188. i := i + 1;
  189. if(i < |rectangles|){
  190. r := rectangles[i];
  191. }
  192. }
  193. }
  194.  
  195. method setSize()
  196.  
  197. // la list rectangle contient au moins un élément et que des rectangles non null valides
  198. requires |rectangles| > 0
  199. requires forall r: Rectangle | r in rectangles :: r != null
  200. requires forall r: Rectangle | r in rectangles :: r.valid()
  201. requires forall i | 0 <= i < |rectangles| :: rectangles[i] != null
  202. requires forall i | 0 <= i < |rectangles| :: rectangles[i]!= null && 0 <= rectangles[i].getStartX() < rectangles[i].getEndX() && 0 <= rectangles[i].getStartY() < rectangles[i].getEndY()
  203.  
  204.  
  205. ensures rectangles == old(rectangles)
  206. ensures couverture != null
  207. ensures fresh(couverture);
  208. ensures forall i | 0 <= i < |rectangles| :: rectangles[i]!= null && 0 <= rectangles[i].getStartX() < rectangles[i].getEndX() <= couverture.Length0 && 0 <= rectangles[i].getStartY() < rectangles[i].getEndY() <= couverture.Length1
  209. ensures valid()
  210.  
  211. modifies this, couverture
  212. {
  213. var xMax := 1;
  214. var yMax := 1;
  215. var count := 1;
  216. var length := |rectangles|;
  217. var tab := rectangles;
  218.  
  219.  
  220. var i := 0;
  221. var r: Rectangle;
  222.  
  223. while(i < length)
  224. invariant 0 <= i <= length && forall i | 0 <= i < |rectangles| :: rectangles[i] != null && rectangles[i] == tab[i];
  225. invariant forall i | 0 <= i < |rectangles| :: rectangles[i]!= null && 0 <= rectangles[i].getStartX() < rectangles[i].getEndX() && 0 <= rectangles[i].getStartY() < rectangles[i].getEndY()
  226. invariant xMax >= 0 && yMax >= 0;
  227. decreases length-i
  228. decreases length-xMax
  229. decreases length-yMax
  230. {
  231. assert 0<=i<|rectangles|;
  232. r := rectangles[i];
  233. assert r!= null;
  234.  
  235. assert r.getEndX() > 0;
  236. if (r.getEndX() > xMax)
  237. {
  238. xMax := r.getEndX();
  239. assert xMax > 0;
  240. }
  241.  
  242. assert r.getEndY() > 0;
  243. if (r.getEndY() > yMax)
  244. {
  245. yMax := r.getEndY();
  246. assert yMax > 0;
  247. }
  248.  
  249. i := i + 1;
  250. }
  251.  
  252. assert |rectangles| == length;
  253. assert xMax >= 0;
  254. assert yMax >= 0;
  255.  
  256. couverture := new int[xMax, yMax];
  257.  
  258. assert couverture != null;
  259. assert couverture.Length0 > 0 && couverture.Length1 > 0;
  260.  
  261. var y := 0;
  262. while(y < yMax)
  263. invariant 0 <= y <= yMax && couverture != null && couverture.Length0 >0 && couverture.Length1 >0
  264. decreases yMax-y
  265. modifies couverture
  266. {
  267. var x := 0;
  268. while(x < xMax)
  269. invariant 0 <= x <= xMax && couverture != null && couverture.Length0 >0 && couverture.Length1 >0
  270. decreases xMax-x
  271. modifies couverture
  272. {
  273. assert x < couverture.Length0 && y < couverture.Length1;
  274. couverture[x, y] := count;
  275. assert couverture != null;
  276. count := count + 1;
  277. x := x + 1;
  278. }
  279. y := y + 1;
  280. }
  281. assert couverture != null;
  282. assert couverture.Length0 > 0 && couverture.Length1 > 0;
  283. }
  284.  
  285. method contains(x: int, y: int) returns (b: bool)
  286. requires valid()
  287. requires 0 <= x < couverture.Length0 && 0 <= y < couverture.Length1
  288. ensures valid()
  289. {
  290. assert 0 <= x < couverture.Length0 && 0<= y < couverture.Length1;
  291. var value := find(x, y);
  292.  
  293. if(couverture.Length0 > 1){ // correspond à couverture.length en java
  294. if(x == 0){
  295. if(couverture[x+1, y] == value){
  296. return true;
  297. }
  298. }
  299.  
  300. else if(x == couverture.Length0-1){
  301. if(couverture[x-1, y] == value){
  302. return true;
  303. }
  304. }
  305.  
  306. else{
  307. if(couverture[x-1, y] == value || couverture[x+1, y] == value)
  308. {
  309. return true;
  310. }
  311. }
  312. }
  313.  
  314. if(couverture.Length1 > 1) //correspond à couverture[0].length en java
  315. {
  316. if(y==0)
  317. {
  318. if(couverture[x, y+1] == value)
  319. {
  320. return true;
  321. }
  322. }
  323.  
  324. else if(y == couverture.Length1-1)
  325. {
  326. if(couverture[x, y-1] == value)
  327. {
  328. return true;
  329. }
  330. }
  331.  
  332. else
  333. {
  334. if(couverture[x, y+1] == value || couverture[x, y-1] == value)
  335. {
  336. return true;
  337. }
  338. }
  339. }
  340. return false;
  341. }
  342.  
  343. method canMerge(r1: Rectangle, r2: Rectangle) returns (b: bool)
  344. requires valid()
  345. requires r1 != null && r2 != null
  346. requires r1.valid() && r2.valid()
  347. ensures valid()
  348. {
  349. // si c un obstacle on ne peut pas merge
  350. if( r1.getValue() == 0 || r2.getValue() == 0)
  351. {
  352. return false;
  353. }
  354.  
  355. // teste si on peut merger horizontalment
  356. if((r1.getEndX() == r2.getStartX() || r1.getStartX() == r2.getEndX()) && r1.getStartY() == r2.getStartY() && r1.getEndY() == r2.getEndY())
  357. {
  358. return true;
  359. }
  360.  
  361. // teste si on peut merger verticalement
  362. if((r1.getEndY() == r2.getStartY() || r1.getStartY() == r2.getEndY()) && r1.getStartX() == r2.getStartX() && r1.getEndX() == r2.getEndX())
  363. {
  364. return true;
  365. }
  366.  
  367. return false;
  368. }
  369.  
  370. function method doCanMerge(r1: Rectangle, r2: Rectangle): bool
  371. requires r1 != null && r2 != null
  372. requires r1.valid() && r2.valid()
  373. requires valid()
  374. ensures valid()
  375. reads this, couverture, rectangles, r1, r2
  376. {
  377. if r1.getValue() == 0 || r2.getValue() == 0 then false
  378. else if ((r1.getEndX() == r2.getStartX() || r1.getStartX() == r2.getEndX()) && r1.getStartY() == r2.getStartY() && r1.getEndY() == r2.getEndY())
  379. || ((r1.getEndY() == r2.getStartY() || r1.getStartY() == r2.getEndY()) && r1.getStartX() == r2.getStartX() && r1.getEndX() == r2.getEndX())
  380. then true
  381. else false
  382. }
  383.  
  384. method merge(r1: Rectangle, r2: Rectangle) returns (r: Rectangle)
  385. requires valid()
  386. requires r1 != null && r2 != null
  387. requires r1.valid() && r2.valid()
  388. requires r1.getEndX() > r1.getStartX() >= 0 && r2.getEndX() > r2.getStartX() >= 0 && r1.getEndY() > r1.getStartY() >= 0 && r2.getEndY() > r2.getStartY() >= 0
  389. requires couverture.Length0 > r1.getEndX() > 0 && couverture.Length0 > r2.getEndX() > 0 && couverture.Length1 > r1.getEndY() > 0 && couverture.Length1 > r2.getEndY() > 0
  390. requires doCanMerge(r1, r2)
  391.  
  392. ensures r == null || r.valid()
  393. ensures valid()
  394. modifies this, couverture
  395. {
  396. var x := r2.getStartX();
  397. while(x < r2.getEndX())
  398. invariant r2.getStartX() <= x <= r2.getEndX()
  399. invariant couverture != null
  400. invariant r1.getStartX() < couverture.Length0 && r1.getStartY() < couverture.Length1
  401. invariant r2.getStartX() < couverture.Length0 && r2.getStartY() < couverture.Length1
  402. decreases r2.getEndX()-x
  403. modifies couverture
  404. {
  405. var y := r2.getStartY();
  406. while(y < r2.getEndY())
  407. invariant r2.getStartY() <= y <= r2.getEndY() && couverture != null
  408. invariant r1.getStartX() < couverture.Length0 && r1.getStartY() < couverture.Length1
  409. invariant r2.getStartX() < couverture.Length0 && r2.getStartY() < couverture.Length1
  410. invariant x == old(x)
  411. decreases r2.getEndY()-y
  412. modifies couverture
  413. {
  414. assume 0 <= x < couverture.Length0 && 0 <= y < couverture.Length1;
  415. couverture[x, y] := couverture[r1.getStartX(), r1.getStartY()];
  416. y := y + 1;
  417. }
  418. x := x + 1;
  419. }
  420.  
  421. assert couverture != null;
  422. assert couverture.Length0 > 0 && couverture.Length1 > 0;
  423.  
  424. var startX := min(r1.getStartX(), r2.getStartX());
  425. assert startX >= 0;
  426.  
  427. var startY := min(r1.getStartY(), r2.getStartY());
  428. assert startY >=0;
  429.  
  430. var endX := max(r1.getEndX(), r2.getEndX());
  431. assert endX >0;
  432.  
  433. var endY := max(r1.getEndY(), r2.getEndY());
  434. assert endY >0;
  435.  
  436. var value := 1;
  437. assert value == 0 || value==1;
  438.  
  439. var rectangle := new Rectangle(startX, startY, endX, endY, value);
  440. assert rectangle != null && rectangle.valid();
  441.  
  442. return rectangle;
  443. }
  444.  
  445. function method min(a: int, b: int): int
  446. {
  447. if a > b then b else a
  448. }
  449.  
  450. function method max(a: int, b: int): int
  451. {
  452. if a > b then a else b
  453. }
  454.  
  455. method improve() returns (b: bool)
  456. requires valid()
  457. requires |rectangles| > 0 ==> forall r: Rectangle | r in rectangles :: r != null
  458. requires forall i | 0 <= i < |rectangles| :: rectangles[i] != null
  459. requires forall r: Rectangle | r in rectangles :: r.valid()
  460. requires forall r: Rectangle | r in rectangles :: (couverture.Length0 > r.getEndX() > r.getStartX() >= 0 && couverture.Length1 > r.getEndY() > r.getStartY() >= 0)
  461. ensures valid()
  462. ensures b == false || b == true
  463. modifies this, couverture
  464. {
  465. var index1 := 0;
  466. var index2 := 0;
  467.  
  468. var i := 0;
  469. while(i < |rectangles|)
  470. invariant 0<=i<=|rectangles|
  471. invariant couverture !=null && couverture.Length0 > 0 && couverture.Length1 > 0
  472. decreases |rectangles|-i
  473. {
  474. var j := i + 1;
  475. while(j < |rectangles|)
  476. invariant i+1<=j<=|rectangles|
  477. decreases |rectangles|-j
  478. {
  479. assert i < |rectangles| && j < |rectangles|;
  480.  
  481. var r1: Rectangle := rectangles[i];
  482. var r2: Rectangle := rectangles[j];
  483.  
  484. assert r1 != null && r2 != null;
  485. assert r1.valid() && r2.valid();
  486. assert 0 <= r1.getStartX() < r1.getEndX() < couverture.Length0 && 0 <= r1.getStartY() < r1.getEndY() < couverture.Length1;
  487. assert 0 <= r2.getStartX() < r2.getEndX() < couverture.Length0 && 0 <= r2.getStartY() < r2.getEndY() < couverture.Length1;
  488. if(|rectangles| > 1 && doCanMerge(rectangles[i], rectangles[j])){
  489.  
  490. //take the first i elements and drop the first i+1 elements
  491. //then concatenate them to obtain a list without the i th value?
  492. rectangles := rectangles[..i] + rectangles[i+1..];
  493. //same process
  494. if(i < j) { j := j - 1;}
  495. rectangles := rectangles[..j] + rectangles[j+1..];
  496. var newR: Rectangle := merge(r1, r2);
  497. rectangles := rectangles + [newR];
  498.  
  499. return true;
  500. }
  501. j := j + 1;
  502. }
  503. i := i + 1;
  504. }
  505. return false;
  506. }
  507.  
  508. method optimize()
  509. requires valid()
  510. requires forall i | 0 <= i < |rectangles| :: rectangles[i] != null
  511. requires forall r: Rectangle | r in rectangles :: r.valid()
  512. requires forall r: Rectangle | r in rectangles :: (couverture.Length0 > r.getEndX() > r.getStartX() >= 0 && couverture.Length1 > r.getEndY() > r.getStartY() >= 0)
  513. modifies this, couverture, rectangles
  514. {
  515. var b: bool := improve();
  516.  
  517. while(b)
  518. //invariant forall i | 0 <= i < |rectangles| :: rectangles[i] != null && rectangles[i].valid()
  519. //invariant couverture != null && couverture.Length0 > 0 && couverture.Length1 > 0
  520. invariant b <==> (false || true)
  521. modifies this, couverture, rectangles
  522. {
  523. b := improve();
  524. }
  525. return;
  526. }
  527.  
  528. //*************************************************************************
  529. //Union-Find Methods
  530. //*************************************************************************
  531.  
  532. function method find(a: int, b: int): int
  533. requires valid() && 0 <= a < couverture.Length0 && 0 <= b < couverture.Length1
  534. ensures valid()
  535. ensures couverture != null
  536. reads this, couverture, rectangles
  537. {
  538. couverture[a, b]
  539. }
  540.  
  541. method union(a: int, b: int, c: int, d: int)
  542. requires valid()
  543. requires 0 <= a < couverture.Length0 && 0 <= b < couverture.Length1 && 0 <= c < couverture.Length0 && 0 <= d < couverture.Length1
  544. modifies couverture
  545. {
  546. if( connected(a, b, c, d)){
  547. return;
  548. }
  549.  
  550. var qId := find(a, b);
  551. var pId := find(c, d);
  552.  
  553. if(pId == qId) { return; }
  554. var x := 0;
  555. while(x < couverture.Length0)
  556. invariant couverture!=null
  557. invariant 0 <= x <= couverture.Length0
  558. decreases couverture.Length0-x
  559. modifies couverture
  560. {
  561. assert x < couverture.Length0;
  562. var y := 0;
  563.  
  564. while(y < couverture.Length1)
  565. invariant couverture != null
  566. invariant 0 <= y <= couverture.Length1
  567. invariant 0 <= x <= couverture.Length0
  568. decreases couverture.Length1-y
  569. modifies couverture
  570. {
  571. assert x < couverture.Length0;
  572. assert y < couverture.Length1;
  573. if(couverture[x, y] == pId)
  574. {
  575. couverture[x, y] := qId;
  576. }
  577. y := y + 1;
  578. }
  579. x := x + 1;
  580. }
  581. }
  582.  
  583. function method connected(a: int, b: int, c: int, d: int): bool
  584. requires valid()
  585. requires 0 <= a < couverture.Length0 && 0 <= b < couverture.Length1 && 0 <= c < couverture.Length0 && 0 <= d < couverture.Length1
  586. ensures valid()
  587. reads this, couverture, rectangles
  588. {
  589. find(a, b) == find(c, d)
  590. }
  591. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement