Programming Languages!

Haskell Part 2

Dr. Philip Cannata

1

A programming language is a language with a welldefined syntax (lexicon and grammar), type system, and semantics that can be used to implement a set of algorithms. Haskell

Dr. Philip Cannata

2

Haskell: /lusr/bin/hugs, should be in your default $PATH or for windows, download and install winhugs at http://cvs.haskell.org/Hugs/pages/downloading.htm $ hugs __ __ __ __ ____ ___ _________________________________________ || || || || || || ||__ Hugs 98: Based on the Haskell 98 standard ||___|| ||__|| ||__|| __|| Copyright (c) 1994-2005 ||---|| ___|| World Wide Web: http://haskell.org/hugs || || Bugs: http://hackage.haskell.org/trac/hugs || || Version: 20051031 _________________________________________ Haskell 98 mode: Restart with command line option -98 to enable extensions Type :? for help Hugs> :load 10H2 Main>

Dr. Philip Cannata

To load the file “10H2.hs” from the directory in which you started hugs. Similar for 10Logic and 10Movie 3

Propositional Logic Propositions: Statements that can be either True or False Logical Operators: •  Negation: not not :: Bool-> Bool not True = False not False = True •  Conjunction: && (&&) :: Bool-> Bool-> Bool False && x = False True && x = x •  Disjunction: || (||) :: Bool-> Bool-> Bool True || x = True False || x = x Dr. Philip Cannata

Logical Operators: •  Implication (if – then): ==> Antecedent ==> Consequent (==>) :: Bool -> Bool -> Bool x ==> y = (not x) || y •  Equivalence (if, and only if): () :: Bool -> Bool -> Bool x y = x == y •  Not Equivalent () :: Bool -> Bool -> Bool x y = x /= y

4

Truth tables: P && Q P || Q not P P ==> Q P Q P Q

P

Q

False

False

False

P

Q

P || Q

False

False

False

False

True

False

False

True

True

True

False

False

True

False

True

True

True

True

True

True

True

P False False True True

Q P Q False True True True False False True True

P

¬P

False

True

True

False

P

Dr. Philip Cannata

Q

P && Q

PQ



P

Q

P Q

False

False

True

False

False

False

False

True

False

False

True

True

True

False

False

True

False

True

True

True

True

True

True

False

5

Reasoning with Truth Tables Proposition (WFF): ((P ∨ Q)∧((¬P)→Q)) P

Q

(P ∨ Q)

(¬P)

False False

False

True

False

False

False True

True

True

True

True

True

False

True

False

True

True

True

True

True

False

True

True

If prop is True when all variables are True: P, Q

((P∨Q)∧((¬P)→Q))

A Truth double turnstile Dr. Philip Cannata

((¬P)→Q)

((P∨Q)∧((¬P)→Q))

Some True: prop is Satisfiable* If they were all True: Valid / Tautology All False: Contradiction (not satisfiable*) *Satisfiability was the first known NP-complete problem

6

The class P consists of all those decision problems (see Delong, page 159) that can be solved on a deterministic sequential machine in an amount of time that is polynomial in the size of the input; the class NP consists of all those decision problems whose positive solutions can be verified in polynomial time given the right information.

A problem is NP-hard if an algorithm for solving it can be translated into one for solving any NP-problem (nondeterministic polynomial time) problem. NP-hard therefore means "at least as hard as any NP-problem," although it might, in fact, be harder.

Complexity Theory

•  If there is a polynomial algorithm for any NP-hard problem, then there are polynomial algorithms for all problems in NP, and hence P = NP; •  If P ≠ NP, then NP-hard problems have no solutions in polynomial time, while P = NP does not resolve whether the NP-hard problems can be solved in polynomial time; •  A common mistake is to think that the NP in NP-hard stands for nonpolynomial. Although it is widely suspected that there are no polynomialtime algorithms for NP-hard problems, this has never been proven. Moreover, the class NP also contains all problems which can be solved in polynomial time. Dr. Philip Cannata

7

Truth Table Application truthTable :: (Bool -> Bool -> Bool) -> [Bool] truthTable wff = [ (wff p q) | p q)) Hugs> :load 10Logic.hs LOGIC> :type tt tt :: Bool -> Bool -> Bool LOGIC> truthTable tt [False,True,False,False] LOGIC> or (truthTable tt) True LOGIC> and (truthTable tt) False Dr. Philip Cannata

