assignment #4 solution - umass amherstlaser.cs.umass.edu/.../documents/assignment4solution.pdf ·...

21
Assignment #4 Solution 1.a. Assumptions and Notations: Assume setA and setB both have 2 elements, and only the second element of setA also appears in setB. Let A and B be the symbolic names of the two input sets. Also, let |X| denote the size of a set X. We use A[i] as a shorthand for setA.get(i).getIntValue() Stmt PV PC 0 U{} true 1 sizeA|A| true 2 sizeB|B| true 3 isInUnionfalse true 4 i0 true 5 U[0]A[0] true0<|A|0<|A| 6 i1 0<|A| 4 0<|A| 5 U[1]A[1] 0<|A|1<|A|1<|A| 6 i2 1<|A| 4 1<|A| 7 j0 1<|A|2|A|2=|A| 8 isInUnionfalse 2=|A|0<|B| 9 m0 2=|A|0<|B| 10 2=|A|0<|B| 13 m1 2=|A|0<|B|B[0]U[0]U[0]=A[0] 2=|A|0<|B|B[0]A[0] 9 2=|A|0<|B|B[0]A[0] 10 2=|A|0<|B|B[0]A[0] 13 m2 2=|A|0<|B|B[0]A[0]B[0]U[1]U[1]=A[1] 2=|A|0<|B|B[0]A[0]B[0]A[1] 9 2=|A|0<|B|B[0]A[0]B[0]A[1] 14 2=|A|0<|B|B[0]A[0]B[0]A[1] 15 U[2]B[0] 2=|A|0<|B|B[0]A[0]B[0]A[1] 16 j1 2=|A|0<|B|B[0]A[0]B[0]A[1] 7 2=|A|0<|B|B[0]A[0]B[0]A[1] 8 isInUnionfalse 2=|A|0<|B|B[0]A[0]B[0]A[1]1<|B| 2=|A|1<|B|B[0]A[0]B[0]A[1] 9 m0 2=|A|1<|B|B[0]A[0]B[0]A[1] 10 2=|A|1<|B|B[0]A[0]B[0]A[1] 13 m1 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]U[0]U[0]=A[0] 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0] 9 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0] 10 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0] 11 isInUniontrue 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0]B[1]=U[1] U[1]=A[1] 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0]B[1]=A[1] 12 m|U| 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0]B[1]=A[1] 13 m|U|+1 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0]B[1]=A[1] 9 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0]B[1]=A[1] 14 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0]B[1]=A[1] 15 U[2]B[1] 2=|A|1<|B|B[0]A[0]B[0]A[1]B[1]A[0]B[1]=A[1]

Upload: ngohanh

Post on 10-May-2018

223 views

Category:

Documents


2 download

TRANSCRIPT

Assignment #4 Solution 1.a.

Assumptions and Notations: Assume setA and setB both have 2 elements, and only the second element of setA also appears in setB. Let A and B be the symbolic names of the two input sets. Also, let |X| denote the size of a set X. We use A[i] as a shorthand for setA.get(i).getIntValue()

Stmt PV PC 0 Uß{} true 1 sizeAß|A| true 2 sizeBß|B| true 3 isInUnionßfalse true 4 iß0 true 5 U[0]ßA[0] true∧0<|A|à0<|A| 6 iß1 0<|A| 4 0<|A| 5 U[1]ßA[1] 0<|A|∧1<|A|à1<|A| 6 iß2 1<|A| 4 1<|A| 7 jß0 1<|A|∧2≥|A|à2=|A| 8 isInUnionßfalse 2=|A|∧0<|B| 9 mß0 2=|A|∧0<|B| 10 2=|A|∧0<|B| 13 mß1 2=|A|∧0<|B|∧B[0]≠U[0]∧U[0]=A[0]à

2=|A|∧0<|B|∧B[0]≠A[0] 9 2=|A|∧0<|B|∧B[0]≠A[0] 10 2=|A|∧0<|B|∧B[0]≠A[0] 13 mß2 2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠U[1]∧U[1]=A[1]à

2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠A[1] 9 2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠A[1] 14 2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠A[1] 15 U[2]ßB[0] 2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠A[1] 16 jß1 2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠A[1] 7 2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠A[1] 8 isInUnionßfalse 2=|A|∧0<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧1<|B|à

