Why is (a and (not b)) or (a and b) = a? - boolean

I reached the end of a pretty long Boolean simplification, where I was supposed to prove that something = a. I reached a point (a and (not b)) or (a and b). Any further reorganization of the equation did not bring me further. But using a Truth tabel I checked to see that (a and (not b)) or (a and b) indeed does equal a. And it does make sense intuitively too, but can you actually use the Laws of Boolean Algebra to turn (a and (not b)) or (a and b) into a?

It makes more sense when you use the simplified notation, * for and, + for or, ~ for not.
(a and b) or (a and (not b)) =
(a*b)+(a*(~b)) =
a*(b+(~b)) =
a*(1) =
a

((a and (not b)) or (a and b)) ... distributive law
<=> (a and (b or not b) ... (b or not b) is alway true
<=> a

Feel free to distribute:
c = (a and ¬b)
(a and b) or c
(a or c) and (b or c)
(a or (a and ¬b)) and (b or (a and ¬b))
distribute again for both the left and right sides:
((a or a) and (a or ¬b)) and ((b or a) and (b or ¬b))
simplify:
(a and (a or ¬b)) and ((b or a) and T)
(a and (a or ¬b)) and (b or a)
simplify again (using the absorption property = x and (x or y) == x):
(a) and (b or a)
and again:
a and (a or b)
== a
(I know this is a bit of the long way around...)

Related

question about how to search the occurs times of element in list by lisp

If I want to find the occurs times of an element in a long list, what should I do?
for example
(input 1 '((l1 (a b c)) (l2 (b a e))))
then the result should be (c e) since they occur 1 time
also
(input 3 '((l1 (a b c)) (l2 (b a e)) (l3 (a b c))))
then the result should be (a b) since they occur 3 times
and if the input number n larger than the length of L it will return nil
(if (<(length L) n) nil)

How do I simplify(expand) this Boolean expression?

Expression - (A OR B OR C OR D) AND (!B AND !D)
I know that with distributive property, it holds that (a OR b) AND (c OR d) = (a AND c) OR (a AND d) OR (b AND c) or (b AND d) but I'm not sure how it will work if the second group has an AND
Steps in the answer would help.
Something like this perhaps?
(A OR B OR C OR D) AND (!B AND !D)
= (A OR B OR C OR D) AND !(B OR D)
= ((A OR C) OR (B OR D)) AND !(B OR D)
= ((A OR C) AND !(B OR D)) OR ((B OR D) AND !(B OR D))
= (A OR C) AND !(B OR D) OR false
= (A OR C) AND !(B OR D)
That seems like it's going to be minimal since each variable appears once and there are no apparent contradictions or tautologies.

How can i get all possible combinations of sets and subsets of a list that satisfy conditions with Common Lisp

For a list of elements for L = (A B C D), to generate all the combinations possible of elements that satisfy the lexicographical order of elements (A < B < C < D ...< Z), will be generated all combination.
For example L = (A B C D) well output (A), (B), (C), (D), (A B), (B C), (C D), (A B C), (B C D), (A B C D).
The lexicographical (not lexicological) order can be obtained through the following function that checks if the list a precedes the list b in lexicographical order:
(defun lex<= (a b)
(or (null a)
(and b
(string<= (car a) (car b))
(lex<= (cdr a) (cdr b)))))
so, you could produce all the combinations, like in the answer of coredump, and then sort them with (sort result #'lex<=).
Looks like you just write simple function to get power set of your list, and then just remove an empty set, and order it in any way you want.
(defun powerset (lst)
(if lst (mapcan (lambda (el) (list (cons (car lst) el) el))
(powerset (cdr lst)))
'(())))
CL-USER> (powerset '(A B C D))
((A B C D) (B C D) (A C D) (C D) (A B D) (B D) (A D) (D) (A B C) (B C) (A C)
(C) (A B) (B) (A) NIL)
To get exactly your describet output you can remove NIL and reverse it:
CL-USER> (reverse (remove nil (powerset '(A B C D))))
((A) (B) (A B) (C) (A C) (B C) (A B C) (D) (A D) (B D) (A B D) (C D) (A C D)
(B C D) (A B C D))
Is this what you want?
UPDATE. Sorry, didn't mention that you want it sorte in another way. You should resort it:
CL-USER> (sort
(reverse
(remove nil
(powerset '(A B C D))))
#'< :key #'length)
((A) (B) (C) (D) (A B) (A C) (B C) (A D) (B D) (C D) (A B C) (A B D) (A C D)
(B C D) (A B C D))
And this is another, more imparative solution, using loop macro, doing what you described:
(defun combinations (lst)
(loop :for i :below (expt 2 (length lst))
:when (loop :for j :below i :for el :in lst if (logbitp j i) :collect el)
:collect it :into result
:finally (return (sort result #'< :key #'length))))
CL-USER> (combinations '(A B C D E))
((A) (B) (C) (D) (E) (A B) (A C) (B C) (A D) (B D) (C D) (A E) (B E) (C E)
(D E) (A B C) (A B D) (A C D) (B C D) (A B E) (A C E) (B C E) (A D E) (B D E)
(C D E) (A B C D) (A B C E) (A B D E) (A C D E) (B C D E) (A B C D E))

Sublist in common lisp

I have list of lists in my program
for example
(( a b) (c d) (x y) (d u) ........)
Actually I want to add 1 new element in the list but new element would be a parent of all existing sublists.
for example if a new element is z, so my list should become like this
( (z( a b) (c d) (x y) (d u) ........))
I have tried with push new element but it list comes like this
( z( a b) (c d) (x y) (d u) ........)
that I dont want as I have lot of new elements coming in and each element represents some block of sublists in the list
Your help would highly be appreciated.
It sounds like you just need to wrap the result of push, cons, or list* in another list:
(defun add-parent (children parent)
(list (list* parent children)))
(add-parent '((a b) (c d) (x y) (d u)) 'z)
;;=> ((Z (A B) (C D) (X Y) (D U)))
This is the approach that I'd probably take with this. It's just important that you save the return value. In this regard, it's sort of like the sort function.
However, if you want to make a destructive macro out of that, you can do that too using define-modify-macro. In the following, we use define-modify-macro to define a macro add-parentf that updates its first argument to be the result of calling add-parent (defined above) with the first argument and the parent.
(define-modify-macro add-parentf (parent) add-parent)
(let ((kids (copy-tree '((a b) (c d) (x y) (d u)))))
(add-parentf kids 'z)
kids)
;;=> ((Z (A B) (C D) (X Y) (D U)))
For such a simple case you can also use a shorter backquote approach, for example:
(let ((parent 'z) (children '((a b) (c d) (e f))))
`((,parent ,#children)))
If you aren't familiar with backquote, I'd recommend reading the nice and concise description in Appendix D: Read Macros of Paul Graham's ANSI Common Lisp.

boolean algebra simplification provided equation

i have this one
OM5= NOT ( A OR (B AND C)) OR D
i provided i photo of it.
http://i.stack.imgur.com/opS1I.png
I used different calcs that were online and all gave me this result
http://www.wolframalpha.com/input/?i=not+(a+or+b%26%26c)+or+d like the wolframalpha one!
But when i did it with my hand i had different results.
the result was NOT(A) AND ( NOT(B) OR NOT(C) OR D )
NOT ( A OR (B AND C)) OR D
= (NOT A AND NOT (B AND C)) OR D
= (NOT A AND (NOT B OR NOT C)) OR D
= (NOT A AND NOT B) OR (NOT A AND NOT C) OR D
That's it.