370

# Hereditary Harrop Formulas (Papers We Love Boston)

Slides about Hereditary Harrop Formulas from Papers We Love Boston: https://youtu.be/RwBiHLoQ3E4

May 29, 2018

## Transcript

1. None

3. ### 3 Basic idea of Prolog: parent(zeus, athena). parent(chronos, zeus). parent(rhea,

zeus). Deﬁne CLAUSES (“X is true if Y and Z are true”). ancestor(A, B) :- parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). “facts” = clauses  with no conditions. ?- ancestor(P, athena). P = zeus. P = chronos. P = rhea. Use CLAUSES to solve GOALS (or QUERIES):
4. ### 4 How does Prolog actually work? Surprise: the computer is

not actually smart.
5. ### 5 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). ancestor(P, athena) :- parent(P, athena) A = P B = athena
6. ### 6 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). ancestor(P, athena) :- parent(P, athena) parent(zeus, athena) P = zeus Uniﬁcations
7. ### 7 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). ancestor(P, athena) :- parent(P, athena) parent(zeus, athena) P = zeus Uniﬁcations Answer 0: ancestor(zeus, athena)
8. ### 8 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). ancestor(P, athena) :- parent(P, athena) parent(zeus, athena) P = zeus Uniﬁcations Answer 0: ancestor(zeus, athena) ancestor(P, athena) :- parent(P, Q), ancestor(Q, athena).
9. ### 9 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). Uniﬁcations ancestor(P, athena) :- parent(P, Q), ancestor(Q, athena). parent(zeus, athena) P = zeus Q = athena
10. ### 10 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). Uniﬁcations ancestor(P, athena) :- parent(P, Q), ancestor(Q, athena). parent(zeus, athena) P = zeus Q = athena ancestor(athena, athena)
11. ### 11 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). Uniﬁcations ancestor(P, athena) :- parent(P, Q), ancestor(Q, athena). parent(zeus, athena) P = zeus Q = athena ancestor(athena, athena)
12. ### 12 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). Uniﬁcations ancestor(P, athena) :- parent(P, Q), ancestor(Q, athena). parent(zeus, athena) P = zeus Q = athena ancestor(athena, athena) parent(athena, athena)?
13. ### 13 parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :-

parent(A, B). ancestor(A, C) :- parent(A, B), ancestor(B, C). ?- ancestor(P, athena). Uniﬁcations ancestor(P, athena) :- parent(P, Q), ancestor(Q, athena). parent(zeus, athena) P = zeus Q = athena ancestor(athena, athena)
14. ### 14 “Backward chaining” and “Uniﬁcation” Uniﬁcations P = zeus Q

= athena Goals ancestor(..) parent(..) Program Clauses parent(zeus, athena). parent(chronos, zeus). parent(rhea, zeus). ancestor(A, B) :- … ancestor(A, C) :- …
15. ### 15 ( Uniﬁcations Goals Program Clauses D, {G}, Θ )

M = (D, {G}, Θ) M1 -> M2 Machine state Transition between states
16. ### 16 ( Uniﬁcations Goals Program Clauses D, {G}, Θ )

(D, {ancestor(P, athena)}, {}) (D, {parent(P, athena)}, {}) (D, { parent(P, Q), ancestor(Q, athena) }, {}) Branches in our search space: implementation must try both
17. ### 17 Horn Clauses G ::= A | G and G

| G or G | exists<T> { G } D ::= A | A :- G | D and D | forall<T> { D } (zeus) An “atom” A (zeus). A clause D ::= A (X) :- (X). A clause D ::= forall<X> { … }
18. ### 18 G ::= A | G and G | G

or G | exists<T> { G } Prove an atom A using clauses given by the user. Proving these other goals is “built in”. (D, {(G1 and G2)}, Θ) (D, {G1, G2}, Θ) (D, {(G1 or G2)}, Θ) (D, {G1}, Θ) (D, {G2}, Θ) Same as when proving an atom against many program clauses.
19. ### 19 G ::= A | G and G | G