2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1] 9 mß0 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1] 10 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1] 13 mß1 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠U[0]∧U[0]=A[0]à

2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0] 9 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0] 10 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0] 11 isInUnionßtrue 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=U[1] ∧U[1]=A[1]à

2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] 12 mß|U| 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] 13 mß|U|+1 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] 9 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] 14 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] 15 U[2]ßB[1] 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1]

16 jß2 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] 7 2=|A|∧1<|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] 17 return U 2=|A|∧2=|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1]

P=0,1,2,3,4,5,6,4,5,6,4,7,8,9,10,13,9,10,13,9,14,15,16,7,8,9,10,13,9,10,11,12,13,9,14,15,16,7,17

D[P]={(A,B) | 2=|A|∧2=|B|∧B[0]≠A[0]∧B[0]≠A[1]∧B[1]≠A[0]∧B[1]=A[1] }

C[P]=PV.U={A[0],A[1],B[1]}

1.b.

Assume setA has 2 elements while setB has zero elements.

Stmt PV PC 0 Uß{} true 1 sizeAß|A| true 2 sizeBß|B| true 3 isInUnionßfalse true 4 iß0 true 5 U[0]ßA[0] true∧0<|A|à0<|A| 6 iß1 0<|A| 4 0<|A| 5 U[1]ßA[1] 0<|A|∧1<|A|à1<|A| 6 iß2 1<|A| 4 1<|A| 7 jß0 1<|A|∧2≥|A|à2=|A| 17 return U 2=|A|∧0=|B| P=0,1,2,3,4,5,6,4,5,6,4,7,17

D[P]={(A,B) | 2=|A|∧0=|B|}

C[P]=PV.U={A[0],A[1] }

2.a.

requires //input assertions

/* non negative size */

setA.size() >= 0 && setB.size() >= 0 &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setA.size()-1; i++)

\for all(int j=i+1; j<setA.size(); j++)

setA.get(i).intValue() != setA.get(j).intValue()) &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setB.size()-1; i++)

\for all(int j=i+1; j<setB.size(); j++)

setB.get(i).intValue() != setB.get(j).intValue());

ensures //output assertions

/* non negative size */

\result.size() >= 0 &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<\result.size()-1; i++)

\for all(int j=i+1; j<\result.size(); j++)

\result.get(i).intValue() != \result.get(j).intValue()) &&

/* all elements of setA should also be elements of \result */

(\for all(int i=0; i<setA.size(); i++)

\for some(int j=0; j<\result.size(); j++)

setA.get(i).intValue() == \result.get(j).intValue()) &&

/* all elements of setB should also be elements of \result */

(\for all(int i=0; i<setB.size(); i++)

\for some(int j=0; j<\result.size(); j++)

setB.get(i).intValue() == \result.get(j).intValue()) &&

/* \result doesn’t allow to have elements which are not in setA or setB */

(\for all(int i=0; i<\result.size(); i++)

\for some(int j=0; j<setA.size() || j<setB.size(); j++)

if(j<setA.size())

\result.get(i).intValue() == setA.get(j).intValue() ||

If(j<setB.size())

\result.get(i).intValue() == setB.get(j).intValue());

2.b.

ensures //loop invariant 1

sizeA>=0 &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setA.size()-1; i++)

\for all(int j=i+1; j<setA.size(); j++)

setA.get(i).intValue() != setA.get(j).intValue()) &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setB.size()-1; i++)

\for all(int j=i+1; j<setB.size(); j++)

setB.get(i).intValue() != setB.get(j).intValue()) &&

/* duplicated elements are not allowed */

(\for all(int k=0; k<union.size()-1; k++)

\for all(int l=k+1; l< union.size(); l++)

union.get(k).intValue() != union.get(l).intValue()) &&

/* all elements of union should also be elements of setA */

(\for all(int k=0; k<union.size(); k++)

\for some(int l=0; l<sizeA; l++)

union.get(k).intValue() == setA.get(l).intValue()) &&

/* 0..i-1 elements of setA should also be elements of union */

(if(i!=0) \for all(int k=0; k<i; k++)

\for some(int l=0; l<union.size(); l++)

setA.get(k).intValue() == union.get(l).intValue()) &&

