html("

A JS-EDEN construal of bubblesort

When you load the construal, you get a (rather scruffy!) bubblesort display that animates in response to mousepresses in the canvas.

The key observables are fairly easy to identify from the Script Generator.

The array of values is in a list called val - when you assign values you can assign a list to the array val, or new values to the individual components using val[2] = 10; etc.

There are two 'higher level' observables that are meaningful when the sorting activity is in progress (as opposed to when you're messing about with the construal) - bs_pass, which says which pass is currently in progress, and bs_pos which tells you where the comparison of elements in the current pass is currently being made. The agents next_pos and next_pass are direct interpretations of what conditions are observed when bs_pos and bs_pass are changed.

You can initialise the construal by resetting the array val, and assigning


nexta = 0;
bs_pass=1;
bs_pos =1;

- there are some built-in initial settings for val:

val_set0 = [7,56,19,90,21,3,46];
val_set1 = [1,3,5,6,8,9,90];
val_set2 = [100,98,86,76,64,46,29];

which you can use for illustrative purposes. When you load the construal the setting is

val = val_set0;

An instructive feature is that the Figure 1 heading asserts that the array is sorted when the value of the observable sorted is true:

sorted is (val1<=val2) && (val2<=val3) && (val3<=val4)
        && (val4 <= val5) && (val5 <= val6) && (val6<=val7);
- in fact, this is not in the spirit of bubblesorting, where the array is only deemed to be sorted when the condition sorted has been proved to be true.

The observable which determines the text label for the Figure is


UnsS is (sorted)?\"S\":\"Uns\";
- a better definition might be

UnsS is (sorted && (bs_pass>6))?\"S\":\"Uns\";
- though this is conservative in the sense that the array may have been confirmed to sorted long before the bubbelsorting process has reached the end. The construal could of course be modified to take account of this.

"); ## bubblesort.js-e val_set0 = [7,56,19,90,21,3,46]; val_set1 = [1,3,5,6,8,9,90]; val_set2 = [100,98,86,76,64,46,29]; val = val_set0; UnsS is (sorted)?"S":"Uns"; sorted is (val1<=val2) && (val2<=val3) && (val3<=val4) && (val4 <= val5) && (val5 <= val6) && (val6<=val7); val1 is val[1]; val2 is val[2]; val3 is val[3]; val4 is val[4]; val5 is val[5]; val6 is val[6]; val7 is val[7]; proc exc { para i,j; auto tmp; tmp = val[i]; val[i] = val[j]; val[j] = tmp; } first=1; last=7; func maxfl { para list, f,l; auto i, max; max = list[f]; for(i=f;i<=l;i++){ if (list[i] >= max) { max = list[i]; } } return max; } func minfl { para list, f,l; auto i, min; min = list[f]; for(i=f;i<=l;i++){ if (list[i] <= min) { min = list[i]; } } return min; } minelt is minfl(val,first,last); maxelt is maxfl(val,first,last); RED="red"; GREEN = "green"; GREEN="blue"; BLACK="black"; first = 1; last = 7; func ixminfl { para l,fst,lst; auto result; result=fst; if (fst!=lst) while (l[result]!=minfl(l,fst,lst)) result++; return result; } func ixmaxfl { para l,fst,lst; auto result; result=fst; if (fst!=lst) while (l[result]!=maxfl(l,fst,lst)) result++; return result; } ix_min is ixminfl(val, first, last); ix_max is ixmaxfl(val,first,last); eltarr is [elt1, elt2, elt3, elt4, elt5, elt6, elt7]; RlineB is Point(eltarr[Rmark].x, eltarr[Rmark].y+15); LlineB is Point(eltarr[Lmark].x, eltarr[Lmark].y+15); RlineT is Point(eltarr[Rmark].x, eltarr[Rmark].y+25); LlineT is Point(eltarr[Lmark].x, eltarr[Lmark].y+25); Firstpt is Point(eltarr[first].x, eltarr[first].y+20); Lastpt is Point(eltarr[last].x, eltarr[first].y+20); Lline is mkline(LlineT, LlineB); Rline is mkline(RlineT, RlineB); rangeline is mkline(Firstpt, Lastpt); Rmark is first; Lmark is last; /* range line for bubblesort Rmark is 7-bs_pass+1; Lmark is bs_pos; first = 1; last is Rmark; */ /* Find a Function list ## Text(text, x, y, colour, size); ## Point(x,y) ## Line(x1,y1,x2,y2,colour) */ fig1 is Text("Figure 1: Unsorted array of elements", 250, 15); ## picture is [fig1]; SW is Point(75, 50); SE is Point(425, 50); NW is Point(75, 70); NE is Point(425, 70); W is mkline(NW, SW); E is mkline(NE, SE); S is mkline(SE, SW); N is mkline(NE, NW); V1 is mkline(S1, N1); V2 is mkline(S2, N2); V3 is mkline(S3, N3); V4 is mkline(S4, N4); V5 is mkline(S5, N5); V6 is mkline(S6, N6); S1 is Point(75 + sep, 50); S2 is Point(75 + 2 * sep, 50); S3 is Point(75 + 3 * sep, 50); S4 is Point(75 + 4 * sep, 50); S5 is Point(75 + 5 * sep, 50); S6 is Point(75 + 6 * sep, 50); N1 is Point(75 + sep, 70); N2 is Point(75 + 2 * sep, 70); N3 is Point(75 + 3 * sep, 70); N4 is Point(75 + 4 * sep, 70); N5 is Point(75 + 5 * sep, 70); N6 is Point(75 + 6 * sep, 70); func mkline { para p,q; return Line(p.x,p.y,q.x,q.y); } sep = 50; elt1 is midpt(SW,N1); elt2 is midpt(S1,N2); elt3 is midpt(S2,N3); elt4 is midpt(S3,N4); elt5 is midpt(S4,N5); elt6 is midpt(S5,N6); elt7 is midpt(S6,NE); func midpt { para p,q; return Point((p.x+q.x)/2, (p.y+q.y)/2); } fig1 is Text("Figure 1: " // UnsS // "orted array of elements", 150, 35); v1 is Text(str(val1), elt1.x, elt1.y, col_v1); v2 is Text(str(val2), elt2.x, elt2.y, col_v2); v3 is Text(str(val3), elt3.x, elt3.y, col_v3); v4 is Text(str(val4), elt4.x, elt4.y, col_v4); v5 is Text(str(val5), elt5.x, elt5.y, col_v5); v6 is Text(str(val6), elt6.x, elt6.y, col_v6); v7 is Text(str(val7), elt7.x, elt7.y, col_v7); labels is [fig1, v1, v2, v3, v4, v5, v6, v7]; points is [SW, SE, NW, NE, S1, S2, S3, S4, S5, S6, N1, N2, N3, N4, N5, N6, elt1, elt2, elt3, elt4, elt5, elt6, elt7]; lines is [W, E, S, N, V1, V2, V3, V4, V5, V6, Lline, Rline, rangeline]; picture is labels // points // lines; picture is labels // lines; col_v1 is (val1==minelt) ? RED: ((val1==maxelt) ? GREEN: BLACK); col_v2 is (val2==minelt) ? RED: ((val2==maxelt) ? GREEN: BLACK); col_v3 is (val3==minelt) ? RED: ((val3==maxelt) ? GREEN: BLACK); col_v4 is (val4==minelt) ? RED: ((val4==maxelt) ? GREEN: BLACK); col_v5 is (val5==minelt) ? RED: ((val5==maxelt) ? GREEN: BLACK); col_v6 is (val6==minelt) ? RED: ((val6==maxelt) ? GREEN: BLACK); col_v7 is (val7==minelt) ? RED: ((val7==maxelt) ? GREEN: BLACK); ## bsagents.js-e proc nextastep: mousePressed { if (mousePressed && (nexta==0)) nexta++; } /* ## or alternatively, with an explicit button to initiate the next step: nextButt is Button("next", "Next step", 10,10,true); picture is [nextButt] // labels // lines; proc nextastep: next_clicked { if (next_clicked && (nexta==0)) nexta++; } */ nexta = 0; bs_pass=1; bs_pos =1; proc next_pass: nexta { if ((bs_pass <= 6)&&(bs_pos==(7-bs_pass+1))&&(nexta==1)) { bs_pass++; bs_pos=1; nexta=0; } } proc next_pos: nexta { if ((bs_pos <= 7-bs_pass)&&(nexta==1)) { if ((val[bs_pos]>val[bs_pos+1])) { exc(bs_pos, bs_pos+1); } bs_pos++; nexta=0; } } first is 1; last is 7-bs_pass+1; Rmark is 7-bs_pass+1; Lmark is bs_pos; first = 1; last is Rmark;