% Prolog doesn't know anything at first. "true" and "false" are
% just arbitrary words. We need to use them by way of the operations
% "not", "xor", and "implies", so we'll define those using truth tables:
xor(false, false, false).
implies
(false
, false
, true).implies
(true, false
, false
).
% Now, let's write down what we were given...
% Statement 1a is true iff (there is a king) implies (there is an ace).
stmt_1a(HasKing, HasAce, Result) :-
implies(HasKing, HasAce, Result).
% Statement 1b is true iff (there is not a king) implies (there is an ace).
stmt_1b(HasKing, HasAce, Result) :-
implies(DoesntHaveKing, HasAce, Result),
not(DoesntHaveKing, HasKing).
% Statement 1 is true iff (statement 1a) xor (statement 1b) is true.
stmt_1(HasKing, HasAce, Result) :-
xor(Stmt1ATrue, Stmt1BTrue, Result),
stmt_1a(HasKing, HasAce, Stmt1ATrue),
stmt_1b(HasKing, HasAce, Stmt1BTrue).
% Statement 2 is true iff there is a king.
stmt_2(HasKing, _HasAce, Result) :-
Result = HasKing.
% Finally: we can say we've found a valid assignment (true/false values for
% HasKing and HasAce) if they satisfy both of the given statements.
satisfied(HasKing, HasAce) :-
stmt_1
(HasKing
, HasAce
, true), stmt_2
(HasKing
, HasAce
, true).
% Now let's ask Prolog our question: for what values of HasKing and HasAce
% is the statement satisfied?
:- satisfied(HasKing, HasAce),
% Marking this as a failure causes Prolog to backtrack,
% so if there were multiple solutions, we'd see each of them.
JSBQcm9sb2cgZG9lc24ndCBrbm93IGFueXRoaW5nIGF0IGZpcnN0LiAidHJ1ZSIgYW5kICJmYWxzZSIgYXJlCiUganVzdCBhcmJpdHJhcnkgd29yZHMuIFdlIG5lZWQgdG8gdXNlIHRoZW0gYnkgd2F5IG9mIHRoZSBvcGVyYXRpb25zCiUgIm5vdCIsICJ4b3IiLCBhbmQgImltcGxpZXMiLCBzbyB3ZSdsbCBkZWZpbmUgdGhvc2UgdXNpbmcgdHJ1dGggdGFibGVzOgpub3QodHJ1ZSwgZmFsc2UpLgpub3QoZmFsc2UsIHRydWUpLgoKeG9yKGZhbHNlLCBmYWxzZSwgZmFsc2UpLgp4b3IoZmFsc2UsIHRydWUsIHRydWUpLgp4b3IodHJ1ZSwgZmFsc2UsIHRydWUpLgp4b3IodHJ1ZSwgdHJ1ZSwgZmFsc2UpLgoKaW1wbGllcyhmYWxzZSwgZmFsc2UsIHRydWUpLgppbXBsaWVzKGZhbHNlLCB0cnVlLCB0cnVlKS4KaW1wbGllcyh0cnVlLCBmYWxzZSwgZmFsc2UpLgppbXBsaWVzKHRydWUsIHRydWUsIHRydWUpLgoKJSBOb3csIGxldCdzIHdyaXRlIGRvd24gd2hhdCB3ZSB3ZXJlIGdpdmVuLi4uCgolIFN0YXRlbWVudCAxYSBpcyB0cnVlIGlmZiAodGhlcmUgaXMgYSBraW5nKSBpbXBsaWVzICh0aGVyZSBpcyBhbiBhY2UpLgpzdG10XzFhKEhhc0tpbmcsIEhhc0FjZSwgUmVzdWx0KSA6LQogICAgaW1wbGllcyhIYXNLaW5nLCBIYXNBY2UsIFJlc3VsdCkuCgolIFN0YXRlbWVudCAxYiBpcyB0cnVlIGlmZiAodGhlcmUgaXMgbm90IGEga2luZykgaW1wbGllcyAodGhlcmUgaXMgYW4gYWNlKS4Kc3RtdF8xYihIYXNLaW5nLCBIYXNBY2UsIFJlc3VsdCkgOi0KICAgIGltcGxpZXMoRG9lc250SGF2ZUtpbmcsIEhhc0FjZSwgUmVzdWx0KSwKICAgICAgICBub3QoRG9lc250SGF2ZUtpbmcsIEhhc0tpbmcpLgoKJSBTdGF0ZW1lbnQgMSBpcyB0cnVlIGlmZiAoc3RhdGVtZW50IDFhKSB4b3IgKHN0YXRlbWVudCAxYikgaXMgdHJ1ZS4Kc3RtdF8xKEhhc0tpbmcsIEhhc0FjZSwgUmVzdWx0KSA6LQogICAgeG9yKFN0bXQxQVRydWUsIFN0bXQxQlRydWUsIFJlc3VsdCksCiAgICBzdG10XzFhKEhhc0tpbmcsIEhhc0FjZSwgU3RtdDFBVHJ1ZSksCiAgICBzdG10XzFiKEhhc0tpbmcsIEhhc0FjZSwgU3RtdDFCVHJ1ZSkuCgolIFN0YXRlbWVudCAyIGlzIHRydWUgaWZmIHRoZXJlIGlzIGEga2luZy4Kc3RtdF8yKEhhc0tpbmcsIF9IYXNBY2UsIFJlc3VsdCkgOi0KICAgIFJlc3VsdCA9IEhhc0tpbmcuCgolIEZpbmFsbHk6IHdlIGNhbiBzYXkgd2UndmUgZm91bmQgYSB2YWxpZCBhc3NpZ25tZW50ICh0cnVlL2ZhbHNlIHZhbHVlcyBmb3IKJSBIYXNLaW5nIGFuZCBIYXNBY2UpIGlmIHRoZXkgc2F0aXNmeSBib3RoIG9mIHRoZSBnaXZlbiBzdGF0ZW1lbnRzLgoKc2F0aXNmaWVkKEhhc0tpbmcsIEhhc0FjZSkgOi0KICAgIHN0bXRfMShIYXNLaW5nLCBIYXNBY2UsIHRydWUpLAogICAgc3RtdF8yKEhhc0tpbmcsIEhhc0FjZSwgdHJ1ZSkuCgolIE5vdyBsZXQncyBhc2sgUHJvbG9nIG91ciBxdWVzdGlvbjogZm9yIHdoYXQgdmFsdWVzIG9mIEhhc0tpbmcgYW5kIEhhc0FjZQolIGlzIHRoZSBzdGF0ZW1lbnQgc2F0aXNmaWVkPwoKOi0gc2F0aXNmaWVkKEhhc0tpbmcsIEhhc0FjZSksCgl3cml0ZSgnSGFzIGtpbmc6ICcpLCB3cml0ZShIYXNLaW5nKSwgbmwsCgl3cml0ZSgnSGFzIGFjZTogJyksIHdyaXRlKEhhc0FjZSksIG5sLAoJd3JpdGUoJy0tLS0tLS0tLS0tLS0tJyksIG5sLAoJJSBNYXJraW5nIHRoaXMgYXMgYSBmYWlsdXJlIGNhdXNlcyBQcm9sb2cgdG8gYmFja3RyYWNrLAoJJSBzbyBpZiB0aGVyZSB3ZXJlIG11bHRpcGxlIHNvbHV0aW9ucywgd2UnZCBzZWUgZWFjaCBvZiB0aGVtLgoJZmFpbDsKCXdyaXRlKCdObyBtb3JlIHNvbHV0aW9ucyEnKSwgaGFsdC4=