COMP3161/9164 Concepts of Programming Languages
Term 3, 2025

Tutorial - Completed (Week 2)

Table of Contents

1. Predicate Logic

1.1. Question 1

For which values of \(A\) and \(B\) does the boolean expression \(\varphi = \neg (A \Rightarrow B) \lor \neg B\) hold?

Using a truth table:

\(A\) \(B\) \(A \Rightarrow B\) \(\neg B\) \(\varphi\)
\(\bot\) \(\bot\) \(\top\) \(\top\) \(\top\)
\(\bot\) \(\top\) \(\top\) \(\bot\) \(\bot\)
\(\top\) \(\bot\) \(\bot\) \(\top\) \(\top\)
\(\top\) \(\top\) \(\top\) \(\bot\) \(\bot\)

This is an answer but it is not so informative. Using boolean algebra manipulation instead:

\begin{array}{lcl} \neg (A \Rightarrow B) \lor \neg B & = & \neg (\neg A \lor B) \lor \neg B \\ & = & (A \land \neg B) \lor \neg B \\ & = & (A \lor \neg B) \land (\neg B \lor \neg B) \\ & = & (A \lor \neg B) \land \neg B \\ & = & \neg B \\ \end{array}

Here we can see clearly that \(\varphi\) holds only when \(B\) is false, and the value of \(A\) does not matter.

1.2. Question 2

A binary connective \(\bullet\) is defined as follows:

\(A\) \(B\) \(A\ \bullet\ B\)
\(\bot\) \(\bot\) \(\top\)
\(\bot\) \(\top\) \(\bot\)
\(\top\) \(\bot\) \(\top\)
\(\top\) \(\top\) \(\top\)

Restate the formula \(A \lor B\) in terms of \(\bullet\). What is the \(\bullet\) connective?

\(A \bullet \neg B\), \(\bullet\) is a flipped implication operator. The ex falso quodlibet principle is relevant here: from false, you can prove anything.

1.3. Question 3

Assuming that \(F(x)\) states that the person \(x\) is my friend and that \(P(x)\) states that the person \(x\) is perfect, what is a logical translation of the phrase "None of my friends are perfect"?

One option is \(\lnot \exists x. \; F(x) \land P(x)\), which can be read literally as saying "there does not exist a person \(x\) such that they are both my friend and perfect" in plain English. There are a number of other equally-valid translations too:

  • \(\forall x. \; F(x) \Rightarrow \lnot P(x)\), which can be read as saying "if a person is my friend, then they aren't perfect".
  • \(\forall x. \; P(x) \Rightarrow \lnot F(x)\), which can be read as saying "if a person is perfect, then they aren't my friend".

The logical formulae for all 3 are equivalent. As an exercise, prove this!

2. Haskell

  1. Write a Haskell function mySum that sums all elements in a list of numbers. Feel free to use the following template:

    mySum :: [Int] -> Int
    mySum []     = ???
    mySum (n:ns) = ???
    
  2. Write a Haskell function myProduct that multiplies all elements in a list of numbers.
  3. You probably used copypaste to solve the previous question, didn't you? No reason to be ashamed, we've all done it! But let's try not to.

    Find a generalisation myBinop that applies a given binary operator f with unit element z to a list of numbers. We will then be able to define myProduct and mySum using myBinop.

    myBinop :: (Int -> Int -> Int) -> Int -> ([Int] -> Int)
    myBinop f z [] = ???
    myBinop f z (n:ns) = ???
    
    mySum :: [Int] -> Int
    mySum ns = myBinop (+) 0 ns
    
    myProduct :: [Int] -> Int
    myProduct ns = myBinop (*) 1 ns
    
  4. We just reinvented a wheel. The fold functions are general-purpose library functions that completely subsume myBinop. Try to implement mySum and myProduct using foldr instead of myBinop.

    The linked library documentation references a lot of concepts that we don't assume familiarity with, so don't worry if you don't fully understand it. Perhaps start by looking at the examples.

mySum :: [Int] -> Int
mySum [] = 0
mySum (n:ns) = n + mySum ns

myProduct :: [Int] -> Int
myProduct [] = 1
myProduct (n:ns) = n*myProduct ns

myBinop :: (Int -> Int -> Int) -> Int -> ([Int] -> Int)
myBinop f z [] = z
myBinop f z (n:ns) = n `f` myBinop f z ns

mySum2 :: [Int] -> Int
mySum2 = myBinop (+) 0

myProduct2 :: [Int] -> Int
myProduct2 = myBinop (*) 1

mySum3 :: [Int] -> Int
mySum3 = foldr (+) 0

myProduct3 :: [Int] -> Int
myProduct3 = foldr (*) 1

3. Inductive Types

Consider the (++) operator in Haskell.

