I have a bit of a question regarding why my code seems to hang when I run it. The code is for a project I have in a class, but we spent one class period going over Prolog so much of what I've learned is stuff I've searched around for and have taught myself. I do apologize if my code contains horrendous stylistic errors, but again, as we never formally learned how we 'should' use Prolog, this is based mostly on my own experimentation.
The goal of the segment of code I am writing is, more or less, to form a chain that connects one actor to another through a series of movies that they have been in.
I have a function I am calling that is meant to construct connections between a starting actor, all possible linked actors ending actor, and the list of movies that connects them. This is probably a horribly inefficient method of doing this, however implementing it this way solves two parts of the assignment with one segment of code.
The code that calls the function works, and for the sake of making this simpler to read, I will omit it unless asked to share it. In short, it asserts a globalStartingActor, and passes on two empty lists (ActorList = [] and MovieList = []) to a function doActorAssertions.
In turn, we have doActorAssertions. This is the revised version of it, which should be simplified and easier to read, but lacks the massive commenting that it had previously.
doActorAssertions(ActorsName,ActorList,MovieList) :-
isNotInList(ActorsName,ActorList) ->
(
findMoviesIn(ActorsName,MoviesIn),%finds all movies ActorsName is in
howLong(MoviesIn,LenMoviesIn),%Sees how many movies there are.
(
LenMoviesIn ==0;
(
append(ActorsName,ActorList,UpdatedActorList),%this causes errors!
globalStartingActor(GSAName),%asserted starting actor
assert(connectedActors(GSAName,ActorsName,MovieList)), %says that the GSAName is connected to ActorsName by a list of movies MovieList.
write(actorAsserted),
addAndTraverse(MoviesIn,UpdatedActorList,MovieList) %Goes to propegate all movies the actor is in, then actors in those movies, then recursively calls this function again.
)
)
),
true.
As I said previously, the append tag seemed to be the source of the error! This indeed appears to be the case when I simplify the code to what it is above. I simply comment that append out, and the code body works.
Why, then, is append preventing the code from working properly? I need to have append (or similar function) in that part of the code!
Is ActorsName a list? The variable' name suggests it is, as well as the usage in append/3, but then what isNotInList(ActorsName,ActorList) means? Partial or full disjunction? This could be the cause of the endless loop, maybe you should use the difference of those sets to increment the ActorList.
You should try to avoid assert/1, and instead pass around the state in variables. See this other answer for a schema doing something very similar to what you are attempting here.
This is useless, could be a typo, but then I don't understand the ->
...
),
true.
I think should read
...
); % note the semicolon!
true.
Related
The code I'm talking about can be found in this codesandbox.
I'm currently working on a clone of a memory game called Indefinite Interrogation. The way it works is you're asked questions; you have to always answer the same questions with the same answers. The first time you're asked each question, your answer doesn't matter; but every time you're asked that question again, you must answer with whatever you chose the first time.
What's supposed to happen in my code is that questionList (the list of questions be asked) gets updated via the getNextQuestion() function every 10th question, and the Game component is supposed to continue displaying questions. What actually happens is my website crashes after answering the 10th question correctly, because it "Cannot read properties of undefined (reading '10')"; the questionList logic somehow returns undefined (the error occurs on line 512).
I'm not sure why, but state variables such as currentListIndex (the current index in questionList) don't seem to be getting updated by getNextQuestion(). Even after that function gets called, the old value of currentListIndex seems to still be getting used, and that breaks the game every 10 questions (each questionList is 10 elements long so the max index is 9; currentListIndex seems to become 10 at some point for unknown reasons).
questionsIndices (basically an array of indices to determine which lists of questions can be used to generate questionList) also seems to fail to get updated by that same function.
My only guess is that I'm using useEffect() incorrectly. Thank you for taking the time to read this, and I appreciate any assistance I can receive to resolve this issue.
EDIT: use the console output to see the correctAnswer to each question. Game overs will cause the game to reset itself back to score 0 (this may take a few seconds).
I've been drawing a sequence diagram of a module recently, while reverse engineering.
I encountered a control statement, and it is like,
if (func_A() == True)
{
DoSomeThing();
}
else
{
DoSomeThingElse();
}
The problem is how to draw the condition?
As I mentioned, It is reverse engineering. The code cannot be modified now.
I drew two diagrams, and I don't know which way is right,
The first one is this, I think it's wrong because it doesn't show the function call as a message from A to B.
This is the second, It shows a message func_A.
What do you think about to do this right?
To complete the other answer there is anyway a problem in the second proposal because we do not know if in [func_A() == True] you reuse the value return by the previous call or you do a second call, to avoid that add the explicit return in your diagram :
Out of that do you know the activities ? A sequence diagram is "just" an interaction while an activity is a behavior and can be more adapted :
It depends. If func_A is an operation defined in Object2 the second representation would be correct. The first does not tell where the operation is defined. Most likely (!) one would interpret func_A as an operation local to ObjectA which your code seems to say. (Btw. you have two completely different object sets AB vs. 12 in your examples.) But that is uncertain. So the 2nd variant is more explicit (and correct).
In any case I advise to not overdo SDs with fragments as "graphical programming" doesn't make things easier to read (my practical experience). It's excellent to show message flows in various collaborations. But when it comes to conditions it's getting messy very soon. A better way is to create different sub-diagrams or even use pseudo code if there are too nested if conditions. In many cases such if clauses are a good fit for state machines.
I work in safety critical application development. Recently as a code reviewer I complained against coding style shown below, but couldn't make a strong case against it. So what would be a good argument against such Variable redundancy/duplication, I am looking for cases where this might lead to problems or test cases which might fail, rather than just coding style.
//global data
// global data
int Block1Var;
int Block2Var;
...
//Block1
{
...
Block1Var = someCondition; // someCondition is an logical expression
...
}
//Block2
{
...
Block2Var = Block1Var; // Block2Var is an unconditional copy of Block1Var
...
}
I think a little more context would be helpful perhaps.
You could argue that the value of Block1Var is not guaranteed to stay the
same across concurrent access/modification. This is only valid if Block1Var
ever changes (ie is not only read). I don't know if you are concerned with
multi-threaded applications or not.
Readability is an important issue as well. Future code maintainers
don't want to have to trace around a bunch of trivial assignments.
Depends on what's done with those variables later, but one argument is that it's not future-proof. If, in the future, you change the code such that it changes the value of Block1Var, but Block2Var is used instead (without the additional change) later on, then this will result in erroneous behavior.
If the shown function context reaches a certain length (I'm assuming a lot of detail has been discarded to create the minimal reproducible example for this question), a good next step could be to create a new (sub-)function out of Block 2. This subfunction then should be started assigning Block1Var (-> actual parameter) to Block2Var (-> formal parameter). If there were no other coupling to the rest of the function, one could cut the rest of Block 2 and drop it as a function definition, and would only have to replace the assignment by the subfunction call.
My answer is fairly speculative, but I have seen many cases where this strategy helped me to mark useful points to split a complex function later during the development. Of course, this interpretation only applies to an intermediate stage of development and not to code that is stated to be "ready for release".
I've seen this asked for other languages, but having just found out how nicely Fortran can handle arrays, I thought there might be an easy way to do this without loops.
Currently I'm searching over a 3D array looking at 'nearest neighbours' to see if they contain the letter 'n', and whenever it finds this value, I want it to perform some clusterLabel assignment (which isn't relevant for this question)
I wanted to use if(lastNeighArray.eq."n") then...<rest of code>
but for obvious reasons it doesn't like checking an array against a value. Neither does it like me using lastNeighArray(:), even though I'd like it to check each of the elements one at a time. where(lastNeighArray.eq."n") doesn't work as I have a case statement inside the where loop and I get the error WHERE statements and constructs must not be nested.
So I'm a little stuck. What I really want is something like when(lastNeighArray.eq."n") but that doesn't exist.
I've also looked at any and forall but they don't seem like the right choice.
ANY should actually be the right choice
if ( ANY( lastNeighArray=="n" ) ) then
there is also ALL if you wanted the whole array to contain that value.
I have this code
n_userobject inv_userobject[]
For i = 1 to dw_1.Rowcount()
inv_userobject[i] = create n_userobject
.
.
.
NEXT
dw_1.rowcount() returns only 210 rows. Its so odd that in the range of 170 up, the application stop and crashes on inv_userobject[i] = create n_userobject.
My question, is there any limit on array or userobject declaration using arrays?
I already try destroying it after the loop so as to check if that will be a possible solution, but it is still crashing.
Or how can i be able to somehow refresh the userobject?
Or is there anyone out there encounter this?
Thanks for all your help.
First, your memory problem. You're definitely not running into an array limit. If I was to take a guess, one of the instance variables in n_userobject isn't being cleaned up properly (i.e. pointing to a class that isn't being destroyed when the parent class is destroyed) or pointing to a class that similarly doesn't clean itself up. If you've got PB Enterprise, I'd do a profiling trace with a smaller loop and see what is being garbage collected (there's a utility called CDMatch that really helps this process).
Secondly, let's face it, you're just doing this to avoid writing a reset method. Even if you get this functional, it will never be as efficient as writing your own reset method and reusing the same instance over again. Yes, it's another method you'll have to maintain whenever the instance variable list changes or the defaults change, but you'll easily gain that back in performance.
Good luck,
Terry.
I'm assuming the crash you're facing is at the PBVM level, and not a regular PB exception (which you can catch in your code). If I'm wrong, please add the exception details.
A loop of 170-210 iterations really isn't a large one. However, crashes within loops are usually the result of resource exhaustion. What we usually do in long loops is call GarbageCollect() occasionally. How often should it be called depends on what your code does - using it frequently could allow the use of less memory, but it will slow down the run. Read this for more.
If this doesn't help, make sure the error does not come from some non-PB code (imported DLL or so). You can check the stack trace during the crash to see the exception's origin.
Lastly, if you're supported by Sybase (or a local representative), you can send them a crash dump. They can analyze it, and see if it's a bug in PB, and if so, let you know when it was (or will be) fixed.
What I would normally do with a DataWindow is to create an object that processes the data in a row and call it for each row.
the only suggestion i have for this is to remove the rowcount from the for (For i = 1 to dw_1.Rowcount()) this will cause the code to recount the rows every time it uses one. get the count into a variable and then use the variable. it should run a bit better and be far more easy to debug.