, , , ,

[SOLVED] Cspb 3155: assignment 7

$25

File Name: Cspb_3155:_assignment_7.zip
File Size: 216.66 KB

Categories: , , , , Tags: , , , ,
5/5 - (1 vote)
5/5 – (1 vote)

Problem 1 (20 points): CPS Style Transformation

Reimplement the programs below in the CPS style.

A (10 points)

Convert helloUp, doubleUp and mainFun into the CPS functions helloUp_kdoubleUp_kmainFun_k. They should take continuations that are of type String => String.

def helloUp(x: String): String = {
    "Hello " + x
}

def doubleUp(x: String): String = {
    x + x
}

def mainFun(x: String): String = {
    doubleUp(helloUp(x) + "World")
}
??? // YOUR CODE HERE
//BEGIN TEST
assert(helloUp_k("World", x => x) == "HelloWorld", "Test 1, Set 1 Failed" )
assert(doubleUp_k("World", x => x) == "WorldWorld", "Test 2 Set 1 Failed" )
assert(mainFun_k("Donkey", x => x) == "HelloDonkeyWorldHelloDonkeyWorld", "Test 3 Set 1 Failed")
passed(5)
//END TEST
//BEGIN TEST
assert(helloUp_k("Hello", x => ("*"+x+"*")) == "*HelloHello*", "Test 1, Set 2 Failed")
assert(doubleUp_k("HelloWorld", x => ("*"+x+"*")) == "*HelloWorldHelloWorld*", "Test 2, Set 2 Failed")
assert(mainFun_k("Cruel", x => ("*"+x+"*")) == "*HelloCruelWorldHelloCruelWorld*", "Test 3, Set 2 Failed")
passed(5)
//END TEST

B (10 points)

Convert the following program into CPS.

def util(x: Int):String = {
    val v1 = 2 * x
    v1.toString
}

def fun1(x: String): Int = {
    val v1 = util(x.toInt)
    v1.toInt
}

def fun2(x: String): String = {
    util(x.toInt)
}

def mainFun(x: String): Int = {
    val v1 = fun2(x)
    val v2 = fun1(x)
    val v3 = v1.length
    v2 - v3
}

To enable this create a polymorphic versions of each function.

def util_k[T](x: Int, k: String => T): T
def fun1_k[T](x: String, k: Int => T):T
def fun2_k[T] (x: String, k: String => T):T 
def mainFun_k[T](x: String, k: Int => T ):T
??? // YOUR CODE HERE
//BEGIN TEST
assert(util_k(10, _ + "d") == "20d", "Test 1 failed")
assert(util_k(21, Some[String]) == Some("42"), "Test 2 failed")
passed(4)
//END TEST
//BEGIN TEST
assert(fun1_k("10", Some[Int]) == Some(20), "Test 1 failed")
assert(fun2_k("-6", _ + "3sdf") == "-123sdf", "Test 2 failed")
passed(2)
//END TEST
//BEGIN TEST
mainFun_k[Unit]("217", println)
mainFun_k[Unit]("5000", println)
mainFun_k[Unit]("0", println)
assert(mainFun_k[String]("217", x=>(x.toString)) == "431", "Test 2, Set 1 Failed")
assert(mainFun_k[Int]("217", x=>x) == 431, "Test 3, Set 1 Failed")
assert(mainFun_k[Int]("5000", x=>x) == 9995, "Test 4, Set 1 Failed")
assert(mainFun_k[List[Int]]("5000", x => List(x)) == List(9995), "Test 5, Set 1 Failed")
passed(4)
//END TEST

Problem 2 (25 points): Regular Expression Pattern Matching and Continuations

Consider the problem of pattern matching regular expressions. The grammar for regular expressions are given as

RegExpr||||Atom(String)Or(RegExpr,RegExpr)Concat(RegExpr,RegExpr)KleeneStar(RegExpr)And(RegExpr,RegExpr)RegExpr→Atom(String)|Or(RegExpr,RegExpr)|Concat(RegExpr,RegExpr)|KleeneStar(RegExpr)|And(RegExpr,RegExpr)