8

Satisfiable: Are there well formed propositional formulas that return True for some input? satisfiable1 :: (Bool -> Bool) -> Bool satisfiable1 wff = (wff True) || (wff False) satisfiable2 :: (Bool -> Bool -> Bool) -> Bool satisfiable2 wff = or [ (wff p q) | p Bool -> Bool) -> Bool satisfiable3 wff = or [ (wff p q r) | p Bool -> Bool x ==> y = (not x) || y infix 1 () :: Bool -> Bool -> Bool x y = x == y infixr 2 () :: Bool -> Bool -> Bool x y = x /= y

( \ p -> not p) ( \ p q -> (not p) || (not q) ) ( \ p q r -> (not p) || (not q) && (not r) )

Dr. Philip Cannata

9

Validity (Tautology): Are there well formed propositional formulas that return True no matter what their input values are? valid1 :: (Bool -> Bool) -> Bool valid1 wff = (wff True) && (wff False) valid2 :: (Bool -> Bool -> Bool) -> Bool valid2 wff = (wff True True) && (wff True False) && (wff False True) && (wff False False) ( \ p -> p || not p ) -- Excluded Middle ( \ p -> p ==> p ) ( \ p q -> p ==> (q ==> p) ) ( \ p q -> (p ==> q) ==> p )

Dr. Philip Cannata

10

Tautological Proof It’s either summer or winter. If it’s summer, I’m happy. If it’s winter, I’m happy. Is there anything you can uncompress from this? ( (s ∨ w) ^ (s -> h) ^ (w -> h) ) -> h valid3 :: (Bool -> Bool -> Bool -> Bool) -> Bool valid3 bf = and [ bf r s t| r r r -> r ¬r ∨ r .: T (Convince yourself of this using logEquiv3)

LOGIC> valid3 (\ s w h -> ((s || w) && (s ==> h) && (w ==> h)) ==> h) True Is h a Truth? Dr. Philip Cannata

11

if … then … else …

( (c → b) & (~c → a) ) ( (c & b) ∨ (~c & a) ) LOGIC> valid3 (\ c a b ->((c==>a) && ((not c)==>b))) False LOGIC> logEquiv3 (\ c a b ->((c==>a) && ((not c)==>b))) (\ c a b -> ((c && a) || ((not c) && b))) True

Dr. Philip Cannata

12

Contradiction (Not Satisfiable): Are there well formed propositional formulas that return False no matter what their input values are? contradiction1 :: (Bool -> Bool) -> Bool contradiction1 wff = not (wff True) && not (wff False) contradiction2 :: (Bool -> Bool -> Bool) -> Bool contradiction2 wff = and [not (wff p q) | p Bool -> Bool) -> Bool contradiction3 wff = and [ not (wff p q r) | p (p && not p) || (q && not q) && (r && not r) ) Dr. Philip Cannata

13

Truth: Are there well formed propositional formulas that return True when their input is True truth1 :: (Bool -> Bool) -> Bool truth1 wff = (wff True) truth2 :: (Bool -> Bool -> Bool) -> Bool truth2 wff = (wff True True) ( \ p -> not p) ( \ p q -> (p && q) || (not p ==> q)) ( \ p q -> not p ==> q) ( \ p q -> (not p && q) && (not p ==> q) )

Dr. Philip Cannata

14

Equivalence: logEquiv1 :: (Bool -> Bool) -> (Bool -> Bool) -> Bool logEquiv1 bf1 bf2 = (bf1 True bf2 True) && (bf1 False bf2 False) logEquiv2 :: (Bool -> Bool -> Bool) -> (Bool -> Bool -> Bool) -> Bool logEquiv2 bf1 bf2 = and [(bf1 r s) (bf2 r s) | r Bool -> Bool) -> (Bool -> Bool -> Bool -> Bool) -> Bool logEquiv3 bf1 bf2 = and [(bf1 r s t) (bf2 r s t) | r not (not p)) id is the identity function, i.e., id True gives True logEquiv1 id (\ p -> p && p) logEquiv1 id (\ p -> p || p) logEquiv2 (\ p q -> p ==> q) (\ p q -> not p || q) logEquiv2 (\ p q -> not (p ==> q)) (\ p q -> p && not q) logEquiv2 (\ p q -> not p ==> not q) (\ p q -> q ==> p) logEquiv2 (\ p q -> p ==> not q) (\ p q -> q ==> not p) logEquiv2 (\ p q -> not p ==> q) (\ p q -> not q ==> p) logEquiv2 (\ p q -> p q) (\ p q -> (p ==> q) && (q ==> p)) logEquiv2 (\ p q -> p q) (\ p q -> (p && q) || (not p && not q)) logEquiv2 (\ p q -> p && q) (\ p q -> q && p) logEquiv2 (\ p q -> p || q) (\ p q -> q || p) logEquiv2 (\ p q -> not (p && q)) (\ p q -> not p || not q) logEquiv2 (\ p q -> not (p || q)) (\ p q -> not p && not q) logEquiv3 (\ p q r -> p && (q && r)) (\ p q r -> (p && q) && r) logEquiv3 (\ p q r -> p || (q || r)) (\ p q r -> (p || q) || r) logEquiv3 (\ p q r -> p && (q || r)) (\ p q r -> (p && q) || (p && r)) test9b logEquiv3 (\ p q r -> p || (q && r)) (\ p q r -> (p || q) && (p || r)) Dr. Philip Cannata

-- Idempotence -- Idempotence -- Idempotence -- Implication -- Contrapositive -- Contrapositive -- Contrapositive -- Contrapositive

-- Commutativity -- Commutativity -- deMorgan -- deMorgan -- Associativity -- Associativity -- Distributivity -- Distributivity 16

Why Reasoning with Truth Tables is Infeasible Works fine when there are 2 variables {T,F} × {T,F} = set of potential values of variables 2 × 2 lines in truth table Three variables — starts to get tedious {T,F} × {T,F} × {T,F} = set of potential values 2 × 2 × 2 lines in truth table Twenty variables — definitely out of hand 2 × 2 × … × 2 lines (220) You want to look at a million lines? If you did, how would you avoid making errors? Hundreds of variables — not in a million years à A need for Predicate Logic. We’ll look at this with Prolog. Dr. Philip Cannata

17

Haskell and SQL

Dr. Philip Cannata

18

Standard Oracle scott/tiger emp dept database

Dr. Philip Cannata

19

Standard Oracle scott/tiger emp dept database in Haskell emp = [ (7839, "KING", "PRESIDENT", 0, "17-NOV-81", 5000, 10), (7698, "BLAKE", "MANAGER", 7839, "01-MAY-81", 2850, 30), (7782, "CLARK", "MANAGER", 7839, "09-JUN-81", 2450, 10), (7566, "JONES", "MANAGER", 7839, "02-APR-81", 2975, 20), (7788, "SCOTT", "ANALYST", 7566, "09-DEC-82", 3000, 20), (7902, "FORD", "ANALYST", 7566, "03-DEC-81", 3000, 20), (7369, "SMITH", "CLERK", 7902, "17-DEC-80", 800, 20), (7499, "ALLEN", "SALESMAN", 7698, "20-FEB-81", 1600, 30), (7521, "WARD", "SALESMAN", 7698, "22-FEB-81", 1250, 30), (7654, "MARTIN", "SALESMAN", 7698, "28-SEP-81", 1250, 30), (7844, "TURNER", "SALESMAN", 7698, "08-SEP-81", 1500, 30), (7876, "ADAMS", "CLERK", 7788, "12-JAN-83", 1100, 20), (7900, "JAMES", "CLERK", 7698, "03-DEC-81", 950, 30), (7934, "MILLER", "CLERK", 7782, "23-JAN-82", 1300, 10) ] dept = [ (10, "ACCOUNTING", "NEW YORK"), (20, "RESEARCH", "DALLAS"), (30, "SALES", "CHICAGO"), (40, "OPERATIONS", "BOSTON") ]

Dr. Philip Cannata

20

Main>Main> [(empno, ename, job, sal, deptno) | (empno, ename, job, _, _, sal, deptno)

Dr. Philip Cannata

21

Main> [(empno, ename, job, sal, deptno) | (empno, ename, job, _, _, sal, deptno)

Dr. Philip Cannata

22

Main> [(empno, ename, job, sal, dname) | (empno, ename, job, _, _, sal, edeptno) length [sal | (_, _, _, _, _, sal, _)

Main> (\y -> fromIntegral(sum y) / fromIntegral(length y)) ([sal | (_, _, _, _, _, sal, _)

Dr. Philip Cannata

24

Main> map sqrt (map fromIntegral [sal | (_, _, _, _, _, sal, _)

Dr. Philip Cannata

25

Main> (map sqrt

. map fromIntegral) [sal | (_, _, _, _, _, sal, _)

Dr. Philip Cannata

26

Main> zip ([name | (_, name, _, _, _, _, _) [(name, sal, dept) | (_, name, _, _, _, sal, dept)

Dr. Philip Cannata

28

Main> [(name, sal, dept) | (_, name, _, _, _, sal, dept)

Dr. Philip Cannata

29

Main> [(name, sal, dept) | (_, name, _, _, _, sal, dept) (\ y -> x + y)) a b cmap f [] = [] cmap f l = (\ x -> (\ (y:ys) -> x y : cmap x ys )) f l -- Main> -- 2.0 -- Main> -- 2.0 cfoldr f cfoldr f

foldr (/) 2 [8,4,2] (/) 8 ((/) 4 ((/) 2 2)) i [a] = f a i i l = (\ x -> (\ y -> (\ (z:zs) -> x z (cfoldr x y zs) ))) f i l -- cfoldr (/) 2 [8,4,2]

-- The class of functions that we can express using foldr is called primitive recursive. -- A surprisingly large number of list manipulation functions are primitive recursive. -- For example, here's map, filter and foldl written in terms of foldr: cfoldr_map f l = cfoldr (\ x -> (\ y -> f x : y)) [] l -- cfoldr_map (\ x -> x*x) [1,2,3,4,5] cfoldr_filter f l = cfoldr (\ x -> (\ y -> if f x then x : y else y )) [] l -- cfoldr_filter (\ x -> x /= 4) [1,2,3,4,5] -- cfoldr_filter (\ x -> (x `mod` 2) == 0) [1,2,3,4,5] -- Main> foldl (/) 2 [8,4,2] -- 0.03125 -- Main> (/) ((/) ((/) 2 8) 4) 2 -- 0.03125 cflip f a b = (\ x -> (\ y -> (\ z -> x b a))) f a b cfoldr_foldl f i l = cfoldr (cflip f) i (reverse l) Dr. Philip Cannata

-- cfoldr_foldl (/) 2 [8,4,2]

32

Function Bodies using Combinators A function is called primitive recursive if there is a finite sequence of functions ending with f such that each function is a successor, constant or identity function or is defined from preceding functions in the sequence by substitution or recursion. s f g x = f x (g x) k x y = x b f g x = f (g x) c f g x = f x g y f = f (y f) cond p f g x = if p x then f x else g x -- Some Primitive Recursive Functions on Natural Numbers pradd x z = y (b (cond ((==) 0) (k z)) (b (s (b (+) (k 1)) ) (c b pred))) x prmul x z = y (b (cond ((==) 0) (k 0)) (b (s (b (+) (k z)) ) (c b pred))) x prexp x z = y (b (cond ((==) 0) (k 1)) (b (s (b (*) (k x)) ) (c b pred))) z prfac x = y (b (cond ((==) 0) (k 1)) (b (s (*) ) (c b pred))) x -- Alternative formulation pradd1 x z = y (b (cond ((==) 0) (k z)) (b (s (b (+) (k 1)) ) (c b pred))) x prmul1 x z = y (b (cond ((==) 0) (k 0)) (b (s (b (pradd1) (k z)) ) (c b pred))) x prexp1 x z = y (b (cond ((==) 0) (k 1)) (b (s (b (prmul1) (k x)) ) (c b pred))) z prfac1 x = y (b (cond ((==) 0) (k 1)) (b (s (prmul1) ) (c b pred))) x No halting problem here but not Turing complete either

Implies recursion or bounded loops, if-then-else constructs and run-time stack. see the BlooP language in Dr. Philip Cannata

33

A Strange Proposal s f g x = f x (g x) k x y = x b f g x = f (g x) c f g x = f x g y f = f (y f) cond p f g x = if p x then f x else g x -- Some pradd x prmul x prexp x prfac x

Primitive Recursive Functions on Natural Numbers z = y (b (cond ((==) 0) (k z)) (b (s (b (+) (k 1)) z = y (b (cond ((==) 0) (k 0)) (b (s (b (+) (k z)) z = y (b (cond ((==) 0) (k 1)) (b (s (b (*) (k x)) = y (b (cond ((==) 0) (k 1)) (b (s (*)

) ) ) )

(c (c (c (c

b b b b

pred))) pred))) pred))) pred)))

x x z x

To find Primitive Recursive Functions, try something like the following: prf

x z = y (b (cond ((==) 0) (k A)) (b (s AAAAAA . . . AAAAAAAAAA ) (c b pred))) A

Where each A is a possibly different element of {x z 0 least having parentheses match.

Gödel may

Dr. Philip Cannata

1 + * s k b c ( ) “”} but at

|

haskell type checker that rules out bad combinations

be lurking!

34

John McCarthy’s Takeaway

-- Primitive Recursive Functions on Lists are more interesting than PRFs on Numbers prlen x = y (b (cond ((==) []) (k 0)) (b (s (b (+) (k 1)) ) (c b cdr))) x prsum x = y (b (cond ((==) []) (k 0)) (b (s (b (+) (car)) ) (c b cdr))) x prprod x = y (b (cond ((==) []) (k 1)) (b (s (b (*) (car)) ) (c b cdr))) x prmap f x = y (b (cond ((==) []) (k [])) (b (s (b (:) (f) ) ) (c b cdr))) x -- prmap (\ x -> (car x) + 2) [1,2,3] or -- prmap (\ x -> pradd (car x) 2) [1,2,3] prFoldr fn z x = y (b (cond ((==) []) (k z)) (b (s (b fn (car)) ) (c b cdr))) x prfoo x = y (b (cond ((==) []) (k [])) (b (s (b (:) (cdr)) ) (c b cdr))) x -- A programming language should have first-class functions as (b p1 p2 . . . Pn), substitution, lists with car, cdr and cons operations and recursion. car (f:r) = f cdr (f:r) = r : -- cons Dr. Philip Cannata

35

/ ASP

Other Takeaways ?

3rd Gen. PLs 2nd Gen. PLs

Pattern 1 (Modus Tollens): Q :- (P1, P2). -Q è -(P1, P2) Pattern 2 (Affirming a Conjunct): P1. -(P1, P2) è -P2

No Gödel

Lisp/Haskell (e1, e2, e3, e4, e5) (p1 p2 p3 body) Lisp: (car (list 1 2 3 4)) Haskell: head :: [a] -> a head (x : _ ) = x Dr. Philip Cannata

Pattern 3: P2. -P2 è Contradiction

Prolog 1). parent(hank,ben). 2). parent(ben,carl). 3). parent(ben,sue). 4). grandparent(X,Z) :parent(X,Y) , parent(Y,Z). 5). –grandparent(A, B)

1st Gen. PLs

FORTRAN

Formula Translation

DTRAN

Data Translation

Meaning Translation

Relation-based Languages SQL RDF/Inferencing/SPARQL Select * from dept

MTRAN OO

-- General inferencing in the family model EXECUTE SEM_APIS.CREATE_RULEBASE('family_rb_cs345_XXX'); INSERT INTO mdsys.semr_family_rb_cs345_XXX VALUES ('grandparent_rule', '(?x :parentOf ?y) (?y :parentOf ?z)', NULL, '(?x :grandParentOf ?z)', SEM_ALIASES(SEM_ALIAS('','http://www.example.org/ family/'))); COMMIT; -- Select all grandfathers and their grandchildren from the family model. -- Use inferencing from both the RDFS and family_rb rulebases. SELECT x grandfather, y grandchild FROM TABLE(SEM_MATCH( '(?x :grandParentOf ?y) (?x rdf:type :Male)', SEM_Models('family_cs345_XXX'), SEM_Rulebases('RDFS','family_rb_cs345_XXX'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/ family/')), null))

36