Related
I'm new to Prolog and I am confused because the else clause is being executed even if it doesn't meet the condition.
printNum(A, B) :-
A =< B,
writeln(A),
A1 is A + 1,
ignore(printNum(A1, B))
; A > B,
writeln(error).
if you try to input printNum(3, 6) with this code, it outputs:
3
4
5
6
error
true
my expected result is:
3
4
5
6
true
since A !> B
Well, the problem is that the or operation is executed at the ignore(printNum(A1, B)); A > B line rather than being executed in the whole predicate. If you modify the code a little bit :
printNum(A, B) :-
(A =< B,
writeln(A),
A1 is A + 1,
ignore(printNum(A1, B))
;
A > B,
writeln(error)).
This way, the logical or operation will work correctly, and you will get the desired output.
Using Sicstus and given the list
[b > f, f > c, c > b, g > h, g > g, d, b, f > k, k > f, f > c]
I want to transform it to:
graph([b,c,d,f,g,h,k],[e(b,f),e(c,b),e(f,c),e(f,k),e(g,g),e(g,h),e(k,f)])
My goal is to transform the first list to the two separate lists by only one pass through the former and the usage of two accumulators.
hf_to_graph_term([H|T], AccN, Nodes, AccE, Edges):-
H = A>B,!,
merge([H],AccE,NewAccE),
hf_to_graph_term(T,AccN,Nodes,NewAccE,Edges).
However, I get the error message:
! Syntax error
! operator expected after expression
! in line 290
! hf_to_graph_term ( [ H | T ] , AccN , Nodes , AccE , Edges ) :- H = A
! <<here>>
! > B , ! ,
This is because > is reserved as comparison operator.
Which changes do I have to make in my code?
This is in fact a priority clash: for the interpreter it is not clear how it should read H = A > B, as H = (A > B), or (H = A) > B?
The solution is to make this explicit, and use brackets. You can rewrite the predicate to:
hf_to_graph_term([H|T], AccN, Nodes, AccE, Edges):-
H = (A > B),
!,
merge([H],AccE,NewAccE),
hf_to_graph_term(T,AccN,Nodes,NewAccE,Edges).
or you can do this in a more canonical form:
hf_to_graph_term([H|T], AccN, Nodes, AccE, Edges):-
H = >(A, B),
!,
merge([H],AccE,NewAccE),
hf_to_graph_term(T,AccN,Nodes,NewAccE,Edges).
Since here you do not seem to use A or B, we can also use underscores:
hf_to_graph_term([H|T], AccN, Nodes, AccE, Edges):-
H = >(_, _),
!,
merge([H],AccE,NewAccE),
hf_to_graph_term(T,AccN,Nodes,NewAccE,Edges).
If I have two premises as follows:
a -> c (a implies c)
b -> c (b implies c)
and a derived conclusion:
a -> b (a therefore implies b),
then the conclusion can be shown to be invalid because:
a -> c is valid for statement #1 when a is true and c is true, and
b -> c is valid for statement #2 when b is false and c is true. This leads to a -> b when a is true and b is false, a direct contradiction of statement #3.
Or, per proof with a truth table that contains a line for where the premises are true but the conclusion is false:
Truth Table with true premises and false conclusion
My question is: "Is there a way to use prolog to show that the assertions of statements #1 and #2 contradict the conclusion of statement #3? If so, what is a clear and concise way to do so?"
#coder has already given a very good answer, using clpb constraints.
I would like to show a slightly different way to show that the conclusion does not follow from the premises, also using CLP(B).
The main difference is that I post individual sat/1 constraints for each of the premises, and then use taut/2 to see whether the conclusion follows from the premises.
The first premise is:
a → c
In CLP(B), you can express this as:
sat(A =< C)
The second premise, i.e., b → c, becomes:
sat(B =< C)
If the a → b followed from these premises, then taut/2 would succeed with T = 1 in:
?- sat(A =< C), sat(B =< C), taut(A =< B, T).
false.
Since it doesn't, we know that the conclusion does not follow from the premises.
We can ask CLP(B) to show a counterexample, i.e., an assignment of truth values to variables where a → c and b → c both hold, and a → b does not hold:
?- sat(A =< C), sat(B =< C), sat(~(A =< B)).
A = C, C = 1,
B = 0.
Simply posting the constraints suffices to show the unique counterexample that exists in this case. If the counterexample were not unique, we could use labeling/1 to produce ground instances, for example: labeling([A,B,C]).
For comparison, consider for example:
?- sat(A =< B), sat(B =< C), taut(A =< C, T).
T = 1,
sat(A=:=A*B),
sat(B=:=B*C).
This shows that a → c follows from a → b ∧ b → c.
You could use library(clpb):
Firstly assign to a variable Expr your expression:
Expr = ((A + ~C)*(B + ~C)+(~(A + ~B)).
Note that:
'+' stands for logical OR
'*' for logical AND
'~' for logical NOT
Also A->B is equivalent with A+(~B). So the above expression is equivalent with ((A->C),(B->C))-> (A->C) where we wrote '->' using +,~ and ',' with *.
Now if we query:
?- use_module(library(clpb)).
true.
?- Expr=((A + ~C)*(B + ~C))+(~(A + ~B)),taut(Expr,T).
false.
Predicate taut/2 takes as input an clpb Expression and returns T=1 if it tautology, T=0 if expression cannot be satisfied and fails in any other case. So the fact that the above query failed means that Expr was nor a tautology neither could not be satisfied, it meant that it could be satisfied.
Also by querying:
?- Expr=((A + ~C)*(B + ~C))+(~(A + ~B)),sat(Expr).
Expr = (A+ ~C)* (B+ ~C)+ ~ (A+ ~B),
sat(1#C#C*B),
sat(A=:=A).
Predicate sat/1 returns True iff the Boolean expression is satisfiable and gives the answer that the above Expression is satisfiable when:
sat(1#C#C*B),
sat(A=:=A).
where '#' is the exclusive OR which means that your expression (we know from taut/2 that is satisfiable) is satisfied when 1#C#C*B is satisfied.
Another solution without using libraries could be:
truth(X):-member(X,[true,false]).
test_truth(A,B,C):-
truth(A),
truth(B),
truth(C),
((A->C),(B->C)->(A->C)).
Example:
?- test_truth(A,B,C).
A = B, B = C, C = true ;
false.
Also if I understood correctly from your comment, to collect all possible solutions you could write:
?- findall([A,B,C],test_truth(A,B,C),L).
L = [[true, true, true]].
Which gives a list of lists, where the inner lists have the form [true,true,true] in the above example which means a solution is A=true,B=true,C=true and in the above case it has only one solution.
To find all contradictions you could write:
truth(X):-member(X,[true,false]).
test_truth(A,B,C):-
truth(A),
truth(B),
truth(C),
not( (\+ ((\+A; C),(\+B ; C)) ; (\+A ; B)) ).
last line could also been written as:
not( ( (A->C;true),(B->C;true) ) -> (A->B;true) ;true ).
Example:
?- findall([A,B,C],test_truth(A,B,C),L).
L = [[true, false, true]].
If I have three or more objects like so:
a = 4
b = 4
c = 4
d = 2
what would be a clean ruby-style way of determining whether they are all equal? Any bespoke methods for running equality tests on three or more elements?
I suppose I could do something like this:
arrays = [a,b,c,d].map{|x| [x]}
arrays.first == arrays.reduce(:&) ? true : false
which appears to work, but feels sort of ham handed, and might be difficult for other developers to read.
[a,b,c,d].any?{|x| x != a}
or
array.any?{|x| x != array.first}
Alternatively, the #all? method may read more intuitively for some:
array.all? {|x| x == array.first }
[a, b, c, d].group_by(&:itself).length == 1
# => false
or
[a, b, c, d].chunk(&:itself).to_a.length == 1
# => false
or
[a, b, c, d].chunk_while(&:==).to_a.length == 1
# => false
or the naive:
[a, b, c, d].uniq.length == 1
I was reminded of one?. Provided that you do not have any falsy element, the above can be written:
[a, b, c, d].uniq.length.one?
I think the answer by #kipar is better by all means, but for the sake of “doing it the way you started” I would post this here:
[a, b, c, d].reduce { |r, e| r == e && r } && true
Using Prolog I'm trying to write a predicate that recognizes context free grammar and returns true if the input list matches the CFG.
The alphabet of the input consists only of a,b.
The CFG i'm trying to match is
S-> TT
T -> aTb | ab
I'm not quite sure how to implement this, mainly the T rule.
s(S0,S):-t(S0,S),t(S1,S).
t(S0,S):-S0 = a, t(S1,S), S1 = b; S0 = a, S1 = b.
match([H|T] :- s(H,T).
So if I query [a, a, b, b] it should return true.
However, I'm just getting an infinite loop.
I'm not quite sure how to implement the a^n b^n rule.
I would write the CFG in this way:
S -> T
T -> a T b | {epsilon}
that translates directly to a DCG:
s --> t.
t --> [].
t --> a, t, b.
Note I swapped the epsilon rule, to get the ability to generate phrases.
Translating that DCG by hand :
s(S0,S) :- t(S0,S).
t(S0,S0).
t(S0,S) :- S0=[a|S1], t(S1,S2), S2=[b|S].
Yields
?- phrase(s,L).
L = [] ;
L = [a, b] ;
L = [a, a, b, b] ;
L = [a, a, a, b, b, b] ;
...