or G | exists<T> { G } (D, {exists<T> { G }}, Θ) (D, {[T -> X] G}, Θ) “Replace T with some fresh variable X” …exists<G> { (G) }… …(Y)… Same as a “forall” clause like forall<G> { (G) :- (G) }
20. ### 20 Horn Clauses G ::= A | G and G

| G or G | exists<T> { G } D ::= A | A :- G | D and D | forall<T> { D } “What about me?” => Can’t have a clause that says “either Foo or Bar is true but I don’t know which”.
21. ### 21 Prolog’s Awesomeness Expressive logical language Simple solver Yet: Sound

and complete! Caveat: “If it terminates…” “If it terminates, the solver will ﬁnd all possible answers.”
22. ### 22 Prolog’s Limitations Always working with “concrete atoms” ?- forall<G>

{ (G) } ?- (G). ∃G. (G) ? We might want to be more generic…

24. ### 24 Prolog’s Limitations Always working with a ﬁxed set of

facts/rules We’d like to able to add hypotheses if (C) { G } ?- forall<G> { if ((G)) { (G) } } “For any god G… …assuming they have lightning… are they scary?” “If we assume C is true, is G provable?”
25. ### 25 (zeus). (zeus). (G) :- (G). :- forall<G> { if

((G)) { (G) } } (G).
26. ### 26 fn foo<T>(a: T, b: T) where T: Ord {

a == b // requires T: Eq<T> } forall<T> { if (Implemented(T: Ord)) { Implemented(T: Eq<T>) } }

29. ### 29 Hereditary Harrop Clauses G ::= A | G and

G | G or G | exists<T> { G } | forall<T> { G } | if(D) { G } D ::= A | A :- G | D and D | forall<T> { D } These two are new
30. ### 30 How to implement “if”? ( Uniﬁcations Goals Program Clauses

D, {(D, G)}, Θ ) Each goal now carries a list of hypotheses along with it
31. ### 31 (D, {(true, (athena) => (athena))}, {}) (D, {(true &&

(athena), (athena))}, {}) Hypotheses New goal
32. ### 32 Now, when we want to prove an atom (D,

A): Check each program clauses from the user, as before Also check the hypotheses D G ::= A | G and G | G or G | exists<T> { G } | forall<T> { G } | if(D) { G } D ::= A | A :- G | D and D | forall<T> { D } G => D D => G
33. ### 33 How to implement “forall”? U0 U1 “Universe” — a

set of names U0 — all the global names, like `athena`, `zeus`. U1 — all the global names, and then one more, `!U1`
34. ### 34 U0 U1 U2 U3 U4 U2 can name !U2,

!U1, and the root names
35. ### 35 (D, {forall<T> { G }}, Θ) (D, {[T ->

!U] G}, Θ) “Replace T with !U with the next universe U” …forall<G> { (G) }… …(!U1)… (zeus). (G) :- (G). “!U1 is not zeus” But G can be any name, even U1
36. ### 36 Really? ANY name? forall<A> { exists<E> { A =

E } } Sure, E = A (or E = !U1) exists<E> { forall<A> { A = E } } No! E = A doesn’t work, A is not in scope.
37. ### 37 Idea: give each variable a universe forall<A> { exists<E>

{ A = E } } Here, E is in universe U1, so it can name !U1 exists<E> { forall<A> { A = E } } Here, E is in universe U0, so it cannot. U0 U1 U0 U1
38. ### 38 M = (D, {(D,G,I)}, L, Θ) Program clauses. Hypotheses

Goal to prove Current universe counter; starts out at U0 Labels: what universe is each variable in Substitution
39. ### 39 U0 U1 U2 U3 U4 Why just a counter?

e.g., what about U1 and U4? How do we know that U1 is not U4’s parent?
40. ### 40 G={exists<E> { forall<A> { E = A } and

forall<B> { E = B } }} G={forall<A> { E = A } and forall<B> { E = B }} L=() L=(E: U0) G={forall<A> { E = A }, forall<B> { E = B }} L=(E: U0) G={E = !U1, forall<B> { E = B }} L=(E: U0) !U1 and !U2 are siblings — never directly interact
41. ### 41 Thanks! If you enjoyed this, consider joining the Traits

Working Group. Help us rework Rust’s trait system implementation in these terms. (Also, this book is really good.)