/* i..sizeA-1 elements of setA should not be elements of union */

(\for all(int k=i; k<sizeA; k++)

\for all(int l=0; l<union.size(); l++)

setA.get(k).intValue() != union.get(l).intValue());

ensures // invariant 1

/* non negative size */

setA.size() >= 0 && setB.size() >= 0 && union.size() &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setA.size()-1; i++)

\for all(int j=i+1; j<setA.size(); j++)

setA.get(i).intValue() != setA.get(j).intValue()) &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setB.size()-1; i++)

\for all(int j=i+1; j<setB.size(); j++)

setB.get(i).intValue() != setB.get(j).intValue());

/* duplicated elements are not allowed */

(\for all(int k=0; k<union.size()-1; k++)

\for all(int l=k+1; l< union.size(); l++)

union.get(k).intValue() != union.get(l).intValue()) &&

/* all elements of setA should also be elements of union */

(\for all(int i=0; i<setA.size(); i++)

\for some(int j=0; j< union.size(); j++)

setA.get(i).intValue() == union.get(j).intValue()) &&

ensures //loop invariant 2

sizeB>=0 &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setA.size()-1; i++)

\for all(int j=i+1; j<setA.size(); j++)

setA.get(i).intValue() != setA.get(j).intValue()) &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setB.size()-1; i++)

\for all(int j=i+1; j<setB.size(); j++)

setB.get(i).intValue() != setB.get(j).intValue());

/* duplicated elements are not allowed */

(\for all(int k=0; k<union.size()-1; k++)

\for all(int l=k+1; l< union.size(); l++)

union.get(k).intValue() != union.get(l).intValue()) &&

/* all elements of setA should also be elements of union */

(\for all(int i=0; i<setA.size(); i++)

\for some(int j=0; j< union.size(); j++)

setA.get(i).intValue() == union.get(j).intValue()) &&

/* 0..j-1 elements of setB should also be elements of union */

(if(j!=0) \for all(int k=0; k<i; k++)

\for some(int l=0; l<union.size(); l++)

setB.get(k).intValue() == union.get(l).intValue());

ensures //loop invariant 3

union.size()>=0 && isInUnion==false &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setA.size()-1; i++)

\for all(int j=i+1; j<setA.size(); j++)

setA.get(i).intValue() != setA.get(j).intValue()) &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setB.size()-1; i++)

\for all(int j=i+1; j<setB.size(); j++)

setB.get(i).intValue() != setB.get(j).intValue())&&

/* duplicated elements are not allowed */

(\for all(int k=0; k<union.size()-1; k++)

\for all(int l=k+1; l< union.size(); l++)

union.get(k).intValue() != union.get(l).intValue())&&

/* all elements of setA should also be elements of union */

(\for all(int i=0; i<setA.size(); i++)

\for some(int j=0; j< union.size(); j++)

setA.get(i).intValue() == union.get(j).intValue()) &&

/* isInUnion should be true when 0..j-1 elements of setB are elements of union */

(if(isInUnion==true) \for all(int k=0; k<j; k++)

\for some(int l=0; l<union.size(); l++)

setB.get(k).intValue() == union.get(l).intValue());

ensures // invariant 2

setA.size() >= 0 && setB.size() >= 0 && union.size() &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setA.size()-1; i++)

\for all(int j=i+1; j<setA.size(); j++)

setA.get(i).intValue() != setA.get(j).intValue()) &&

/* duplicated elements are not allowed */

(\for all(int i=0; i<setB.size()-1; i++)

\for all(int j=i+1; j<setB.size(); j++)

setB.get(i).intValue() != setB.get(j).intValue())&&

/* duplicated elements are not allowed */

(\for all(int k=0; k<union.size()-1; k++)

\for all(int l=k+1; l< union.size(); l++)

union.get(k).intValue() != union.get(l).intValue())&&

/* all elements of setA should also be elements of union */

(\for all(int i=0; i<setA.size(); i++)

\for some(int j=0; j< union.size(); j++)

setA.get(i).intValue() == union.get(j).intValue()) &&

/* isInUnion should be true when 0..j-1 elements of setB are elements of union */

(if(isInUnion==true) \for all(int k=0; k<j; k++)

\for some(int l=0; l<union.size(); l++)

setB.get(k).intValue() == union.get(l).intValue());