(++) :: [a] -> [a] -> [a]
[]     ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
  1. State the formal properties of left identity, right identity and associativity for (++).
  2. Try to prove these properties. In some cases, you may need to perform induction on the structure of lists. The base case of the induction will be for the empty list, and the inductive case will be to show your property for a list (x:xs), assuming the property for the list xs (this assumption is called the inductive hypothesis).

1:

[] ++ ys == ys -- left identity
xs ++ [] == xs -- right identity
(xs ++ (ys ++ zs)) == ((xs ++ ys) ++ zs) -- associativity

2: Proving left identity is a trivial consequence of the first defining equation of (++).

For right identity, we want to prove xs ++ [] == xs for all xs.

Base case: xs == [], we must show [] ++ [] == [], which follows from the first defining equation.

Inductive case: xs == (x:xs'), assuming the inductive hypothesis that:

xs' ++ [] == xs'

We must show that:

(x:xs') ++ [] == (x:xs')

By equational reasoning:

LHS == (x:xs') ++ [] 
    == x:(xs' ++ []) -- Equation 2
    == (x:xs')       -- Inductive Hypothesis
    == RHS

Thus right identity is proven by induction on lists.

For associativity, we want to prove (xs ++ ys) ++ zs == xs ++ (ys ++ zs) for all xs, ys and zs. By induction on xs:

Base case: xs == [], we must show ([] ++ ys) ++ zs == [] ++ (ys ++ zs). Simplifying with the first defining equation, both sides become ys ++ zs.

Inductive case: xs == (x:xs'). Assuming the inductive hypothesis that:

(xs' ++ ys) ++ zs == xs' ++ (ys ++ zs)

We must show that:

((x:xs') ++ ys) ++ zs == (x:xs') ++ (ys ++ zs)

By equational reasoning:

LHS == ((x:xs') ++ ys) ++ zs 
    == (x:(xs' ++ ys)) ++ zs -- Equation 2
    == x:((xs' ++ ys) ++ zs) -- Equation 2
    == x:(xs' ++ (ys ++ zs)) -- Inductive Hypothesis
    == (x:xs') ++ (ys ++ zs) -- Equation 2 (symmetrically)
    == RHS

Thus associativity is proven by induction on lists.

4. Inference Rules (and Red Black Trees)

Red-black trees are binary search trees where each node in the tree is coloured either red or black. In C, red-black trees could, for example, be encoded with the following user-defined data type:

typedef struct redBlackNode* link;

struct redBlackNode { 
  Item item; // Item type defined elsewhere
  link left, right; 
  int  isRed; // 1 if node is red, 0 if black
};

and in Haskell (again, we assume the Item type is defined elsewhere)

data RBColour
  = Red
  | Black

data RBTree
  = RBLeaf
  | RBNode RBColour Item RBTree RBTree 
  1. The user defined Haskell data type characterises a set of terms as RBTree. List the inference rules to define the same set. Assume there already exists a judgement \(x\ \mathbf{Item}\) which is derivable for all \(x\) in the Item type.
  2. In a proper red-black tree, we can never have a red parent node with a red child, although it is possible to have black nodes with black children. Moreover, the root node cannot be red. Therefore, not all terms of type RBTree are real red-black trees. Define inference rules for a property \(t\ \mathbf{OK}\), such that \(\mathbf{OK}\) is derivable if the term \(t\) represents a proper red-black tree.

1:

\[ \dfrac{ }{\mathit{Red}\ \mathbf{RBColour}} \quad \dfrac{ }{\mathit{Black}\ \mathbf{RBColour}} \]

\[ \dfrac{ }{\mathit{RBLeaf}\ \mathbf{RBTree}} \quad \dfrac{c\ \mathbf{RBColour}\quad x\ \mathbf{Item}\quad t_1\ \mathbf{RBTree}\quad t_2\ \mathbf{RBTree}}{(\mathit{RBNode}\ c\ x\ t_1\ t_2)\ \mathbf{RBTree}} \]

2: We define this using an additional property, \(\mathbf{OK}^R\). \(\mathbf{OK}\) is a red-black tree with a black root node or a leaf, whereas \(\mathbf{OK}^R\) trees can also have red root nodes. If a node has a red root node, both children have to have black root nodes.

\[ \dfrac{ }{\mathit{RBLeaf}\ \mathbf{OK}}\quad\dfrac{t_1\ \mathbf{OK}^R\quad t_2\ \mathbf{OK}^R }{ (\mathit{RBNode}\ \mathit{Black}\ x\ t_1\ t_2)\ \mathbf{OK}} \] \[ \dfrac{t_1\ \mathbf{OK}\quad t_2\ \mathbf{OK} }{ (\mathit{RBNode}\ \mathit{Red}\ x\ t_1\ t_2)\ \mathbf{OK}^R}\quad \dfrac{n\ \mathbf{OK}}{n\ \mathbf{OK}^R} \]

2025-12-05 Fri 11:50

Announcements RSS