Given a string, ss and regular expression rr, we wish to define a function Matches(r,s)Matches(r,s) which returns a tuple (v1,j)(v1,j)

  • Wherein v1v1 is either truetrue if some prefix of the string ss matches the expression rr or falsefalse otherwise.
  • If v1=truev1=true, then jj denotes the position where the match ends, such that j0j≥0 and j<length(s)j<length(s). In other words, the substring s(0),,s(j)s(0),…,s(j) matches the regular expression rr.
  • If falsefalse, we will simply set j=1j=−1.

We will use operational semantics rules to define MatchesMatches.

Atom

s(0,,j)=tMatches(Atom(t),s)=(true,j)(atom-match)s(0,…,j)=tMatches(Atom(t),s)=(true,j)(atom-match)
t is not a prefix of sMatches(Atom(t),s)=(false,1)(atom-no-match)t is not a prefix of sMatches(Atom(t),s)=(false,−1)(atom-no-match)

Or

Matches(r1,s)=(v1,j1), Matches(r2,s)=(v2,j2)Matches(Or(r1, r2),s)=(v1 or v2,max(j1,j2))(or-match)Matches(r1,s)=(v1,j1), Matches(r2,s)=(v2,j2)Matches(Or(r1, r2),s)=(v1 or v2,max(j1,j2))(or-match)

Concat

Matches(r1,s)=(true,j1), Matches(r2,s(j1+1,,n))=(true,j2)Matches(Concat(r1, r2),s)=(true,j1+j2+1)(concat-match)Matches(r1,s)=(true,j1), Matches(r2,s(j1+1,…,n))=(true,j2)Matches(Concat(r1, r2),s)=(true,j1+j2+1)(concat-match)
Matches(r1,s)=(false,1)Matches(Concat(r1, r2),s)=(false,1)(concat-no-match-1)Matches(r1,s)=(false,−1)Matches(Concat(r1, r2),s)=(false,−1)(concat-no-match-1)
Matches(r1,s)=(true,j1),  Matches(r2,s)=(false,1)Matches(Concat(r1, r2),s)=(false,1)(concat-no-match-2)Matches(r1,s)=(true,j1),  Matches(r2,s)=(false,−1)Matches(Concat(r1, r2),s)=(false,−1)(concat-no-match-2)

Kleene Star

Matches(r,s)=(true,j1), n=length(s), Matches(KleeneStar(r),s(j+1,,n))=(true,j2)Matches(KleeneStar(r),s)=(true,j1+j2+1)(kleene-star-match)Matches(r,s)=(true,j1), n=length(s), Matches(KleeneStar(r),s(j+1,…,n))=(true,j2)Matches(KleeneStar(r),s)=(true,j1+j2+1)(kleene-star-match)
Matches(r,s)=(false,1)Matches(KleeneStar(r),s)=(true,1)(kleene-star-no-match)Matches(r,s)=(false,−1)Matches(KleeneStar(r),s)=(true,−1)(kleene-star-no-match)

The Kleene-star-no-match rule looks very strange on first sight. But really, it is trying to say that any string matches the Kleene star of a regular expression. However, if the inner regular expression does not match, the Kleene star matches trivially with a match of length 0.

A (10 points)

Complete the code below for evaluating the semantics above.

sealed trait RegExp
case class Atom(s: String) extends RegExp
case class Or(r1: RegExp, r2: RegExp) extends RegExp
case class Concat(r1: RegExp, r2: RegExp) extends RegExp
case class KleeneStar(r1: RegExp) extends RegExp

def isPrefixOf(t: String, s: String) = {
    /* If string t is a prefix of s, then return true,
       else return false
       */
    s.startsWith(t)
}