3.

(infeasible paths are discovered at 4 and 5 answers.)

* input assertions à invariant 1

* input assertions à loop invariant 1

* loop invariant 1 à invariant 1

* loop invariant 1 à loop invariant 1

* invariant 1 à output assertions

* invariant 1 à loop invariant 2

* loop invariant 2 à invariant 2

* loop invariant 2 à loop invariant 3

* loop invariant 3 à invariant 2 (B1:true)

* loop invariant 3 à invariant 2 (B1:false)

* loop invariant 3 à loop invariant 3(B1:true)

* loop invariant 3 à loop invariant 3(B1:false)

* invariant 2 à loop invariant 2(B2:true)

* invariant 2 à loop invariant 2(B2:false)

* invariant 2 à output assertions (B2:true)

* invariant 2 à output assertions (B2:false)

4.

* loop invariant 3 à loop invariant 3(B1:true)

loop invariant 3 (See 2.b.) setB.get(j).intValue() == union.get(m).intValue(); isInUnion=true; m=union.size(); m++; m<union.size()

mß|U| mß|U|+1 |U|+1<|U| = false

loop invariant 3 (See 2.b.) Proof>

According to the symbolic execution of the code, “loop invariant 3 à loop invariant 3(B1:true)” is infeasible path.

* loop invariant 3 à loop invariant 3(B1:false)

loop invariant 3 (See 2.b.) m++; m<union.size()

mßm+1 m+1<|U|

loop invariant 3 (See 2.b.)

Proof>

union.size()>=0 && isInUnion==false This is true because the execution doesn’t change union and isInUnion

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because the code doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue())&&

This is true because the code doesn’t change union.

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because the code doesn’t change setA and union.

/* isInUnion should be true when 0..j-1 elements of setB are elements of union */ (if(isInUnion==true) \for all(int k=0; k<j; k++) \for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because isInUnion is false

5.

* input assertions à invariant 1

input assertions (see 2.b.) ArrayList<Integer> union = new ArrayList<Integer>(); int sizeA = setA.size(); int sizeB = setB.size(); boolean isInUnion = false; int i = 0; i>=sizeA

Uß{} sizeAß|A| sizeBß|B| isInUnionßfalse iß0 0>=sizeA (0=|A|)

Invariant 1 (see 2.b.)

Proof>

/* non negative size */ setA.size() >= 0 && setB.size() >= 0 && union.size() &&

This is true because |A|=0, |U|=0 and B doesn’t changed.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because it doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because it doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue()) &&

This is true because |U|=0.

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because |A|=0 and |U|=0.

* input assertions à loop invariant 1

input assertions (see 2.b.) ArrayList<Integer> union = new ArrayList<Integer>(); int sizeA = setA.size(); int sizeB = setB.size(); boolean isInUnion = false; int i = 0; i<sizeA

Uß{} sizeAß|A| sizeBß|B| isInUnionßfalse iß0 0<|A|

loop invariant 1(see 2.b.)

Proof>

sizeA>=0 && This is true because 0<|A| /* duplicated elements are not allowed */ This is true because the code doesn’t

(\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because the code doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue()) &&

This is true because 0=|U|

/* all elements of union should also be elements of setA */ (\for all(int k=0; k<union.size(); k++) \for some(int l=0; l<sizeA; l++) union.get(k).intValue() == setA.get(l).intValue()) &&

This is true because 0=|U|

/* 0..i-1 elements of setA should also be elements of union */ (if(i!=0) \for all(int k=0; k<i; k++) \for some(int l=0; l<union.size(); l++) setA.get(k).intValue() == union.get(l).intValue()) &&

This is true because i=0

/* i..sizeA-1 elements of setA should not be elements of union */ (\for all(int k=i; k<sizeA; k++) \for all(int l=0; l<union.size(); l++) setA.get(k).intValue() != union.get(l).intValue());

This is true because 0=|U|

* loop invariant 1 à invariant 1

Loop invariant 1 (see 2.b.) Union.add(setA.get(i)); i++ i>=sizeA

UßU∪A[i] ißi+1 i>=|A|

invariant 1 (see 2.b.)

Proof>

/* non negative size */ setA.size() >= 0 && setB.size() >= 0 && union.size() &&

