Prolog check if first element in lists are not equal and second item in list is equal
I want to compare 2 lists, the first element should not be equal, the second one should be equal.
example database:
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
so it should return true for same([josh,muse], [sam,muse]).
This is what I tried so far:
same([H1|R1], [H2|R2]):-
H1 = H2,
same(R1,R2).
This returned false for every combination.
list prolog
add a comment |
I want to compare 2 lists, the first element should not be equal, the second one should be equal.
example database:
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
so it should return true for same([josh,muse], [sam,muse]).
This is what I tried so far:
same([H1|R1], [H2|R2]):-
H1 = H2,
same(R1,R2).
This returned false for every combination.
list prolog
add a comment |
I want to compare 2 lists, the first element should not be equal, the second one should be equal.
example database:
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
so it should return true for same([josh,muse], [sam,muse]).
This is what I tried so far:
same([H1|R1], [H2|R2]):-
H1 = H2,
same(R1,R2).
This returned false for every combination.
list prolog
I want to compare 2 lists, the first element should not be equal, the second one should be equal.
example database:
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
so it should return true for same([josh,muse], [sam,muse]).
This is what I tried so far:
same([H1|R1], [H2|R2]):-
H1 = H2,
same(R1,R2).
This returned false for every combination.
list prolog
list prolog
edited Nov 23 '18 at 9:50
false
10.5k771144
10.5k771144
asked Nov 22 '18 at 19:46
srp1908srp1908
304
304
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
The [Head|Tail]
Prolog notation for lists that you're using in the definition of the same/2
predicate provides access to the list head and tail. The tail of a list is itself a (possibly empty) list. But in your case you want to access the first and the second elements, which you can do by writing [First, Second| _]
(i.e. by enumerating the elements separated by a comma; here I'm using an anonymous variable for the tail as we don't need it and therefore we can ignore it).
Your predicate can be fixed by rewriting it as:
same([F1,S1|_], [F2,S2|_]):-
F1 == F2,
S1 == S2.
If you know that the arguments are always lists with two elements, you can simplify the predicate to:
same([F1,S1], [F2,S2]):-
F1 == F2,
S1 == S2.
Sample calls:
?- same([josh,muse], [sam,muse]).
true.
?- same([sam,muse], [sam,muse]).
false.
?- same([josh,muse], [sam,maria]).
false.
As a last note, your question is about term equality but in your solution attempt you're using term unification. These have different semantics and should not be confused.
add a comment |
In reading your question you first gave a database of facts
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
but then used list for the predicate
same([josh,muse], [sam,muse]).
As Paulo answered starting with list, I will answer starting with facts.
The first thing is to create a predicate that reads the facts, does some logic and returns results.
same_1(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item).
which gives
?- same_1(P1,P2,Item).
P1 = P2, P2 = josh,
Item = muse ;
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
P1 = P2, P2 = sam,
Item = muse ;
P1 = P2, P2 = josh,
Item = gnr ;
P1 = P2, P2 = sam,
Item = radiohead.
So this needs to make sure P1 is not the same as P2.
same_2(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item),
P1 = P2.
which gives
?- same_2(P1,P2,Item).
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Still two answers that are valid but essentially a duplicate. To remove these duplicates requires storing all of the results so that each new result can be checked against existing results and not added to the current results. Also before storing the results they need to be normalized so that no matter which way the names are ordered when initially created they are in the same order when comparing them before saving them.
Modifying the code to create normalized entries.
same_3(P1,P2,Item) :-
likes(T1,Item),
likes(T2,Item),
T1 = T2,
normalize(T1,T2,P1,P2).
normalize(P1,P2,P1,P2) :- P1 @> P2.
normalize(P1,P2,P2,P1) :- P1 @=< P2.
which returns
?- same_3(P1,P2,Item).
P1 = sam,
P2 = josh,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Notice that this result has the names in the same order.
Now to just save the results as they are generated and only add unique items to the result. This is done using setof/3.
?- setof((P1,P2,Item),(same_3(P1,P2,Item)),Bag).
Bag = [(sam, josh, muse)].
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437271%2fprolog-check-if-first-element-in-lists-are-not-equal-and-second-item-in-list-is%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The [Head|Tail]
Prolog notation for lists that you're using in the definition of the same/2
predicate provides access to the list head and tail. The tail of a list is itself a (possibly empty) list. But in your case you want to access the first and the second elements, which you can do by writing [First, Second| _]
(i.e. by enumerating the elements separated by a comma; here I'm using an anonymous variable for the tail as we don't need it and therefore we can ignore it).
Your predicate can be fixed by rewriting it as:
same([F1,S1|_], [F2,S2|_]):-
F1 == F2,
S1 == S2.
If you know that the arguments are always lists with two elements, you can simplify the predicate to:
same([F1,S1], [F2,S2]):-
F1 == F2,
S1 == S2.
Sample calls:
?- same([josh,muse], [sam,muse]).
true.
?- same([sam,muse], [sam,muse]).
false.
?- same([josh,muse], [sam,maria]).
false.
As a last note, your question is about term equality but in your solution attempt you're using term unification. These have different semantics and should not be confused.
add a comment |
The [Head|Tail]
Prolog notation for lists that you're using in the definition of the same/2
predicate provides access to the list head and tail. The tail of a list is itself a (possibly empty) list. But in your case you want to access the first and the second elements, which you can do by writing [First, Second| _]
(i.e. by enumerating the elements separated by a comma; here I'm using an anonymous variable for the tail as we don't need it and therefore we can ignore it).
Your predicate can be fixed by rewriting it as:
same([F1,S1|_], [F2,S2|_]):-
F1 == F2,
S1 == S2.
If you know that the arguments are always lists with two elements, you can simplify the predicate to:
same([F1,S1], [F2,S2]):-
F1 == F2,
S1 == S2.
Sample calls:
?- same([josh,muse], [sam,muse]).
true.
?- same([sam,muse], [sam,muse]).
false.
?- same([josh,muse], [sam,maria]).
false.
As a last note, your question is about term equality but in your solution attempt you're using term unification. These have different semantics and should not be confused.
add a comment |
The [Head|Tail]
Prolog notation for lists that you're using in the definition of the same/2
predicate provides access to the list head and tail. The tail of a list is itself a (possibly empty) list. But in your case you want to access the first and the second elements, which you can do by writing [First, Second| _]
(i.e. by enumerating the elements separated by a comma; here I'm using an anonymous variable for the tail as we don't need it and therefore we can ignore it).
Your predicate can be fixed by rewriting it as:
same([F1,S1|_], [F2,S2|_]):-
F1 == F2,
S1 == S2.
If you know that the arguments are always lists with two elements, you can simplify the predicate to:
same([F1,S1], [F2,S2]):-
F1 == F2,
S1 == S2.
Sample calls:
?- same([josh,muse], [sam,muse]).
true.
?- same([sam,muse], [sam,muse]).
false.
?- same([josh,muse], [sam,maria]).
false.
As a last note, your question is about term equality but in your solution attempt you're using term unification. These have different semantics and should not be confused.
The [Head|Tail]
Prolog notation for lists that you're using in the definition of the same/2
predicate provides access to the list head and tail. The tail of a list is itself a (possibly empty) list. But in your case you want to access the first and the second elements, which you can do by writing [First, Second| _]
(i.e. by enumerating the elements separated by a comma; here I'm using an anonymous variable for the tail as we don't need it and therefore we can ignore it).
Your predicate can be fixed by rewriting it as:
same([F1,S1|_], [F2,S2|_]):-
F1 == F2,
S1 == S2.
If you know that the arguments are always lists with two elements, you can simplify the predicate to:
same([F1,S1], [F2,S2]):-
F1 == F2,
S1 == S2.
Sample calls:
?- same([josh,muse], [sam,muse]).
true.
?- same([sam,muse], [sam,muse]).
false.
?- same([josh,muse], [sam,maria]).
false.
As a last note, your question is about term equality but in your solution attempt you're using term unification. These have different semantics and should not be confused.
edited Nov 22 '18 at 20:23
answered Nov 22 '18 at 20:17
Paulo MouraPaulo Moura
11.7k21325
11.7k21325
add a comment |
add a comment |
In reading your question you first gave a database of facts
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
but then used list for the predicate
same([josh,muse], [sam,muse]).
As Paulo answered starting with list, I will answer starting with facts.
The first thing is to create a predicate that reads the facts, does some logic and returns results.
same_1(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item).
which gives
?- same_1(P1,P2,Item).
P1 = P2, P2 = josh,
Item = muse ;
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
P1 = P2, P2 = sam,
Item = muse ;
P1 = P2, P2 = josh,
Item = gnr ;
P1 = P2, P2 = sam,
Item = radiohead.
So this needs to make sure P1 is not the same as P2.
same_2(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item),
P1 = P2.
which gives
?- same_2(P1,P2,Item).
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Still two answers that are valid but essentially a duplicate. To remove these duplicates requires storing all of the results so that each new result can be checked against existing results and not added to the current results. Also before storing the results they need to be normalized so that no matter which way the names are ordered when initially created they are in the same order when comparing them before saving them.
Modifying the code to create normalized entries.
same_3(P1,P2,Item) :-
likes(T1,Item),
likes(T2,Item),
T1 = T2,
normalize(T1,T2,P1,P2).
normalize(P1,P2,P1,P2) :- P1 @> P2.
normalize(P1,P2,P2,P1) :- P1 @=< P2.
which returns
?- same_3(P1,P2,Item).
P1 = sam,
P2 = josh,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Notice that this result has the names in the same order.
Now to just save the results as they are generated and only add unique items to the result. This is done using setof/3.
?- setof((P1,P2,Item),(same_3(P1,P2,Item)),Bag).
Bag = [(sam, josh, muse)].
add a comment |
In reading your question you first gave a database of facts
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
but then used list for the predicate
same([josh,muse], [sam,muse]).
As Paulo answered starting with list, I will answer starting with facts.
The first thing is to create a predicate that reads the facts, does some logic and returns results.
same_1(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item).
which gives
?- same_1(P1,P2,Item).
P1 = P2, P2 = josh,
Item = muse ;
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
P1 = P2, P2 = sam,
Item = muse ;
P1 = P2, P2 = josh,
Item = gnr ;
P1 = P2, P2 = sam,
Item = radiohead.
So this needs to make sure P1 is not the same as P2.
same_2(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item),
P1 = P2.
which gives
?- same_2(P1,P2,Item).
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Still two answers that are valid but essentially a duplicate. To remove these duplicates requires storing all of the results so that each new result can be checked against existing results and not added to the current results. Also before storing the results they need to be normalized so that no matter which way the names are ordered when initially created they are in the same order when comparing them before saving them.
Modifying the code to create normalized entries.
same_3(P1,P2,Item) :-
likes(T1,Item),
likes(T2,Item),
T1 = T2,
normalize(T1,T2,P1,P2).
normalize(P1,P2,P1,P2) :- P1 @> P2.
normalize(P1,P2,P2,P1) :- P1 @=< P2.
which returns
?- same_3(P1,P2,Item).
P1 = sam,
P2 = josh,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Notice that this result has the names in the same order.
Now to just save the results as they are generated and only add unique items to the result. This is done using setof/3.
?- setof((P1,P2,Item),(same_3(P1,P2,Item)),Bag).
Bag = [(sam, josh, muse)].
add a comment |
In reading your question you first gave a database of facts
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
but then used list for the predicate
same([josh,muse], [sam,muse]).
As Paulo answered starting with list, I will answer starting with facts.
The first thing is to create a predicate that reads the facts, does some logic and returns results.
same_1(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item).
which gives
?- same_1(P1,P2,Item).
P1 = P2, P2 = josh,
Item = muse ;
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
P1 = P2, P2 = sam,
Item = muse ;
P1 = P2, P2 = josh,
Item = gnr ;
P1 = P2, P2 = sam,
Item = radiohead.
So this needs to make sure P1 is not the same as P2.
same_2(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item),
P1 = P2.
which gives
?- same_2(P1,P2,Item).
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Still two answers that are valid but essentially a duplicate. To remove these duplicates requires storing all of the results so that each new result can be checked against existing results and not added to the current results. Also before storing the results they need to be normalized so that no matter which way the names are ordered when initially created they are in the same order when comparing them before saving them.
Modifying the code to create normalized entries.
same_3(P1,P2,Item) :-
likes(T1,Item),
likes(T2,Item),
T1 = T2,
normalize(T1,T2,P1,P2).
normalize(P1,P2,P1,P2) :- P1 @> P2.
normalize(P1,P2,P2,P1) :- P1 @=< P2.
which returns
?- same_3(P1,P2,Item).
P1 = sam,
P2 = josh,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Notice that this result has the names in the same order.
Now to just save the results as they are generated and only add unique items to the result. This is done using setof/3.
?- setof((P1,P2,Item),(same_3(P1,P2,Item)),Bag).
Bag = [(sam, josh, muse)].
In reading your question you first gave a database of facts
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
but then used list for the predicate
same([josh,muse], [sam,muse]).
As Paulo answered starting with list, I will answer starting with facts.
The first thing is to create a predicate that reads the facts, does some logic and returns results.
same_1(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item).
which gives
?- same_1(P1,P2,Item).
P1 = P2, P2 = josh,
Item = muse ;
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
P1 = P2, P2 = sam,
Item = muse ;
P1 = P2, P2 = josh,
Item = gnr ;
P1 = P2, P2 = sam,
Item = radiohead.
So this needs to make sure P1 is not the same as P2.
same_2(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item),
P1 = P2.
which gives
?- same_2(P1,P2,Item).
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Still two answers that are valid but essentially a duplicate. To remove these duplicates requires storing all of the results so that each new result can be checked against existing results and not added to the current results. Also before storing the results they need to be normalized so that no matter which way the names are ordered when initially created they are in the same order when comparing them before saving them.
Modifying the code to create normalized entries.
same_3(P1,P2,Item) :-
likes(T1,Item),
likes(T2,Item),
T1 = T2,
normalize(T1,T2,P1,P2).
normalize(P1,P2,P1,P2) :- P1 @> P2.
normalize(P1,P2,P2,P1) :- P1 @=< P2.
which returns
?- same_3(P1,P2,Item).
P1 = sam,
P2 = josh,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Notice that this result has the names in the same order.
Now to just save the results as they are generated and only add unique items to the result. This is done using setof/3.
?- setof((P1,P2,Item),(same_3(P1,P2,Item)),Bag).
Bag = [(sam, josh, muse)].
answered Nov 22 '18 at 21:19
Guy CoderGuy Coder
15.4k43983
15.4k43983
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437271%2fprolog-check-if-first-element-in-lists-are-not-equal-and-second-item-in-list-is%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown