%animal(X) :- X = dog.
animal(dog).
animal(barry).
animal(hobbes).

%likes(C, F) :- C = cat, F = fish.
likes(cat, fish).

%bigger(M1, M2) :- M1 = men, M2 = mice.
bigger(men, mice).

eats(X, Y) :- bigger(X, Y).

%pet(X) :- animal(X), sound(X, Y), Y = bark.
pet(X) :- animal(X), sound(X, bark).
pet(X) :- animal(X), sound(X, bubbles).


sound(dog, bark).
sound(barry, bubbles).
sound(hobbes, roar).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


father_of(juan, pedro).
%father_of(pedro, juan).
father_of(juan, maria).
father_of(pedro, miguel).
mother_of(maria, david).

%grandfather_of(juan, juan).
grandfather_of(L,M):- 
        father_of(L,N), 
        father_of(N,M).
grandfather_of(X,Y):- 
        father_of(X,Z), 
        mother_of(Z,Y). 

grandmother_of(L,M):- 
        mother_of(L,N), 
        father_of(N,M).
grandmother_of(X,Y):- 
        mother_of(X,Z), 
        mother_of(Z,Y). 




resistor(power,n1).
resistor(power,n2). 
transistor(n2,ground,n1).
transistor(n3,n4,n2).  
transistor(n5,ground,n4). 

inverter(Input,Output, Log, not(Log)):- 
   transistor(Input,ground,Output), 
   resistor(power,Output).

nand_gate(Input1,Input2,Output, Log1, Log2, nand(Log1, Log2)):- 
   transistor(Input1,X,Output),
   transistor(Input2,ground,X),
   resistor(power,Output).

and_gate(Input1, Input2, Output, Log1, Log2, LogNot):-
   nand_gate(Input1,Input2,X, Log1, Log2, LogNand),
   inverter(X, Output, LogNand, LogNot).


not_interpret(1, 0).
not_interpret(0, 1).
nand_interpret(0, 0, 1).
nand_interpret(0, 1, 1).
nand_interpret(1, 0, 1).
nand_interpret(1, 1, 0).

interpret(1, 1).
interpret(0, 0).

interpret(not(X), Z):- 
        interpret(X, Y),
        not_interpret(Y, Z).
interpret(nand(X, Y), Z):-
        interpret(X, X1),
        interpret(Y, Y1),
        nand_interpret(X1, Y1, Z).



natural(z).
natural(s(X)) :- natural(X).

plus(z, X, X):- natural(X).
plus(s(X), Y, s(Z)):- plus(X, Y, Z).

is_list([]). 
is_list([_Head|Tail]):- is_list(Tail).



memb(Element, [Element|_List]).
memb(Element, [_AnElement|RestList]):- 
    memb(Element, RestList).

submemb(Element, [Element|_List]).
submemb(Element, [First|_RestList]):- 
    submemb(Element, First).
submemb(Element, [_AnElement|RestList]):- 
    submemb(Element, RestList).


append([], X, X).
append([X|Xs], Y, [X|Zs]):-
        append(Xs, Y, Zs).

rev([], []).
rev([X|Xs],Ys ):-  
    rev(Xs,Zs), 
    append(Zs,[X],Ys).

palindrome(X):- rev(X, X).

suffix(Suffix, List):- append(_Prefix, Suffix, List).


hanoi(s(z),A,B,_C,[move(A, B)]).
hanoi(s(N),A,B,C,Moves):- 
    hanoi(N,A,C,B,M1),
    hanoi(N,C,B,A,M2),
    append(M1,[move(A, B)|M2],Moves).



initial(q0).      
final(q0).

delta(q0,a,q1).
delta(q1,b,q0).   
delta(q1,b,q1).

accept(S):- initial(Q), accept_(Q,S).

accept_(Q,[]):- final(Q).
accept_(Q,[X|Xs]):- delta(Q,X,NewQ), accept_(NewQ,Xs).


c_add(c(Re1,Im1), c(Re2,Im2), R):- 
    R = c(Re1+Re2,Im1+Im2). 
c_mult(c(Re1,Im1),c(Re2,Im2),c(Re3,Im3)):- 
    Re3 = Re1 * Re2 - Im1 * Im2, 
    Im3 = Re1 * Im2 + Re2 * Im1.

circuit(series(N1, N2), V, I, W):- 
    c_add(V1, V2, V), 
    circuit(N1, V1, I, W), circuit(N2, V2, I, W).

circuit(parallel(N1, N2), V, I, W):- 
    c_add(I1, I2, I), 
    circuit(N1, V, I1, W), circuit(N2, V, I2, W).

circuit(resistor(R), V, I, _W):- 
    c_mult(I, c(R, 0), V).

circuit(inductor(L), V, I, W):- 
    c_mult(I, c(0, W * L), V).

circuit(capacitor(C), V, I, W):-
    c_mult(I, c(0, -1 / (W * C)), V).