This is true because A, B and U are not modified.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because it doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because it doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++)

This is true because U is exactly equal to A. A doesn’t have duplicated elements. So, U also doesn’t have duplicated

union.get(k).intValue() != union.get(l).intValue()) &&

elements.

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because A=U

* invariant 1 à output assertions

invariant 1 (see 2.b.) j=0; j>=sizeB return union

jß0 j>=|B| (0=|B|)

output assertions (see 2.b.)

Proof>

/* non negative size */ \result.size() >= 0 &&

This is true because the code doesn’t change U.

/* duplicated elements are not allowed */ (\for all(int i=0; i<\result.size()-1; i++) \for all(int j=i+1; j<\result.size(); j++) \result.get(i).intValue() != \result.get(j).intValue()) &&

This is true because the code doesn’t change U.

/* all elements of setA should also be elements of \result */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j<\result.size(); j++) setA.get(i).intValue() == \result.get(j).intValue()) &&

This is true because the code doesn’t change U.

/* all elements of setB should also be elements of \result */ (\for all(int i=0; i<setB.size(); i++) \for some(int j=0; j<\result.size(); j++) setB.get(i).intValue() == \result.get(j).intValue()) &&

This is true because 0=|B|

/* \result doesn’t allow to have elements which are not in setA or setB */ (\for all(int i=0; i<\result.size(); i++) \for some(int j=0; j<setA.size() || j<setB.size(); j++) if(j<setA.size()) \result.get(i).intValue() == setA.get(j).intValue() || If(j<setB.size()) \result.get(i).intValue() == setB.get(j).intValue());

This is true because the code doesn’t change U. What’s more 0=|B|.

* loop invariant 1 à loop invariant 1

loop invariant 1 (see 2.b.) union.add(setA.get(i)); i++; i<sizeA

UßU∪A[i] ißi+1 i<|A|

loop invariant 1 (see 2.b.)

Proof>

sizeA>=0 && This is true the code doesn’t change setA. /* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because the code doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue()) &&

This is true because setA doesn’t have duplicated elements. What’s more U will only have elements of A since UßU∪A[i].

/* all elements of union should also be elements of setA */ (\for all(int k=0; k<union.size(); k++) \for some(int l=0; l<sizeA; l++) union.get(k).intValue() == setA.get(l).intValue()) &&

This is true because U will only have elements of A since UßU∪A[i].

/* 0..i-1 elements of setA should also be elements of union */ (if(i!=0) \for all(int k=0; k<i; k++) \for some(int l=0; l<union.size(); l++) setA.get(k).intValue() == union.get(l).intValue()) &&

This is true because newly U will have A[i] since UßU∪A[i].

/* i..sizeA-1 elements of setA should not be elements of union */ (\for all(int k=i; k<sizeA; k++) \for all(int l=0; l<union.size(); l++) setA.get(k).intValue() != union.get(l).intValue());

This is true the code only update U by referring A[i]. It doesn’t refer any element of i..sizeA-1 th elements of setA.

* invariant 1 à loop invariant 2

invariant 1 (see 2.b.) j=0; j<sizeB

jß0 0<|B|

loop invariant 2 (see 2.b.)

Proof>

sizeB>=0 && This is true because input assertions hold this and the code doesn’t change setB

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because the code doesn’t change setB.

/* duplicated elements are not allowed */ This is true because loop invariant 1 holds

(\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue()) &&

this and the code only update U by referring A. A is also doesn’t have duplicated elements.

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because U will have all elements of A.

/* 0..j-1 elements of setB should also be elements of union */ (if(j!=0) \for all(int k=0; k<i; k++) \for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because j=0.

* loop invariant 2 à invariant 2

loop invariant 2 (see 2.b.) isInUnion = false; m=0; m>=union.size()

isInUnionßfalse mß0 0>=|U| (0=|U|)

Invariant 2 (see 2.b.)

Proof>

setA.size() >= 0 && setB.size() >= 0 && union.size() && This is true because the code doesn’t change A, B and U.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change A.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue())&&

This is true because the code doesn’t change B

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue())&&

This is true because |U|=0

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because loop invariant 2 holds this.

