#OK to post homework
#Joseph Koutsoutis, 03-02-2025, Assignment 10

read `C10.txt`:

#1

SimulateNAND := proc(n,k,K) local i, P, c:
  c := 0:
  for i from 1 to K do:
    P := RSLP(n,k):
    c += nops(EvalSP(P,n)):
  od:
  evalf(c / K):
end:

#SimulateNAND(10,  5, 1000) outputted 696.576
#SimulateNAND(10, 10, 1000) outputted 661.712
#SimulateNAND(10, 20, 1000) outputted 645.716
#SimulateNAND(10, 50, 1000) outputted 635.187


#2

LD:=proc(p):evalb(rand(1..denom(p))()<=numer(p)):end: 

Monotone := proc(n,k,p) local P, i, i1, j1, ra:
  P := [seq(i, i=1..n)]:
  for i from n+1 to k+n do:
    ra := rand(1..i-1):
    i1 := ra():
    j1 := ra():
    while i1 >= j1 do:
      i1 := ra():
      j1 := ra():  
    od: 
    if LD(p) then:
      P := [op(P), [i1, j1, AND]]:
    else:
      P := [op(P), [i1, j1, OR]]:
    fi:
  od:
  P:
end:

EvalMonotoneP1 := proc(P,IN) local n,P1,i,i1,j1:
P1:=IN:
n:=nops(IN):
for i from n+1 to nops(P) do
 i1:=P[i][1]:
 j1:=P[i][2]:
  P1:=[op(P1),P[i][3](P1[i1],P1[j1])]:
od:

P1[-1]:
end:

EvalMonotone:=proc(P,n) local V,v,T:
V:=TF(n):
T:={}:
for v in V do
 if EvalMonotoneP1(P,v) then
   T:=T union {v}:
 fi:
od:
T:
end:

SimulateMonotone := proc(n,k, p, K) local i, P, c:
  c := 0:
  for i from 1 to K do:
    P := Monotone(n,k,p):
    c += nops(EvalMonotone(P,n)):
  od:
  evalf(c / K):
end:

#The following

#SimulateMonotone(10,5, 1/2,1000);
#SimulateMonotone(10,10, 1/2, 1000);
#SimulateMonotone(10,20, 1/2, 1000);
#SimulateMonotone(10,50, 1/2, 1000);
#SimulateMonotone(10,5, 3/4,1000);
#SimulateMonotone(10,10, 3/4, 1000);
#SimulateMonotone(10,20, 3/4, 1000);
#SimulateMonotone(10,50, 3/4, 1000);
#SimulateMonotone(10,5, 1,1000);
#SimulateMonotone(10,10, 1, 1000);
#SimulateMonotone(10,20, 1, 1000);
#SimulateMonotone(10,50,1, 1000);

#outputted

#521.2000000
#512.6080000
#525.8280000
#493.6220000
#361.0240000
#320.7760000
#277.0940000
#230.8250000
#194.7200000
#150.5120000
#92.27800000
#42.92400000