Lab 7: Call the Plumber (a.k.a. A Tree By Any Other Name)

The purpose of this lab is to:

  • give you practice modeling phenomena in our world using Trees
  • give you practice working with structurally recursive data definitions
  • give you practice writing functions using a template for structurally recursive data definitions

Create the file lab07.arr and copy/paste the following header comment into it:

#|
  CMPU-101
  Fall 2021
  Lab 7
  Name: your name
|#

As usual, ask your instructor or a coach if you're stuck. Remember to save your work every so often.

We would like to represent pipelines in our program. A pipeline has faucets (opened or closed):

faucet open       faucet closed
image of an open faucet       image of an open faucet

straight parts (copper or lead):

one straight pipe leading to a faucet             two straight pipes leading to a faucet
image of an open faucet             image of an open faucet

and branches. Here are two pipelines with branches:

pipeline with one branch pipeline with several branches
image of an open faucet image of an open faucet

We can represent pipelines as described above with the appropriate data definition. Since our pipelines consist of multiple instances of faucets, straight pipes, and branches, our data definition includes these three varieties. Copy this data definition and examples of pipelines into your ''lab07.arr'' file:

data Pipeline:
  | faucet(open :: Boolean)
  | straight(kind :: String, pl :: Pipeline)
  | branch(pl1 :: Pipeline, pl2 :: Pipeline)
end

# Examples of pipelines
f-closed = faucet(false)
f-open = faucet(true)
straight-cop = straight("copper", f-closed)
straight-cop-lead = 
  straight("copper", 
    straight("lead", f-closed))
branching-pipeline = 
  branch(
    branch(
      straight("copper", f-open), 
      f-closed),
    branch(
      f-closed,
      f-closed))

Since we defined a new type of data (Pipeline), we need to create a new Template for functions that take a Pipeline as input. Copy this template into your ''lab07.arr'' file:

#|
fun pipeline-fun(pl :: Pipeline) -> ...:
  doc: "template for a function that takes a pipeline"
  cases (Pipeline) pl:
    | faucet(open) => 
      ... open ...
    | straight(kind, pl1) => 
      ... kind ... 
      ... pipeline-fun(pl1) ...
    | branch(pl1, pl2) =>
      ... pipeline-fun(pl1) ...
      ... pipeline-fun(pl2) ...
  end
where: 
  pipeline-fun(...) is ...
end
|#

# Exercise 1

# Exercise 2

# Exercise 3

# Exercise 4

# Exercise 5

Implement the function, ''is-water-running'', which takes a pipeline and determines whether any faucets are open.

To help you get started, here's our solution. Copy/paste it into your ''lab07.rkt'' file. Study it, run it, and make sure you understand how it works. Then go on to the next exercise.

# Exercise 1

fun is-water-running(pl :: Pipeline) -> Boolean:
  doc: "determines whether any faucets are open in pl"
  cases (Pipeline) pl:
    | faucet(open) => 
      open
    | straight(kind, pl1) => 
      is-water-running(pl1)
    | branch(pl1, pl2) =>
      is-water-running(pl1) or is-water-running(pl2)
  end
where: 
  is-water-running(f-open) is true
  is-water-running(f-closed) is false
  is-water-running(straight-cop) is false
  is-water-running(straight-cop-lead) is false
  is-water-running(branching-pipeline) is true
end

Implement the function, ''count-faucets'', which takes a pipeline and counts the number of faucets.

Implement the function, ''count-open'', which takes a pipeline and counts the number of open faucets.

Implement the function, ''modernize'', which takes a pipeline and converts all "lead" straight pipes to "copper"

Implement the function, ''off'', which takes a pipeline and turns off all the faucets