/* isInUnion should be true when 0..j-1 elements of setB are elements of union */ (if(isInUnion==true) \for all(int k=0; k<j; k++)

\for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because |U|=0

* loop invariant 2 à loop invariant 3

loop invariant 2 (see 2.b.) isInUnion = false; isInUnionßfalse

m=0; m<union.size()

mß0 0<|U|

loop invariant 3 (see 2.b.)

Proof>

union.size()>=0 && isInUnion==false This is true because 0<|U| and isInUnionßfalse

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because the code doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue())&&

This is true because the code doesn’t change union.

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because the code doesn’t change setA and union.

/* isInUnion should be true when 0..j-1 elements of setB are elements of union */ (if(isInUnion==true) \for all(int k=0; k<j; k++) \for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because isInUnion is false

* loop invariant 3 à invariant 2 (B1:true)

loop invariant 3 (see 2.b.) setB.get(j).intValue() == union.get(m).intValue() isInUnion = true; m = union.size(); m++; m>=union.size()

B[j]=U[m] isInUnionßtrue mß|U| mß|U|+1 |U|+1>|U|

Invariant 2 (see 2.b.)

Proof>

setA.size() >= 0 && setB.size() >= 0 && union.size() && This is true because the code doesn’t change A, B and U.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change A.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++)

This is true because the code doesn’t change B

\for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue())&& /* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue())&&

This is true because |U|=0

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because loop invariant 3 holds this.

/* isInUnion should be true when 0..j-1 elements of setB are elements of union */ (if(isInUnion==true) \for all(int k=0; k<j; k++)

\for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because B[j]=U[m]

* loop invariant 3 à invariant 2 (B1:false)

loop invariant 3 (see 2.b.) setB.get(j).intValue() != union.get(m).intValue() m++; m>=union.size()

B[j]≠U[m] mß|U|+1 m>=|U|

Invariant 2 (see 2.b.)

Proof>

setA.size() >= 0 && setB.size() >= 0 && union.size() && This is true because the code doesn’t change A, B and U.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change A.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue())&&

This is true because the code doesn’t change B

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue())&&

This is true because |U|=0

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because loop invariant 3 holds this.

/* isInUnion should be true when 0..j-1 elements of setB are elements of union */ (if(isInUnion==true) \for all(int k=0; k<j; k++)

\for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because loop invariant 3 holds this.

* loop invariant 3 à loop invariant 3(B1:true)

(See 4.)

* loop invariant 3 à loop invariant 3(B1:false)

(See 4.)

* invariant 2 à loop invariant 2(B2:true)

invariant 2 (see 2.b.) !isInUnion == true union.add(setB.get(j).intValue()); j++; j<sizeB

!false = true UßU∪B[j]. jßj+1 j<|B|

loop invariant 2 (see 2.b.)

Proof>

sizeB>=0 && This is true because the code doesn’t change setB

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because the code doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue()) &&

This is true because invariant 2 holds this and the code only update U by referring B. B is also doesn’t have duplicated elements.

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because invariant 2 holds this

/* 0..j-1 elements of setB should also be elements of union */ (if(j!=0) \for all(int k=0; k<i; k++) \for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because invariant 2 holds this and the code updates U by UßU∪B[j]. .

* invariant 2 à loop invariant 2(B2:false)

invariant 2 (see 2.b.) !isInUnion == false j++; j<sizeB

!true = true jßj+1 j<|B|

loop invariant 2 (see 2.b.)

Proof>

sizeB>=0 && This is true because the code doesn’t change setB

/* duplicated elements are not allowed */ (\for all(int i=0; i<setA.size()-1; i++) \for all(int j=i+1; j<setA.size(); j++) setA.get(i).intValue() != setA.get(j).intValue()) &&

This is true because the code doesn’t change setA.

/* duplicated elements are not allowed */ (\for all(int i=0; i<setB.size()-1; i++) \for all(int j=i+1; j<setB.size(); j++) setB.get(i).intValue() != setB.get(j).intValue());

This is true because the code doesn’t change setB.

/* duplicated elements are not allowed */ (\for all(int k=0; k<union.size()-1; k++) \for all(int l=k+1; l< union.size(); l++) union.get(k).intValue() != union.get(l).intValue()) &&

This is true because invariant 2 holds this and the code only update U by referring B. B is also doesn’t have duplicated elements.

/* all elements of setA should also be elements of union */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j< union.size(); j++) setA.get(i).intValue() == union.get(j).intValue()) &&

