Strongly Connected Components (SCC graph algorithm) in SML [closed] - algorithm

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I need to write SCC algorithm in standard ML. But I don't know how.
I have following TYPEs which have to be uesd in the code:
type vertex = int
type edge = int * int
type graph = (vertex * vertex list) list
fun dfs (g: graph) (n: vertex): vertex list =
let
fun helper (todo: vertex list) (visited: vertex list): vertex list =
case todo of
[] => []
| h::t => if (List.exists (fn x => x = h) visited)
then helper t visited
else
let
val adj = case List.find (fn (n, _) => n = h) g of
NONE => raise Fail "incomplete adjacency list"
| SOME (_, adj) => adj
in
h :: (helper (adj # t) (h::visited))
end
in
helper [n] []
end
The above code has been compiled and run correctly.
I put these in the code because I know in computing SCC dfs is needed.
Does anyone have a solution?

Pseudo code - http://algowiki.net/wiki/index.php/Tarjan's_algorithm.

I'm guessing that you're trying to use Standard ML ( http://www.smlnj.org/sml.html ) .
During your classroom time, your teacher should have presented either a modelling tool with which to create your SML code, or should have referred you to a resource with which to write the code. S/he should also have presented sample code - and your book (or a CD in the back of your book) should include SML code.
Assuming you don't have a modelling tool, my recommendation is as follows. Start by refering to the sample code that your teacher or book offers, and pick the code that solves a problem most similar to your needs. Copy & paste that into your answer, being absolutely sure to clearly cite the source at the very beginning of the answer. Then, use other examples from class, the details from your book, and the resources under the "documentation and literature" section of smlnj.org (particularly the tutorials) to implement your solution.
Then, if you have a stumbling block - something that wasn't discussed in class, and wasn't covered in your book, but you just can't solve, you should discuss it with your TA or your teacher. If you ask the question to one of them, then your teacher can find out that the topic wasn't clearly covered in class. If you don't ask them, then they won't know, and much of the rest of your class may have difficulty with the topic.
And finally, if your teacher and TA aren't available, and you're running into a problem that you just don't know how to solve, and you have a very specific question (like, "here's my code; it won't compile and I can't figure out why"), at that point you should ask Stack Overflow.

Related

Solve ~(P /\ Q) |- Q -> ~P in Isabelle

~(P /\ Q) |- Q -> ~P
I don't know where to start.
Negation confuses me.
I have to solve this in Isabelle (a program), but if someone explains how to solve using natural deduction, it will be enough help.
This is an example that the quality of an SO question is many times determined by an answer, not the question. I kind of give this answer to thank M.Eberl for another useful answer, since I can't make comments.
As to a comment above, that you may be asking a homework question, the comment is valid, but if you're confused by negation, then you're mostly doomed anyway, until you make progress, so even one complete answer wouldn't help you, and here, there's no right answer.
The formula is so basic, except through applying step-by-step rules, it would be hard for anyone to prove that they understand what they're proved, without going through the multitude of tedious steps to do so.
For example:
lemma "~(P ∧ Q) ==> Q --> ~P"
by auto
Surely that gets you nothing, if the requirement is that you demonstrate understanding.
I've largely made progress "by the method of absorption over time", and in his answer, M.Eberl gave a significant outline of the basics of natural deduction. My interest in it was to mess around and see if I could absorb a little more.
As to rule and erule, there is the cheat sheet:
http://www.phil.cmu.edu/~avigad/formal/FormalCheatSheet.pdf
As to the proof of logic by means of Isabelle, Isabelle/HOL is so big and involved, that a little help, once, doesn't get you much, though collectively, it's all important.
A basic, logic equivalency
I learned long ago the equivalent statement of an implication. It's even in HOL.thy, line 998:
lemma disj_not2: "(P | ~Q) = (Q --> P)"
From that, it's easy to see, along with DeMorgon's laws (line 993 of HOL.thy), that you stated an equivalency in your question.
Well, of course, not quite, and that's where all the hassle comes in. Rearranging things, based on trivial equivalencies, to finally prove the equivalency. (While also knowing what the notation means, such as that your |- will be ==>. I use ASCII because I don't trust the graphical in browsers.)
M.Eberl mentioned structured proofs. Consider this one:
lemma "~(P ∧ Q) ==> Q --> ~P"
proof-
fix P Q :: bool
assume "~(P ∧ Q)"
hence "~P ∨ ~Q" by simp
hence "~Q ∨ ~P" by metis
thus "Q --> ~P" by metis
qed
What would I deserve in points, for homework? Nothing much. It's actually a testimony that metis knows how to use basic first-order logic. Otherwise, how did it know to make the jump from ~Q ∨ ~P to Q --> ~P?
Assuming you are talking about Isabelle/HOL, you can use ‘single-step tactics’ like rule, erule, assumption with the basic natural deduction rules. The ones you will probably need for your proposition are:
introduction rules notI, conjI, disjE impI
elimination rules like notE, conjE, disjE, impE
destruction rules like mp (modus ponens), conjunct1, conjunct2
If you want to find out what a particular rule means, just write e.g. thm notI and Isabelle will display the statement of the theorem.
You can set up a goal like
lemma "¬(P ∧ Q) ⟹ Q ⟶ ¬P"
and then write e.g.
apply (rule impI)
to apply the introduction rules for implication, which leaves you with the updated goal state
goal (1 subgoal):
1. ¬ (P ∧ Q) ⟹ Q ⟹ ¬ P
Now you find the next appropriate rule and apply that one etc. until all subgoals are solved. Then you can write done and your proof is complete.
As for assumption and erule: if you end up with a goal that has some P to prove and P is already in the assumptions, you can use apply assumption to solve it. (erule is like rule with assumption chained directly after it and is often convenient for applying elimination rules)
However, this kind of proof is very tedious to do. A better way would be to do the whole proof in Isar, Isabelle's structured proof language. For an introduction to Isar, you can have a look at chapter 5 of Concrete Semantics.
Similar to a JIT compiler, this is a LJEFAATGAA answer (learn just enough from another answer to give an answer).
This is more about what I learned than about what others may learn, which may help others learn; the Isabelle learning curve is quite brutal. I'd think the time has come and gone for the OP's need for help.
Except for M.Eberl's answer to exI and refl behavior explanation needed, it would still be a mystery to me about why rule thm produces specific goal states, for a particular thm, and why rule thm produces the message Failed to apply initial proof method.
Except for the precise outline given by Chris, with the rules and braces, I wouldn't have been able to fill in the precise details. An example that if a person has the time to learn, it's better for them to be given a partial answer, to make them do a little work, than to give them the complete answer.
Two main driving points
After a few comments, I show my proof from the outline. It got me the following understanding from having to work out the details, where I talk as if I know I'm right:
The use of apply(rule thm) is being applied to a combination of the chained facts and the goal statement, where this, in the output, displays one or more chained facts.
Braces start and end a local context/scope. Variables inside and outside the context/scope work as we would expect them to work, that is, as scope normally works in programming languages. So if I state fix P Q :: bool at the beginning of a proof, then state fix Q :: bool in a sub-context, the Q in the sub-context refers to a different variable than the parent-context Q.
Having properly credited Chris, I insert his outline here, so it can easily be compared to the Isar source:
1. ~(P & Q) premise
2. { Q assumption
3. { P assumption
4. P & Q and-introduction 3, 2
5. _|_ negation-elimination 1, 4 }
6. ~P negation-introduction 3-5 }
7. Q -> ~P implication-introduction 2-6
The source:
lemma "~(P & Q) ==> Q --> ~P"
proof-
fix P Q :: bool
assume a1: "~(P & Q)"
{
assume a2: "Q"
{
assume a3: "P"
have a4: "P & Q"
apply(rule conjI) apply(rule a3) by(rule a2)
(* NOTE: have to set 'notE' up right. Next 'hence False' doesn't do it. *)
(* hence False apply(rule) by(metis a1) *)
(* 'rule' applies the default of 'conjI', because there is the fact
'this: P & Q', which comes from 'hence'; 'rule notE' gives an error.*)
from a1 a4
have False (* From 'this' and 'goal': ~(P & Q) ⟹ P & Q ==> False *)
by(rule notE) (* notE: ~P ==> P ==> R *)
}
hence "~P"
apply(rule notI) by(assumption)
}
thus "Q --> ~P"
apply(rule impI) by(assumption)
qed
Understanding scope better
Thinking was being required at my statement have False. I wasn't setting things up right for notE. Just to see if I was on the right track, I would execute sledgehammer, but it wasn't able to prove False within that context.
It was because I was on auto-pilot, and was using fix Q :: bool and fix P :: bool in the two local contexts. I took them out and sledgehammer easily found proofs.
That's an example of a person knowing some logic, but not knowing how to implement the logic correctly in the languages Isabelle/HOL and Isabelle/Isar.
Next, I had to learn how to set up things correctly for apply(rule notE).
Belaboring a point
Part of my understanding about the above source comes from seeing the phrase chained facts in isar-ref.pdf. Minor exposure to the natural deduction rules, along with M.Eberl's explanation about unification, instantiation, and resolution finally helped make sense of what happens in the output panel.
Above, I have hence False commented out, and then use have False. Fortunately, in Isabelle, there are multiple ways to do things, but the goal was to apply notE. Even with that, there are different Isar keywords that can be used to set things up.
Anyway, seeing how chained facts are used with rule was a light-bulb moment. I guess here's effectively what's involved at the statement have False, as it relates to notE:
term "~P ==> P ==> R" (* notE: line 376 of HOL.thy *)
lemma "~(P & Q) ⟹ P & Q ==> False"
by(rule notE)
If I had an account, I would upvote the question to get rid of that -1.
Thanks to Chris for giving the precise outline.
Since you explicitly mentioned natural deduction. In a specific flavour of natural deduction -- where lines are numbered and the scope of assumptions is explicitly marked by boxes (denoted by curly braces below) -- one way of proving your statement is the following:
1. ~(P & Q) premise
2. { Q assumption
3. { P assumption
4. P & Q and-introduction 3, 2
5. _|_ negation-elimination 1, 4 }
6. ~P negation-introduction 3-5 }
7. Q -> ~P implication-introduction 2-6
Actually, since your goal is to prove an implication, you only have one choice at the start, namely implication introduction.
It would be a good exercise to translate the above proof as faithfully as possible into a structured Isar proof (e.g., using what is called "raw proof blocks" and incidentally also denoted by curly braces in Isabelle).

Mathematic resolution [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I just heard something very insteresting but cannot find any ressources.
The story is that when faced with an algorithmic problem that requiered multiple ifs, one student of a friend did answer with a mathematic one liner.
Now I already knew that you could do anyting with math but I want to be able to do it.
From what I know it might be possible to do a loop given the shape of those function, but conditions?
Does someone know how to resolve something like:
IF boolean
THEN expression
ELSE expression2
in math terms (without Bool algebra)?
Best regards,
Sarfraz
Assuming boolean is either 0 or 1, and expressions are mathematical:
expr = boolean * expression + (1-boolean) * expression2
Provided that boolean is 0 or 1:
result = boolean*expression+(1-boolean)*expression2
Are you referring to a multiplexer?
If the boolean is S, expression is A and expression2 is B, then the formula for result Z is

Random sort based on parameter [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I would like to create a sorting function based on user input.
Assume that you have:
Ordered integer list or vector, X, from 1 to 10.
Function F
Parameter t
Output list Y
What I would to do 'is a consistent function between
F(X, t) = Y
I mean for same t, it must provide same Y.
Any idea?
Seed your random generator with t and shuffle the list.
I guarantee there is a better answer than this, and I admit I don't quite understand #GeorgScholly's answer, but maybe the function you're looking for is a polynomial, which can be obtained via interpolation.
For example, say your vector X has two integers, x0, x1, and so your output vector Y must have two integers, y0, y1. There is a line y=ax+b that fits any two points (x0, y0) and (x1, y1).
In general, n points, (x0, y0) ... (xn-1, yn-1), can always be perfectly fit by a polynomial of degree n-1, i.e. a function, y = an-1xn-1 + an-2xn-2 + ... + a2x2 + a1x + a0.
These coefficients, an-1 ... a0, can be found by many methods of "polynomial interpolation." Effectively, the coefficients in vector form would define your function, F(x).
Finally, to incorporate a parameter t, you might simply add am "unnecessary" term, i.e. match two points with a parabola (not a line), match three points with a cubic (not a parabola), etc., in order to have an additional an to use as a fixed point, t.
I'll be very surprised if there isn't a much simpler way (if #GoergScholly's answer isn't already one).

Finite-state transducer that computes the relation

From http://www.cse.ohio-state.edu/~gurari/theory-bk/theory-bk-twoli1.html#30007-23021r2.2.4:
Let M = <Q, Σ, Δ, δ, q0, F> be the deterministic finite-state transducer whose transition diagram is given in Figure 2.E.2.
For each of the following relations find a finite-state transducer that computes the relation.
a. { (x, y) | x is in L(M), and y is in Δ* }.
b. { (x, y) | x is in L(M), y is in Δ*, and (x, y) is not in R(M) }.
Yes, this is HW, but I have been struggling with these questions and could at least use pointers. If you want to create your own c. and/or d. examples just to show me HOW to do it rather than lead me to the answers for a. and b. then obviously I'm fine with that.
Thanks in advance!
Since you don't indicate what progress you've made so far, I'm going to assume that you've made no progress at all, and will give overall guidance for how you can approach this sort of problem.
First of all, examine the transition diagram. Do you understand what all the notations mean? Note that the transducer is described as deterministic. Do you understand what that means? Convince yourself that the transducer depicted in the transition diagram is, in fact, deterministic. Trace through it; try to get a sense for what inputs are accepted by the transducer, and what outputs it gives.
Next, figure out what L(M), Δ, and R(M) are for this transducer, since the questions refer to them. Do you know what those notations mean?
Do you know what it means for a transducer to compute a certain relation? Do you understand the { (x, y) | ... } notation for describing the relation?
Can you modify the transition diagram to eliminate the ε/0 transition and merge it into adjacent transitions (which then might output multiple symbols at a single transition)? (This can help, IMHO, with creating other transducers that accept the same input language. More so with part b, in this case, than part a.)
Describe for yourself the transducers you need to create, in a way that's independent of the original transducer. Will these transducers be deterministic?
Create the transition diagrams for these transducers.

Ocaml implementation advice for an algorithm on sets

I am having problems for converting following algo in ocaml To implement this algorithm i used Set.Make(String) functor actualy in and out are 2 functions Can any one give me percise code help in ocaml for following
This is actually Algo for Live Variables[PDF] ..Help would be appreciated greatly
for all n, in[n] = out[n] = Ø
w = { set of all nodes }
repeat until w empty
n = w.pop( )
out[n] = ∪ n’ ∈ succ [n] in[n’]
in[n] = use[n] ∪ (out[n] — def [n])
if change to in[n],
for all predecessors m of n, w.push(m)
end
for all n, in[n] = out[n] = Ø
w = { set of all nodes }
repeat until w empty
n = w.pop( )
out[n] = ∪ n’ ∈ succ [n] in[n’]
in[n] = use[n] ∪ (out[n] — def [n])
if change to in[n],
for all predecessors m of n, w.push(m)
end
It's hard for me to tell what is exactly going on here. I think there is some alignment issues with your text --repeat until w empty should be repeating the next 5lines, right? And how are in and out functions, they look like arrays to me? Aside from those deficiencies I'll tackle some general rules I have followed.
I've had to translate a number of numerical methods in C and Fortran algorithms to functional languages and I have some suggestions for you.
0) Define the datatypes being used. This will really help you with the next step (spoiler: looking for functional constructs). Once you know the datatypes you can more accurately define the functional constructs you will eventually apply.
1) Look for functional constructs. fold, recursion, and maps, and when to use them. For example, the for all predecessors m is a fold (unsure if that it would fold over a tree or list, but none-the-less, a fold). While loops are a good place for recursion --but don't worry about making it a tail call, you can modify the parameters later to adhere to those requirements. Don't worry about being 100% pure. Remove enough impure constructs (references or arrays) to get a feel for the algorithm in a functional way.
2) Write any part of the algorithm that you can. Leaving functions blank, add dummy values, and just implement what you know --then you can ask SO better, more informed questions.
3) Re-write it. There is a good chance you missed some functional constructs or used an array or reference where you now realize you can use a list or set or by passing an accumulator. You may have defined a list, but later you realize you cannot randomly access it (well, it would be pretty detrimental to), or it needs to be traversed forward and back (a good place for a zipper). Either way, when you finally get it you'll know, and you should have a huge ear-to-ear grin on your face.

Resources