def evalRegexp(r: RegExp, s: String ): (Boolean, Int) = r match {
    case Atom(t) => {
        ??? // YOUR CODE HERE
    }
    
    case Or(r1, r2) => {
        val (v1, j1) = evalRegexp(r1, s)
        val (v2, j2) = evalRegexp(r2, s)
        ((v1||v2), math.max(j1, j2) )
    }
    
    case Concat(r1, r2) => {
        ??? // YOUR CODE HERE
    }
    
    case KleeneStar(rHat) => {
        val (v1, j1) = evalRegexp(rHat, s)
        if (v1) {
            val (v2, j2) = evalRegexp(KleeneStar(rHat), s.substring(j1+1, s.length))
            (true, j1+1+j2)
        } else {
            (true, -1)
        }
    }
    
    
}
//BEGIN TEST
assert( evalRegexp(Atom("hello"), "helloworld") == (true, 4) , "Test 1 failed")
assert(evalRegexp(Atom("hello"), "Helloworld") == (false, -1), "Test 2 failed")
assert(evalRegexp(Or(Atom("hello"), Atom("Hellow")), "Helloworld") == (true, 5), "Test 3 failed")
passed(4)
//END TEST
//BEGIN TEST
assert(evalRegexp(KleeneStar(Atom("H")), "Helloworld") == (true, 0), "Test 4 failed")
assert(evalRegexp(Concat(Atom("hell"), Atom("owor")), "helloworld") == (true, 7), "Test 5 failed")
passed(3)
//END TEST
//BEGIN TEST
assert(evalRegexp(Concat( Or( Atom("what"), Or(Atom("why"), Atom("when") )), KleeneStar(Or(Atom("what"), Atom("why") ))), "whatwhywhatwhatwhatwhywhenwhere") == (true, 21), "Test 6 failed")
passed(3)
//END TEST

B (15 points)

Reimplement the interpreter in the CPS so that all recursion happens at the tail position.

def isPrefixOf_k[T](t: String, s: String, k: Boolean => T): T = {
    /* If string t is a prefix of s, then return true,
       else return false
       */
    ??? // YOUR CODE HERE
}


def evalRegexp_k[T](r: RegExp, s: String, k: (Boolean, Int) => T ): T = r match {
    case Atom(t) => {
        isPrefixOf_k(t, s, v => {
            ??? // YOUR CODE HERE
        })    
    }
    
    case Or(r1, r2) => {
        evalRegexp_k(r1, s, (v1:Boolean, j1:Int)=> {
            evalRegexp_k(r2, s.substring(j1+1, s.length), (v2:Boolean, j2: Int) => {
                k((v1 || v2), math.max(j1,j2))    
            })
        })
    }
    
    case Concat(r1, r2) => {
        ??? // YOUR CODE HERE
    }
    
    case KleeneStar(rHat) => {
        evalRegexp_k(rHat, s, (v1: Boolean, j1: Int) => {
                ??? // YOUR CODE HERE
        })
        
    }
    
    
}
//BEGIN TEST
assert( evalRegexp_k[Int](Atom("hello"), "helloworld", (x: Boolean, y: Int) => {y} ) == 4, "Test 1 failed")
assert( evalRegexp_k[Boolean](Atom("hello"), "Helloworld", (x: Boolean, y: Int) => {x} ) == false, "Test 2 failed")
passed(5)
//END TEST
//BEGIN TEST
assert( evalRegexp_k[String](Or(Atom("hello"), Atom("Hellow")), "Helloworld", (x: Boolean, y: Int) => {y.toString} ) == "5", "Test 2 failed")
passed(5)
//END TEST
//BEGIN TEST
assert(evalRegexp_k(KleeneStar(Atom("H")), "HHHHHelloworld", (x: Boolean, y: Int) => (x,y)) == (true, 4), "Test 4 failed")
assert(evalRegexp_k(Concat(Atom("hell"), Atom("owor")), "helloworld", (x: Boolean, y: Int) => (y)) == 7, "Test 5 failed")
assert(evalRegexp_k(Concat( Or( Atom("what"), Or(Atom("why"), Atom("when") )), KleeneStar(Or(Atom("what"), Atom("why") ))), "whatwhywhatwhatwhatwhywhenwhere", (x: Boolean, y:Int) => (x, y)) == (true, 21), "Test 6 failed")
passed(5)
//END TEST

Reviews

There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.

Shopping Cart
[SOLVED] Cspb 3155: assignment 7
$25