This is true because invariant 2 holds this

/* 0..j-1 elements of setB should also be elements of union */ (if(j!=0) \for all(int k=0; k<i; k++) \for some(int l=0; l<union.size(); l++) setB.get(k).intValue() == union.get(l).intValue());

This is true because invariant 2 holds this and the code doesn’t change B. .

* invariant 2 à output assertions (B2:true)

invariant 2 (see 2.b.) !isInUnion == true union.add(setB.get(j).intValue()); j++; j>=sizeB

!false = true UßU∪B[j]. jßj+1 j>=|B|

output assertions (see 2.b.)

Proof>

/* non negative size */ \result.size() >= 0 &&

This is true because the code only increase U size.

/* duplicated elements are not allowed */ (\for all(int i=0; i<\result.size()-1; i++) \for all(int j=i+1; j<\result.size(); j++) \result.get(i).intValue() != \result.get(j).intValue()) &&

This is true because invariant 2 holds this and U only add elements in B. B also doesn’t allow duplicated elements.

/* all elements of setA should also be elements of \result */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j<\result.size(); j++) setA.get(i).intValue() == \result.get(j).intValue()) &&

This is true because invariant 2 holds this

/* all elements of setB should also be elements of \result */ This is true because invariant 2 holds this

(\for all(int i=0; i<setB.size(); i++) \for some(int j=0; j<\result.size(); j++) setB.get(i).intValue() == \result.get(j).intValue()) &&

and the code only updates U by using B’s element.

/* \result doesn’t allow to have elements which are not in setA or setB */ (\for all(int i=0; i<\result.size(); i++) \for some(int j=0; j<setA.size() || j<setB.size(); j++) if(j<setA.size()) \result.get(i).intValue() == setA.get(j).intValue() || If(j<setB.size()) \result.get(i).intValue() == setB.get(j).intValue());

This is true because the code doesn’t change U except by using B|.

* invariant 2 à output assertions (B2:false)

invariant 2 (see 2.b.) !isInUnion == false j++; j>=sizeB

!true = false jßj+1 j>=|B|

output assertions (see 2.b.)

Proof>

/* non negative size */ \result.size() >= 0 &&

This is true because the code doesn’t change U.

/* duplicated elements are not allowed */ (\for all(int i=0; i<\result.size()-1; i++) \for all(int j=i+1; j<\result.size(); j++) \result.get(i).intValue() != \result.get(j).intValue()) &&

This is true because the code doesn’t change U.

/* all elements of setA should also be elements of \result */ (\for all(int i=0; i<setA.size(); i++) \for some(int j=0; j<\result.size(); j++) setA.get(i).intValue() == \result.get(j).intValue()) &&

This is true because the code doesn’t change U.

/* all elements of setB should also be elements of \result */ (\for all(int i=0; i<setB.size(); i++) \for some(int j=0; j<\result.size(); j++) setB.get(i).intValue() == \result.get(j).intValue()) &&

This is true because the code doesn’t change U.

/* \result doesn’t allow to have elements which are not in setA or setB */ (\for all(int i=0; i<\result.size(); i++) \for some(int j=0; j<setA.size() || j<setB.size(); j++) if(j<setA.size()) \result.get(i).intValue() == setA.get(j).intValue() || If(j<setB.size()) \result.get(i).intValue() == setB.get(j).intValue());

This is true because the code doesn’t change U.

6.

setUnion’s termination condition is defined by 3(1,2,3) branch nodes in the below diagram.

(1): the value of i will be increased by 1 at the every iteration. What’s more, sizeA is fixed at the loop. Therefore, i will be increased to make i<sizeA to false, so it will break the loop.

(2): the value of j will be increased by 1 at the every iteration. What’s more, sizeB is fixed at the loop. Therefore, j will be increased to make j<sizeB to false, so it will break the loop.

(3): the value of m will be increased by 1 or union.size()+1 at the every iteration. During the loop execution, union.size() is fixed. Therefore, the loop will be stop on the both increasing cases.

Therefore, the program terminates.

The solution is based on Seung Yeob Shin’s answer.