Deterministic Finite Automata pattern - algorithm

I'm trying to solve this problem using Deterministic Finite Automata :
inputs: {a,b}
conditions:
a. must have exactly 2 a
b. have more than 2 b
so a correct input should be like this abbba or bbbaa or babab
now my question is, "is there a pattern to solve this things?"

Yes there is a pattern. You can take each statement and deduct pre-states from them. Then you take the cross-product of those pre-states, which will comprise the final states. In this example:
a. will yield states: 0a, 1a, 2a, 2+a (you've seen 0 a, 1 a, 2 as or more than 2 as)
b. will yield states: 0b, 1b, 2b, 2+b (you've seen 0 b, 1 b, 2 bs or more than 2 bs)
The cross product of these states result in 4x4=16 states. You'll start from {0a,0b} states. The inputs can be 3 types: a, b or something else.
From that you should be able to go. Do you need more help?
(Are we solving homework?)

Always draw such things first.
Feel free to give states any meanings. What you need here is states like: q2: (1 b, 2 a's). Draw states like this, until the accept state and connect them with lines. The accept state is qx: 2 a's 3 b's.
After reaching the accept state, if input is "b" that line goes to itself, the accept state. If the input is "a", draw a new state, that will get into an endless loop and goes into itself no matter what the input is.
(are we helping for an exam here?)

Related

Propagating recursive property if all predecessors satisfy it

I am working on a directed acyclic graph where a node can satisfy a property. I want to propagate this property recursively on other nodes. The rule is that a node satisfies this property if and only if all of its direct predecessors satisfy it as well.
The following of course does not work, since it would be enough if ONE parent satisfied the property, while I need ALL parents to satisfy it in order to propagate.
satisfies(node) :- isParent(parent, node), satisfies(parent).
Things I tried:
writing a doesNotSatisfy rule instead, which would work, but by doing that, I ran into the exact same issue elsewhere in the program
negating the thing with a !, but that gave me cyclic negations
What helped me in the past with datalog was to solve the problem naturally as a human on paper. But here I don't see any other way than to try to satisfy the "for all" rule.
Is that somehow possible in datalog? And if yes, how?
Okay, what you describe can certainly be achieved with standard Datalog without introducing cyclical negative dependencies. You need two things
forall p = ! exists ! p, which it seems you already figured out
seperation of base property and derived property
Here's a very generic example that you can easily adapt.
Here's a simple graph: the nodes with + possess the basic property (base case). The ones with * are those for which all successors satisfy the property.
1 -- 2 -- 3 * --- 5 + *
|\ \----- 6 + *
| \-- 4 * -- 8 + *
\---- 7
First, encode the graph.
transition(1,2).
transition(2,3).
transition(2,4).
transition(3,5).
transition(3,6).
transition(2,7).
transition(4,8).
Auxiliary to enumerate all nodes.
node(Node) :- transition(Node, _).
node(Node) :- transition(_, Node).
Mark the base case (+ nodes).
property(5).
property(6).
property(8).
Find nodes that does not have to property.
notProperty(Node) :- node(Node), ! property(Node).
Now we figure out the * nodes. Either we know it trivially via property(Node). Or that we can transition to a node where it is not the case that property does not hold.
propertyDerived(Node) :- property(Node).
propertyDerived(Node) :- transition(Node,Next), ! notProperty(Next).
The reason the program can avoid cyclical negation is because I have separated propertyDerived from property which in your example is confounded.
Now if you query, you'd get what you expect!
?- propertyDerived(Node).
3
4
5
6
8

Understanding universal restriction of a concept in Description Logic (DL)

I am trying to understand the following Passage from a DL tutorial in terms of First Order Logic (FOL).
Passage
To represent the set of individuals all of whose children are female, we use the universal restriction
∀parentOf.Female (16)
It is a common error to forget that (16) also includes those individuals that have no children at all.
I take (16) to mean "if an individual has children, then those children are all female". My FOL representation of (16) is:
∀x∀y(parentOf(x,y) → Female(y)) (1)
My rational for this translation is that the implicit variable x represents the set of individuals being defined by the role parentOf. I assume x is universally quantified. The variable y represents female children, which I believe is called the successor of x in DL terminology, it is explicitly universally quantified in DL.
My FOL representation of "individuals that have no children at all" in FOL is:
∀x∀y ¬(parentOf(x,y)) (2)
My interpretation of the Passage, in FOL terms, is that if (2) holds then (1) holds. This is because the antecedent of (1) is false in this case.
Is my interpretation of the Passage correct?
Are my translations correct?
About your formula (1)
If you say
∀x∀y(parentOf(x,y) → Female(y))
or, equivalently
∀y((∃x parentOf(x,y)) → Female(y))
you mean that every x can only have female children. But for stating this in DL you need concept inclusion, that is:
⊤ ⊑ ∀parentOf.Female
that means "the range of role parentOf is included in concept Female".
Concept and role inclusions are intensional assertions, i.e., axioms specifying general properties of DL constructs.
Instead, DL's restrictions are not assertions, but constructs like concepts. So they are not used to state properties that are valid for every individual of the ontology. Like, when you say C⊓D, you are not stating that all the individuals of your ontology are instances of C and D, but you are simply "collecting" only the individuals that are instances of C and D at the same time.
Therefore, the formula ∀parentOf.Female just wants to "catch" all the x such that, if x is parent of y, then y is Female. More formally, its semantics is the following:
{x|∀y (parentOf(x,y) → Female(y))}
About your formula (2)
Analogously, the semantics of "individuals that have no children at all" is a set of individuals too:
{x|∀y ¬parentOf(x,y)}
or equivalently
{x|¬∃y parentOf(x,y)}
Indeed, you are collecting all the individuals that have no children, and not stating that all the individuals have no children.
Conclusion
You say right: "if (2) holds then (1) holds". The point is that neither (2) nor (1) (necessarily) hold.
Since you are working with sets, you should not reason in terms of logical inference but of set inclusion.
Therefore, the correct interpretation of the Passage is not
if ∀x∀y ¬(parentOf(x,y)) then ∀x∀y(parentOf(x,y) → Female(y))
but
{x|∀y ¬parentOf(x,y)} is a subset of {x|∀y (parentOf(x,y) → Female(y))}

Knights and Knives Logical Proposition

I have a question regarding Knights and Knaves and logical proposition. If I want to solve the puzzle and I assume I have two kinds of citizens: Knights, who always tell the truth, and knaves, who always tell lies. On the basis of utterances from some citizens, I must decide what kind they are.
There are three kinds of citizens: a, b and c, who are talking about themselves:
a says: ”All of us are knaves.”
b says: ”Exactly one of us is a knight.”
To solve the puzzle I should determine: What kinds of citizens are a, b and c? I should solve the puzzle by modelling the two utterances above using propositional logic, and I assume that I can use p to describe a knight and ¬p to describe a knave. How would I go about doing that? Any hint for someone who hasn't done any noticeable discrete mathematics in college?
A and C are Knaves. B is a Knight.
If A is a Knight, "All of us are knaves" is true. So, A would also be a Knave. This is a contradiction. Hence, A is a Knave.
If B is a Knave, then "Exactly one of us is a knight." is false. Meaning that 2 or more are Knights. But neither A nor B is a Knight. How can possibly be 2 or more Knights (since C is the only one with a possibility of being a Knight). This is also a contradiction. So, B is a Knight.
We just showed that B is a Knight. So, he himself is the only Knight he is talking about. So, C is a Knave.
Now, I don't think you can model this argument in the Propositional Logic. For one, notice the universal and existential quantifiers ("All" and "Exactly One") in the statements "All of us are knaves" and "Exactly one of us is a knight.". For another one, notice that A and B are talking about themselves. Modeling situations like this is one of the hardest problems in the history (not kidding!). Look at the following links for more info:
https://en.wikipedia.org/wiki/Liar_paradox
https://en.wikipedia.org/wiki/Self-reference
you can create a Truth table,
by first look at it i can say A must be knave, and B is a knight. because if A is a knight he can't say he's a knave(lie), also he can't be right about that all are knaves (can't say the truth) so B is a knight(if B Knave he can't say the truth that makes A a liar and he must be one) and then C is a Knave.

Example channelling constraints ECLiPSe

Can someone provide a simple example of channelling constraints?
Channelling constraints are used to combine viewpoints of a constraint problem. Handbook of Constraint Programming gives a good explanation of how it works and why it can be useful:
The search variables can be the variables of one of the viewpoints, say X1 (this is discussed further below). As
search proceeds, propagating the constraints C1 removes values from the domains of the
variables in X1. The channelling constraints may then allow values to be removed from
the domains of the variables in X2. Propagating these value deletions using the constraints
of the second model, C2, may remove further values from these variables, and again these
removals can be translated back into the first viewpoint by the channelling constraints. The
net result can be that more values are removed within viewpoint V1 than by the constraints
C1 alone, leading to reduced search.
I do not understand how this is implemented. What are these constraints exactly, how do they look like in a real problem? A simple example would be very helpful.
As stated in Dual Viewpoint Heuristics for Binary Constraint Satisfaction Problems (P.A. Geelen):
Channelling constraints of two different models allows for the expression of a relationship between two sets of variables, one of each model.
This implies assignments in one of the viewpoints can be translated into assignments in the other and vice versa, as well as, when search initiates,
excluded values from one model can be excluded from the other as well.
Let me throw in an example I implemented a while ago while writing a Sudoku solver.
Classic viewpoint
Here we interpret the problem in the same way a human would: using the
integers between 1 and 9 and a definition that all rows, columns and blocks must contain every integer exactly once.
We can easily state this in ECLiPSe using something like:
% Domain
dim(Sudoku,[N,N]),
Sudoku[1..N,1..N] :: 1..N
% For X = rows, cols, blocks
alldifferent(X)
And this is yet sufficient to solve the Sudoku puzzle.
Binary boolean viewpoint
One could however choose to represent integers by their binary boolean arrays (shown in the answer by #jschimpf). In case it's not clear what this does, consider the small example below (this is built-in functionality!):
?­ ic_global:bool_channeling(Digit, [0,0,0,1,0], 1).
Digit = 4
Yes (0.00s cpu)
?­ ic_global:bool_channeling(Digit, [A,B,C,D], 1), C = 1.
Digit = 3
A = 0
B = 0
C = 1
D = 0
Yes (0.00s cpu)
If we use this model to represent a Sudoku, every number will be replaced by its binary boolean array and corresponding constraints can be written. Being trivial for this answer, I will not include all the code for the constraints, but a single sum constraint is yet enough to solve a Sudoku puzzle in its binary boolean representation.
Channelling
Having these two viewpoints with corresponding constrained models now gives the opportunity to channel between them and see if any improvements were made.
Since both models are still just an NxN board, no difference in dimension of representation exists and channelling becomes real easy.
Let me first give you a last example of what a block filled with integers 1..9 would look like in both of our models:
% Classic viewpoint
1 2 3
4 5 6
7 8 9
% Binary Boolean Viewpoint
[](1,0,0,0,0,0,0,0,0) [](0,1,0,0,0,0,0,0,0) [](0,0,1,0,0,0,0,0,0)
[](0,0,0,1,0,0,0,0,0) [](0,0,0,0,1,0,0,0,0) [](0,0,0,0,0,1,0,0,0)
[](0,0,0,0,0,0,1,0,0) [](0,0,0,0,0,0,0,1,0) [](0,0,0,0,0,0,0,0,1)
We now clearly see the link between the models and simply write the code to channel our decision variables. Using Sudoku and BinBools as our boards, the code would look something like:
( multifor([Row,Col],1,N), param(Sudoku,BinBools,N)
do
Value is Sudoku[Row,Col],
ValueBools is BinBools[Row,Col,1..N],
ic_global:bool_channeling(Value,ValueBools,1)
).
At this point, we have a channelled model where, during search, if values are pruned in one of the models, its impact will also occur in the other model. This can then of course lead to further overall constraint propagation.
Reasoning
To explain the usefulness of the binary boolean model for the Sudoku puzzle, we must first differentiate between some provided alldifferent/1 implementations by ECLiPSe:
What this means in practice can be shown as following:
?­ [A, B, C] :: [0..1], ic:alldifferent([A, B, C]).
A = A{[0, 1]}
B = B{[0, 1]}
C = C{[0, 1]}
There are 3 delayed goals.
Yes (0.00s cpu)
?­ [A, B, C] :: [0..1], ic_global:alldifferent([A, B, C]).
No (0.00s cpu)
As there has not yet occurred any assignment using the Forward Checking (ic library), the invalidity of the query is not yet detected, whereas the Bounds Consistent version immediately notices this. This behaviour can lead to considerable differences in constraint propagation while searching and backtracking through highly constrained models.
On top of these two libraries there is the ic_global_gac library intended for global constraints for which generalized arc consistency (also called hyper arc consistency or domain consistency) is maintained. This alldifferent/1 constraint provides even more pruning opportunities than the bounds consistent one, but preserving full domain consistency has its cost and using this library in highly constrained models generally leads to a loss in running performance.
Because of this, I found it interesting for the Sudoku puzzle to try and work with the bounds consistent (ic_global) implementation of alldifferent to maximise performance and subsequently try to approach domain consistency myself by channelling the binary boolean model.
Experiment results
Below are the backtrack results for the 'platinumblonde' Sudoku puzzle (referenced as being the hardest, most chaotic Sudoku puzzle to solve in The Chaos Within Sudoku, M. Ercsey­Ravasz and Z. Toroczkai) using respectively forward checking, bounds consistency, domain consistency, standalone binary boolean model and finally, the channelled model:
(ic) (ic_global) (ic_global_gac) (bin_bools) (channelled)
BT 6 582 43 29 143 30
As we can see, our channelled model (using bounds consistency (ic_global)) still needs one backtrack more than the domain consistent implementation, but it definitely performs better than the standalone bounds consistent version.
When we now take a look at the running times (results are the product of calculating an average over multiple executions, this to avoid extremes) excluding the forward checking implementation as it's proven to no longer be interesting for solving Sudoku puzzles:
(ic_global) (ic_global_gac) (bin_bools) (channelled)
Time(ms) 180ms 510ms 100ms 220ms
Looking at these results, I think we can successfully conclude the experiment (these results were confirmed by 20+ other Sudoku puzzle instances):
Channelling the binary boolean viewpoint to the bounds consistent standalone implementation produces a slightly less strong constraint propagation behaviour than that of the domain consistent standalone implementation, but with running times ranging from just as long to notably faster.
EDIT: attempt to clarify
Imagine some domain variable representing a cell on a Sudoku board has a remaining domain of 4..9. Using bounds consistency, it is guaranteed that for both value 4 and 9 other domain values can be found which satisfy all constraints and thus provides consistency. However, no consistency is explicitly guaranteed for other values in the domain (this is what 'domain consistency' is).
Using a binary boolean model, we define the following two sum constraints:
The sum of every binary boolean array is always equal to 1
The sum of every N'th element of every array in every row/col/block is always equal to 1
The extra constraint strength is enforced by the second constraint which, apart from constraining row, columns and blocks, also implicitly says: "every cell can only contain every digit once". This behaviour is not actively expressed when using just the bounds consistent alldifferent/1 constraint!
Conclusion
It is clear that channelling can be very useful to improve a standalone constrained model, however if the new model's constraint strengthness is weaker than that of the current model, obviously, no improvements will be made. Also note that having a more constrained model doesn't necesarilly also mean an overall better performance! Adding more constraints will in fact decrease amounts of backtracks required to solve a problem, but it might also increase the running times of your program if more constraint checks have to occur.
Channeling constraints are used when, in a model, aspects of a problem are represented in more than one way. They are then necessary to synchronize these multiple representations, even though they do not themselves model an aspect of the problem.
Typically, when modelling a problem with constraints, you have several ways of choosing your variables. For example, in a scheduling problem, you could choose to have
an integer variable for each job (indicating which machine does the job)
an integer variable for each machine (indicating which job it performs)
a matrix of Booleans (indicating which job runs on which machine)
or something more exotic
In a simple enough problem, you choose the representation that makes it easiest to formulate the constraints of the problem. However, in real life problems with many heterogeneous constraints it is often impossible to find such a single best representation: some constraints are best represented with one type of variable, others with another.
In such cases, you can use multiple sets of variables, and formulate each individual problem constraint over the most convenient variable set. Of course, you then end up with multiple independent subproblems, and solving these in isolation will not give you a solution for the whole problem. But by adding channeling constraints, the variable sets can be synchronized, and the subproblems thus re-connected. The result is then a valid model for the whole problem.
As hinted in the quote from the handbook, in such a formulation is is sufficient to perform search on only one of the variable sets ("viewpoints"), because the values of the others are implied by the channeling constraints.
Some common examples for channeling between two representations are:
Integer variable and Array of Booleans:
Consider an integer variable T indicating the time slot 1..N when an event takes place, and an array of Booleans Bs[N] such that Bs[T] = 1 iff an event takes place in time slot T. In ECLiPSe:
T #:: 1..N,
dim(Bs, [N]), Bs #:: 0..1,
Channeling between the two representations can then be set up with
( for(I,1,N), param(T,Bs) do Bs[I] #= (T#=I) )
which will propagate information both ways between T and Bs. Another way of implementing this channeling is the special purpose bool_channeling/3 constraint.
Start/End integer variables and Array of Booleans (timetable):
We have integer variables S,E indicating the start and end time of an activity. On the other side an array of Booleans Bs[N] such that Bs[T] = 1 iff the activity takes place at time T. In ECLiPSe:
[S,E] #:: 1..N,
dim(Bs, [N]), Bs #:: 0..1,
Channeling can be achieved via
( for(I,1,N), param(S,E,Bs) do Bs[I] #= (S#=<I and I#=<E) ).
Dual representation Job/Machine integer variables:
Here, Js[J] = M means that job J is executed on machine M, while the dual formulation Ms[M] = J means that machine M executes job J
dim(Js, [NJobs]), Js #:: 0..NMach,
dim(Ms, [NMach]), Ms #:: 1..NJobs,
And channeling is achieved via
( multifor([J,M],1,[NJobs,NMach]), param(Js,Ms) do
(Js[J] #= M) #= (Ms[M] #= J)
).
Set variable and Array of Booleans:
If you use a solver (such as library(ic_sets)) that can directly handle set-variables, these can be reflected into an array of booleans indicating membership of elements in the set. The library provides a dedicated constraint membership_booleans/2 for this purpose.
Here is a simple example, works in SWI-Prolog, but should
also work in ECLiPSe Prolog (in the later you have to use (::)/2 instead of (in)/2):
Constraint C1:
?- Y in 0..100.
Y in 0..100.
Constraint C2:
?- X in 0..100.
X in 0..100.
Channelling Constraint:
?- 2*X #= 3*Y+5.
2*X#=3*Y+5.
All together:
?- Y in 0..100, X in 0..100, 2*X #= 3*Y+5.
Y in 1..65,
2*X#=3*Y+5,
X in 4..100.
So the channel constraint works in both directions, it
reduces the domain of C1 as well as the domain of C2.
Some systems use iterative methods, with the result that this channelling
can take quite some time, here is an example which needs around
1 minute to compute in SWI-Prolog:
?- time(([U,V] ins 0..1_000_000_000, 36_641*U-24 #= 394_479_375*V)).
% 9,883,559 inferences, 53.616 CPU in 53.721 seconds
(100% CPU, 184341 Lips)
U in 346688814..741168189,
36641*U#=394479375*V+24,
V in 32202..68843.
On the other hand ECLiPSe Prolog does it in a blink:
[eclipse]: U::0..1000000000, V::0..1000000000,
36641*U-24 #= 394479375*V.
U = U{346688814 .. 741168189}
V = V{32202 .. 68843}
Delayed goals:
-394479375 * V{32202 .. 68843} +
36641 * U{346688814 .. 741168189} #= 24
Yes (0.11s cpu)
Bye

Prolog - Towers of Hanoi

I'm trying to write a program to solve the towers of hanoi problem in Prolog. None of the posts here helped me so I decided to ask for myself. I have written the following code. It works well for 2 disks but goes into an infinite loop for 3.
hanoi(1,A,B,_,[(A,B)]).
hanoi(X,A,B,C,Y):-
hanoi(X2,A,C,B,Y1),
hanoi(1,A,B,_,[Y2]),
hanoi(X2,C,B,A,Y3),
append(Y1,[Y2|Y3],Y),
X2 is X-1.
It is called in the following way:
?- hanoi(3, a, b, c, Y).
a,b,c are the pegs. 3 is the number of disks and X is where we want the result.
I need to get the result in Y. I'm trying to recursively find the moves for X-1 discs from peg 1 to 3 using 2, 1 disc from peg 1 to 2, X-1 discs from peg 3 to 2 and append them. I can't understand what I'm doing wrong. Any help or guidance would be appreciated! Thanks!
The obvious problem -
When you have a conjunction, like:
a, b, c
You have two readings of this, logical and procedural. The logical reading would be:
"The conjunction is true if a is true, and b is true, and c is true."
The procedural reading is:
"The conjunction will succeed if a is evaluated and succeeds, then b is evaluated and it also succeeds, and then c is evaluated and it also succeeds." (or, to put it in other words, do a depth-first search of the solution space)
If you are careful enough, the procedural reading is not necessary to argue about your code. However, this is only the case when all subgoals in the conjunction have full overlap of the logical and the procedural reading.
The offender here is is/2. It does not have a purely logical meaning. It evaluates the right-hand operand (the arithmetic expression) and unifies the result with the left-hand (usually an unbound variable).
Here, you have a conjunction (in the body of the second clause) that says, in effect, "evaluate a(X), then, if it succeeds, find the value of X". The obvious problem is that a(X) requires the value of X to be evaluated in such a way that it terminates.
So, move the is before all subgoals that use its result, or look into using constraints.

Resources