State machines, is this topic taught any more? - Page 1
Forum section: electronics / general

author: Howardlong
author_rank: Super Contributor
timestamp: October 31, 2018, 07:44:50 pm
content: I had an unexpected experience today, I was handing over a project to half a dozen reasonably experienced developers which uses a state machine to orchestrate and synchronise its tasks. Only one of them knew what a state machine was, so I ended up spending half the meeting explaining the concept, not the easiest of tasks if you’re not prepared.Admittedly this isn’t an embedded system, it’s a big server-side database manipulation task, but I’d still expect any software developer to have at least heard of state machines, or are state machines outside of embedded systems a bit too old school nowadays?

author: KaneTW
author_rank: Frequent Contributor
timestamp: October 31, 2018, 07:57:34 pm
content: FSMs are taught in any (decent) introductory CS course, but not everyone has a formal CS education.

author: JPortici
author_rank: Super Contributor
timestamp: October 31, 2018, 08:08:16 pm
content: I learned about state machines in high school, grafcet, to be more specific (Technical school) but the concept remained with me. I don't remember them ever being mentioned in the courses i attended in uni (EE) were they on programming or digital electronics (say 5 years ago)

author: NorthGuy
author_rank: Super Contributor
timestamp: October 31, 2018, 08:15:46 pm
content: Quote from: Howardlong on October 31, 2018, 07:44:50 pmMay be state machines aren't used much as most of the programming is done for pre-emptive OSes. Did they know about threads, mutexes etc.?

author: tggzzz
author_rank: Super Contributor
timestamp: October 31, 2018, 08:35:49 pm
content: "State machines? Aren't they used in compilers? Something to do with reading the input".Yes, I've heard that from a young softie. And that was after he had been modifying a telecom product whose "arcihitecture" consisted of a number of "nodes" and ways of "jumping from one node to another". Some people shouldn't be let near a keyboard.

author: rstofer
author_rank: Super Contributor
timestamp: October 31, 2018, 08:42:47 pm
content: You would have thought that every grammar school kid knew about the state machine game "Simon Says".

author: Howardlong
author_rank: Super Contributor
timestamp: October 31, 2018, 08:55:40 pm
content: Quote from: NorthGuy on October 31, 2018, 08:15:46 pmFor this project, given the technology there was no need to use those terms, but the underlying concept is the same. In the target environment, which is on big multi socket multi core iron, the whole point of the state machine was to synchronise and orchestrate concurrent isolated processes by using a couple of dozen instances of the same state machine. The state machine itself only has six states, and is not hierarchical thank God!Edit: I think you may be onto something regarding the programming methodologies in use today, where in high level applications and systems we have moved away from explicit event driven models with super loops to method driven OO technologies.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: October 31, 2018, 09:14:49 pm
content: Quote from: Howardlong on October 31, 2018, 07:44:50 pmAnd it is on this basis I hope to keep employed for a few more years.

author: coppice
author_rank: Super Contributor
timestamp: October 31, 2018, 09:26:38 pm
content: Quote from: Howardlong on October 31, 2018, 08:55:40 pmMany things have very persistent state. Frequently persisting far longer than any piece of software ever runs without a break. Whatever you call them, and however you look at them, FSMs won't go away. Remember that they even have their own religion.

author: djacobow
author_rank: Super Contributor
timestamp: October 31, 2018, 09:42:42 pm
content: Quote from: NivagSwerdna on October 31, 2018, 09:14:49 pmI'll drink to that.

author: djacobow
author_rank: Super Contributor
timestamp: October 31, 2018, 09:50:15 pm
content: Quote from: coppice on October 31, 2018, 09:26:38 pmI'll try to keep this rant short, because I agree with you.FSMs, of course, are everywhere, whether you understand that or not. It's much better, though, if your job is to create stateful machines that do useful things, is to have a conceptual model of what a stateful machine is. The formalism of how FSMs are (were?) taught in EE and CS programs is incredibly useful for reasoning about complex processes. It makes designing such machines something mechanical and straightforward, rather than a process of hacking until it seems to work.You see this deficiency in a lot in software, where someone has written a function or group of functions that interact with shared state variables at various times under varying circumstances, and the result is software that usually kinda works, but sometimes does X or Y one call before or after it should, etc, because the programmer never just drew a state diagram and coded to that, but instead just sort of poked at the problem until it kinda mostly worked.

author: kfnight
author_rank: Regular Contributor
timestamp: October 31, 2018, 10:01:54 pm
content: Call them DFAs. They'll know what you're talking about.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: October 31, 2018, 11:34:50 pm
content: Quote from: djacobow on October 31, 2018, 09:50:15 pmI enjoy watching speedruns of games, where this principle applies in game development. A huge fraction of tricks/exploits/glitches consist of entering some state, then doing a frame-perfect state change that clearly was not expected by the developers.I feel that a lot of those, back in the day, were due to time crunch and hardware complexity: systems like the N64 were pushed to market, with as much dev support as they could manage to put together in that time. Which, compared to today's biggest, most popular frameworks, was probably just embarrassing. (Maybe it's not; it's easy to overstate the appeal of a framework I've never personally tried. I should really assume it's just as hacked together as every other framework in existence!) The standard graphics backend for the N64, for example, was at least pretty solid (basically a drop-in of the SGI tech they licensed), but tended to be slow. If you wanted to stray from the standard path (say to squeeze as much geometry and framerate as possible), you had a tremendous amount of work to do. Most famously, Rare's games: compare the gameplay and graphics of DK64 to Perfect Dark!Mistakes continue to be made today, of course. i would argue that it's more a matter of scale now, just because projects are so massive that there's no way they can design, structure or test every combination of every component.Well, that needs a lot of qualifying, too. Tools like Unity are available to literally everyone, from the single-dev indie to massive hundreds-of-devs "AAA" studios. The smaller studios will still have the same early problems: learning the tools, programming challenges in general, and just managing to put out a complete product as such. It's the larger studios to which I'm referring, of course.Just in the last two months, Nintendo'sBreath of the Wildhas been broken open with wall clipping and superspeed techniques, some of which are fairly easy, and some of which have small frame and position windows to execute.Bethesda's games are notorious for glitches. At this point, I've got to think it's at least somewhat intentional, as an endearing feature of their games/engines. Like how the physics engine in later GTAs improved considerably, but left in the glitchy playground equipment that launches actors/vehicles.Meh. I could go on, and on and on. Suffice it to say, if there's a reason something can fail, it will. Structural, design, management, technical, "blame the tools", you name it, some combination will be relevant.Tim

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 01, 2018, 02:05:02 am
content: You can try and have them ramble on aspect-oriented programming instead.

author: richnormand
author_rank: Unknown
timestamp: November 01, 2018, 02:48:52 am
content: A few years ago I took an EDX course from UT 6.02x Embedded Systems.One of the labs was indeed to design a finite state machine for a traffic lights and pedestrian lights at a major intersection. Major pain!While a good tutorial, the argument was that using no "if" or other type statements and being able to prove (to a judge and such) that there was no way it could have misbehaved.So, yes, it is still being thought as a basic concept, albeit not that efficient as a programming method.

author: tggzzz
author_rank: Super Contributor
timestamp: November 01, 2018, 09:00:04 am
content: Quote from: richnormand on November 01, 2018, 02:48:52 amIf you aren't worried about correctness, then "it" can be arbitrarily "efficient" for any value of "it" and "efficient".

author: hans
author_rank: Super Contributor
timestamp: November 01, 2018, 09:40:35 am
content: I think state machines are common in academia, hence people with education probably know about them. However "state machine" is a common design pattern, so you would think computer science people (even self taught) will know about it.Hardware designers will come across FSM at some point, Moore and Mealy machines.. basics of any VHDL course.Theoretical computer scientists use automata to describe state machines. There are many modelling languages and paradigms to describe automata, and prove certain properties of a system. You could use temporal logic, like LTL or CTL, to reason about the temporal behavior of systems. Or PCTL to reason with probabilities in mind as well.For example, the probability of a system failing and not recovering within a certain timespan.Unfortunately, these tools are mostly academic because modelling any real large system requires at least a PhD in the field plus access to sufficiently powerful simulators and machines to do any meaningful experiments.

author: Mechatrommer
author_rank: Super Contributor
timestamp: November 01, 2018, 09:43:10 am
content: Quote from: Howardlong on October 31, 2018, 07:44:50 pmwell there are experienced developers that dont know how to use #define properly nor know what reusable codes are. their qualification maybe was only hands on experience, no proper education line.

author: Howardlong
author_rank: Super Contributor
timestamp: November 01, 2018, 11:21:19 am
content: Quote from: Mechatrommer on November 01, 2018, 09:43:10 amAs an aside, there's reusable code, and then there's reusable code.Reusable code is in general to be applauded, but as with most things it can be taken to the extreme, such as there being only one externally called function, method or interface which does everything, including fitting a square peg into a round hole. This is where a blind religious dogma can take over from pragmatism.

author: Howardlong
author_rank: Super Contributor
timestamp: November 01, 2018, 11:26:43 am
content: Quote from: richnormand on November 01, 2018, 02:48:52 amIf, for example, one uses function pointers to maintain state, efficiency is rarely a problem.More likely, though, is that without a state machine you risk ending up with a complex decision tree with plenty of duplicated code that's difficult to maintain.I'm pretty sure that many programmers use state machines without knowing it, for example in event driven programming, the state machine is performed by the framework.

author: tggzzz
author_rank: Super Contributor
timestamp: November 01, 2018, 11:36:09 am
content: Quote from: Howardlong on November 01, 2018, 11:26:43 amI've seen if-then-elses nested 10 deep.Since it was so difficult to maintain (after all code is difficult to maintain), it was under version control - but the versioning looked like spaghetti in a saucepan. To make it easier, there were many site-specific config variables. Since config isn't code, they weren't under version control. And the pièce de résistance was that many of the config variables directly mapped to the if-the-else clause!QuoteI wish many of those frameworks directly acknowledged that they were intended to be used for event-driven FSM applications. Instead the FSM nature of the application code can indeed be thoroughly hidden by the framework, and hence the application code grows in an unmaintainable ad-hoc fashion. Doubly so with inappropriate use of agile or XP practices.

author: BBBbbb
author_rank: Unknown
timestamp: November 01, 2018, 02:54:19 pm
content: If you worked with lower level embedded (meaning NOT RPi embedded linux and similar stuff) and had to handle precise timings and edge cases, I rally can't believe you are unfamiliar with SMs or doubt their efficiency.Java and such stuff, I understand people not being familiar with SMs

author: tggzzz
author_rank: Super Contributor
timestamp: November 01, 2018, 03:12:15 pm
content: Quote from: BBBbbb on November 01, 2018, 02:54:19 pmThey are just as valuable at a high level. Consider telecom control software, or flight control.I conjecture they ought be used for some event-driven smartphone apps as well.

author: BBBbbb
author_rank: Unknown
timestamp: November 01, 2018, 03:20:22 pm
content: Quote from: tggzzz on November 01, 2018, 03:12:15 pmYup, basically whenever you have important timings and coverage of edge cases (critical systems) SMs seem like a must.I was more thinking about the common programmer doing IoT stuff on embedded linux using higher lvl language, and still considered as embedded sw engineer.

author: rrinker
author_rank: Super Contributor
timestamp: November 02, 2018, 04:25:23 pm
content: Common saying around here is "if everyone knew what they were doing, we would all be flipping burgers".Formal education on state machines? I had ONE course (EE) where it was touched on, in terms of digital logic. I would assume a more CS oriented track would cover this in far more detail, but I was more interested in hardware design so I went EE.

author: tggzzz
author_rank: Super Contributor
timestamp: November 02, 2018, 05:39:16 pm
content: Quote from: rrinker on November 02, 2018, 04:25:23 pmFSMs are absolutely fundamental to the design and implementation of digital logic.

author: Vtile
author_rank: Super Contributor
timestamp: November 02, 2018, 06:22:07 pm
content: Quote from: hans on November 01, 2018, 09:40:35 am...And self thinking pea-counters to give enough timely resources.

author: Vtile
author_rank: Super Contributor
timestamp: November 02, 2018, 06:26:51 pm
content: Quote from: tggzzz on November 01, 2018, 03:12:15 pmNotice your words control. What you are describing is RT system with HMI.I also do not understand how some claims that IF =/= FSM, every FSM lockdown network is in the end multiple IF-THEN statement, similarly not every SR-latch became a practical SM.

author: BBBbbb
author_rank: Unknown
timestamp: November 02, 2018, 07:59:21 pm
content: Quote from: Vtile on November 02, 2018, 06:26:51 pmRegarding if-then comment - yes they end up being nested if-then, but that is not what you’re maintaining and modifying, and that is a huge difference.

author: tggzzz
author_rank: Super Contributor
timestamp: November 02, 2018, 08:04:01 pm
content: Quote from: Vtile on November 02, 2018, 06:26:51 pmThere is no human interaction (in any reasonable sense) in many telecom applications For example, consider billing applications which get inputs from computers designed by different companies, operated by different companies, in different continents - and which output results to a database. Humans, if they exist at all in that context, are very remote in all senses.QuoteOh, if-then-else statements are often parts of state machines. The problem is that too often the people writing those statements don't realise it - and hence don't structure theirthinkingappropriately. The result can be a complete nightmare.Thinking in terms of FSMsavoids many problems, no matter what implementation techniques are used.

author: hans
author_rank: Super Contributor
timestamp: November 03, 2018, 07:46:48 am
content: Quote from: Vtile on November 02, 2018, 06:26:51 pmI think protocols can also be commonly implemented as statemachines. Look at TCP and the common states a socket can have.Also at high level applications. As said, the state pattern is pretty common.At web level, the Saga pattern also ties into it closely, which describes the states a combination of transactions must go through to be successful. The rollback of those transactions is also described depending on what transaction along the way fails:QuoteSo I retract my previous statement. State machines are common as muck.

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2018, 11:06:31 am
content: Quote from: hans on November 03, 2018, 07:46:48 amMore fundamentally, comms protocols are usually defined/specified in terms of state machines. It would be peverse not to implement them using FSMs that have a direct correspondance with the specification.

author: legacy
author_rank: Super Contributor
timestamp: November 03, 2018, 11:41:53 am
content: what do you use, guys, to represent the FSM (its flowchart) on a document?DIA?Graphviz?umm?

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2018, 12:33:00 pm
content: Quote from: legacy on November 03, 2018, 11:41:53 amAnything convenient; it is frequently dictated by the project's environment.Harel StateCharts and UML FSMs are reasonable serarch terms.Note thatit doesn't have to be graphicalflowcharts != FSM diagrams. Flowcharts merely illustrate a subset of the possible event/state trajectories

author: legacy
author_rank: Super Contributor
timestamp: November 03, 2018, 01:14:29 pm
content: that's the question: what is convenient?Quote from: tggzzz on November 03, 2018, 12:33:00 pmno doubt about, just for some details it's more illustrative and easy to understand.Quote from: tggzzz on November 03, 2018, 12:33:00 pmflowcharts are enough to illustrate an FSM in Mealy or Moore formWe use both, Mealy, and Moore, depending on our convenienceAnyway, I need a software to illustrate the FSM of my team's hw debugger engine made for a hobby. This weird gear has a protocol as well as several FSMs in the (v)HDL code as well as server FSM in the C code on the host-software, and I am oriented to Dia since it has a lot of primitives already done which might be used to represent a FSM. Unfortunately, it's not scriptable, therefore I can't automatize the process.I mean, what I have is a lot of vHDL modules and C code, and it would be "cool" extracting the documentation rather than have to manually create it, and the design itself offers a decent modularity, therefore extracting this info should be easy ... to be then converted into Graphwiz scripts? I am really tempted since even LaTex is able to understand themI know, I know, ideally, you should start from the documentation which describes the protocol and things, with flowcharts of the FSM etc, and then implement it on HDL/C/wherever.However, here we are working in reverse because unfortunately (and thanks to my group of hobbyists who help me, and to whom I would always say THANK for the help) this hobby project has never been disciplined like it should have been(1)edit:(1) well, we have a pirate flag on the door of our garage laboratory, guys have said it should mean something

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2018, 02:53:13 pm
content: Quote from: legacy on November 03, 2018, 01:14:29 pmAgreed.QuoteActually you are right; for some unknown reason I was thinking of sequence diagrams. (Memo to self: more coffee needed)Having said that flowcharts (in the conventional sense!) are merely pretty-printed if-then-else statements. That works for FSMs exactly as well as if-then-else statements: OK for trivial FSMs, great when starting, and bloody awful when (not if) more constraints requirements and edge-cases are added.As I mentioned, I've seen 10-deep if-then-else FSMs; it took 6 months(!) to get a change out the door. Seriously!QuoteYes. The difference has tended to be over-emphasised.QuoteI've never seen a decent reverse-engineering tool. If there was one it would beextremelylucrative.QuoteYes and typical, respectively!

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 03, 2018, 04:18:26 pm
content: What are the odds? I postedthison stackoverflow.com a day before OP started this thread. The relevant bit:It looks like I forgot to add the arrow from "Output D O G" back to the initial "Get next char", though.The underlying problem the OP had, was how to change any 'cat' in input to 'dog': a perfect application of a finite state machine.This one works for inputs like 'cacat' and 'fooca', which many implementations (that read the input one character at a time) fail with.My answer was intended as an introduction to finite state machines, and from there to modeling problems logically, and from there to properly documenting the code: the solution the code attempts to implement (at the function level), and the programmer intent at the block/line level. So yeah, I too definitely believe FSMs should be in every software developers toolbox.

author: Howardlong
author_rank: Super Contributor
timestamp: November 03, 2018, 05:37:39 pm
content: Quote from: legacy on November 03, 2018, 11:41:53 amI’ve always used Visio. I don’t use it on a daily basis so it’s often a fight to use: Visio has never been particularly intuitive to use. Add to that, every new release the Idiots In Charge change the templates and UI in one way or another for no apparent reason. But it does make nice looking diagrams.

author: ralphrmartin
author_rank: Frequent Contributor
timestamp: November 03, 2018, 06:30:56 pm
content: I used to teach FSMs as one of many programming paradigms (both to undergraduates and master's students) until very recently. Like many paradigms, there are some problems it is particularly well suited to, and others for which it is a poor model.However, I suspect their popularity went down in mainstream CS when structured programming came in, and the GOTO was ruled to be unacceptable. While it's not the only approach, unfortunately, the simplest way of implementing FSMs is based around GOTOs, and I suspect the FSM baby got thrown out with the GOTO bathwater to some degree.

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2018, 06:53:00 pm
content: Quote from: ralphrmartin on November 03, 2018, 06:30:56 pmYes indeed. The point is to have several tools in your toolbox, and to pull out the most appropriate tool for the problem.QuoteThere I disagree. Gotos disappeared and structured programming appeared long before FSMs were relegated to parsers/compilers.There are many structured programming design patterns that are very well-suited for FSMs, with 2D arrays of function pointers being an excellent example. One dimension's index is the state, the other dimension's is the event.Moving on to OOP, there are several well-knownexcellentdesign patterns where each state is a separate class and events are calls to methods in the class. That is also well suited to hierarchical FSMs.If you want to define a moment when FSMs became de-emphasised, I'd look at the rise of web technologies.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 03, 2018, 07:48:29 pm
content: Agreed (to both tggzzz and ralphrmartin above).One particular use case where a (hierarchical or array-based) FSM is very well suited, is menu-based user interfaces in small microcontrollers. Even if you happen to have many variables the user can edit, a nice, clear, easily maintained interface requires surprisingly small amount of flash/ROM. If I recall correctly, the descriptive texts (shown in a minimal UI) tend to be the biggest memory hogs.My suspicion is that software engineering and information technology, as study subjects, have diverged for quite a time now, with practical software development being somewhere in between in the gap. One side forgoes many practical algorithms and approaches to keep up with buzzwords, new programming languages, and new development methodologies, and the other side gets too deep into the mathematical aspects to have any opinion on anything practical.A similar gap exists with standard, standard library, and compiler developers on one side, and everyone else on the other side. For example, C11 introduced a buttload of (optional) "safe" variants only used by one vendor, while leaving a large number of practically useful functions nonstandardized,getline()in particular. Compiler and standard library writers read the standards to the letter, and if the standard allows one of them to behave in a completely impractical manner, they'll do it; even if a practically useful behaviour would be just as easy to implement. (This is a recurring theme in discussions between the Linux kernel and GCC developers, by the way.)Perhaps we are seeing the statistical effects of the limitations of typical human brains? When stuff is added to one part, other parts shrink or get neglected?

author: coppercone2
author_rank: Super Contributor
timestamp: November 03, 2018, 07:56:52 pm
content: in EE I was taught FSM in a digital design class

author: coppice
author_rank: Super Contributor
timestamp: November 03, 2018, 09:31:02 pm
content: Quote from: tggzzz on November 03, 2018, 06:53:00 pmI'd agree with that. It was the late 70s when people like Michael Jackson (the Jackson Structured Programming one) and Edward Yourdon were a big thing. In the 1980s FSMs were still a thing every good software developer was still trying to find good programming patterns for.

author: Howardlong
author_rank: Super Contributor
timestamp: November 04, 2018, 10:35:00 am
content: Interesting conversation and hypotheses.I’ll add some further detail around the specific environment.This was originally a semi independent distributed application written by a dozen or so developers located across the globe, and it’s funded by business subscriptions to the service, which operates 24/7.As it became an integral part of their businesses, three large players got together and bought it, because it was foreseen as a risk for them were it to fail.Much more recently, one of those businesses took complete control, buying all rights, allowing them to control the development more methodically.The modus operandi is very much customer driven, in that there is continuous development, integration and deployment, with pushes as an when they’re needed, on average one or two per week. However, there has been little strategy around the application, and almost no methodology around the approach other than a reasonably strong change control system that’s recently been effected since it became owned by a single large player.And thereby lies the problem, for many years there were a few developers, many I believe self-taught, and what I’d call startup types, with a JFDI attitude, which works for instant short term gratification for their customers when delivering a cacophony of small changes, but not so much for a longer term product roadmap and maintainability.For a period of time you can hide what’s going on under the hood, but it’s going to come and bite you as the sheer weight of top heavy plasterwork comes crashing down.Some of the original startup style developers have left, leaving those remaining carrying a huge amount of knowledge, but it’s all in their heads. There is almost no historical technical documentation, including biz specs, architectural design, functional design or technical design. Everything is through reverse engineering. Now I’m no proponent of overburdening box ticker documentation, but there really is next to bugger all.And yes, there are GOTOs in the code, everywhere. As are hard coded values everywhere with no comments, which I consider even worse than GOTOs. There’s also almost no staged environment testing, stuff often goes from development straight into production.

author: tggzzz
author_rank: Super Contributor
timestamp: November 04, 2018, 11:10:07 am
content: Quote from: Howardlong on November 04, 2018, 10:35:00 amThat pretty much describes the background to the "10-deep if-the-elses" I mentioned earlier. Hence I am not in the slightest bit surprised.IMNSHO the only realistic option is to extract the core features that are now known to be needed (not by reverse engineering!), and start afresh.The only other aspect of the case I mentioned is that it was implemented in a "Domain Specific Language". That DSL was intended to be used for small things that didn't belong in the core code, but over time the small things became the product. Eventually the product sank under its own weight.And therein lies the problems with DSLs:the languages often start out small, but as new requirements are uncovered, new language features are addedover time the various features don't play well with each other, and eventually even the designers don't understand their creationdocumentation for the language and applications is very limited, since "they aren't needed for small things"tools for understanding and manipulating the DSL are non-existentdevelopers don't want to work in the DSL, since it isn't a transportable skillThose problems are largely avoided with Domain SpecificLibrariesin a standard language.Note that the first two problems can also afflict mainstream languages. C++ is the obvious example, e.g. where the designers didn't realise that their template language was Turing-complete, until it was rubbed in their faces by an embarassing demonstration program.

author: Howardlong
author_rank: Super Contributor
timestamp: November 04, 2018, 11:57:16 am
content: My change went in yesterday. It has cut down a process that took 18 hours to six minutes, but that’s not the whole story.The first three states take two seconds, this is the only time when there is contention with with other processes, unlike the entire 18 hours before, so innevitably all the other previously contending processes miraculously sped up significantly too.The solution wasn’t just to use a state machine though. It was to use the database equivalent of passing by reference rather than passing by value. Passing by reference, it’ll never catch on ;-)

author: tggzzz
author_rank: Super Contributor
timestamp: November 04, 2018, 12:14:13 pm
content: Quote from: Howardlong on November 04, 2018, 11:57:16 amThat company also needed to send a value from one unix process to another. They were on different servers, but both under control of the company.The implemented solution was for server 1 to write a row to a database, and server 2 to poll the database to see if there was a new row. The result/confirmation was returned the same way. Wow, just wow.It wasn't as if remote procedure calls were unknown: the product used TCP links for all the soft realtime telecoms events!

author: aheid
author_rank: Regular Contributor
timestamp: November 04, 2018, 01:50:36 pm
content: At uni my line was simulation and visualization, so I didn't get the full regular comp sci treatment, and the only time I explicitly encountered state machines at uni was during my course on compilers. Even then, it was more a tool for the job at hand (parsing) than something taught explicitly.That said, state machines are,in principle, quite simple and I can't imagine an otherwise experienced developer having much issue picking up the concept. Most will have used a state machine without thinking about it as such.Though, getting handed an existing complex state machine can be a daunting task to get to grips with for anyone.

author: tggzzz
author_rank: Super Contributor
timestamp: November 04, 2018, 02:23:46 pm
content: Quote from: aheid on November 04, 2018, 01:50:36 pmAgreed.A significant all-too-frequent problem is when people implement state machineswithout realising that's what they are doing. Those FSMs tend to be ad-hoc and only sufficient for problems that were encountered in the past.FSMs aren't difficult, and designing an FSM is no more/less difficult than designing other software. But, as with other software and hardware, if they "grow organically" rather than being designed, there will be more or less subtle problems sooner or later.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 04, 2018, 04:30:03 pm
content: Quote from: aheid on November 04, 2018, 01:50:36 pmDocumenting them exactly (and that means keeping the documentation in sync with implementation changes) is what makes that kind of hand-off possible. But that applies to all complex systems, not just state machines.Graphviz (dot language) is one option for state machine documentation. That way programmers don't need to fire up an editor to try and draw the changes (they won't, anyway); just make simple logical changes to a text file. Sits better in most devs' workflow.

author: ehughes
author_rank: Frequent Contributor
timestamp: November 04, 2018, 04:31:39 pm
content: To answer the original question. Yes. I teach them in 2 different classes (a digital design w/ FPGA and a microcontrollers course) as well as to junior engineers in my company.What I see as the biggest oversight in implementations is the lack of guards when transitioning between states. Regardless of how the state machine is implemented in code (function pointer table, switch/case), I never allow a state variable to be directly modified. There is always a singular function that (i.e. TransitionToState(.....)) that accepts the new state, checks to see if it valid, implements any logic during the transition, etc.Seeing things likeCode:State +=3 ;// Move to the state that checks the dilthium interposer before enable IPS conduits)scare me!I personally likeCode:WarpDriveStateTransition(CHECK_DILITHIUM_INTEPOSER);

author: tggzzz
author_rank: Super Contributor
timestamp: November 04, 2018, 04:50:06 pm
content: Quote from: ehughes on November 04, 2018, 04:31:39 pmThe othermajoradvantage of TransitionToState() functions is that they can log the new state. If the received events are also logged, then you have the basis for a very powerful and high-level debugging strategy.That's invaluable:during design to see what's happening and for unit testsduring integration, where you can see what events the other bugger's code is sending to youduring comissioning, where you can see what events the other company's product is sending to youduring lawsuits, since you can prove the other company/bugger is at faultSeriously.

author: ralphrmartin
author_rank: Frequent Contributor
timestamp: November 04, 2018, 06:03:05 pm
content: Quote from: tggzzz on November 03, 2018, 06:53:00 pmThat's certainly one way of doing it, and a neat way of doing it, if your supports functions as first class values.But it's still nowhere as easy for undergarduates to grasp asGOTO stateN...

author: tggzzz
author_rank: Super Contributor
timestamp: November 04, 2018, 06:16:21 pm
content: Quote from: ralphrmartin on November 04, 2018, 06:03:05 pmThere are other neat, and in some ways better, design patterns which don't require functions as (exposed) first class values.The point is to think at a high level, and to find a way to express those thoughts in a structured form in whatever language you are using.With FSMs, a key test is when (not if) there is a bug or enhancement, is it easy:to understand where the change must be made?to know that the change will not affect other unrelated use-casesUsing gotos and nested if-the-else statements bothcompletelyfail that test.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 04, 2018, 08:43:38 pm
content: Quote from: Nominal Animal on November 03, 2018, 04:18:26 pmI wouldn't qualify this as a state machine. The state machine is basically a function which calculates new state based on the old state and the input:state = state_machine (state, input)Even though your task formally qualifies as a Mealy state machine, it isn't programmed like one. I'll take a liberty to pull the relevant code from the stackoverflow (comments mine):Code:void cat_to_dog(FILE *in, FILE *out){int ch;ch = fgetc(in); // blocking callwhile (ch != EOF) {if (ch != 'c') {fputc(ch, out);ch = fgetc(in);continue;}ch = fgetc(in); // blocking callif (ch == EOF) {fputc('c', out);break;} elseif (ch != 'a') {fputc('c', out);continue;}ch = fgetc(in); // blocking callif (ch == EOF) {fputc('c', out);fputc('a', out);break;} elseif (ch != 't') {fputc('c', out);fputc('a', out);continue;}fputc('d', out);fputc('o', out);fputc('g', out);ch = fgetc(in); // blocking call}}Here you do not have any variables representing the state. Even the state does exist, it is maintained implicitly. You have a number of blocking calls. During such calls, if there's no data, the OS will abandon your thread until the new data is ready. During this "out" time, the state of your machine is implicitly remembered by OS as an address where to return - the address of one of your numerous blocking calls. This may be convenient, but your program now requires a multi-threading OS. Your program is also unable to do other simple things, such as saving the state of the state machine for future use.Traditional implementation of a state machine would contain an explicit variable defining the state, along the functions dealing with the state. For example:Code:void dogger_init(dogger_state *s);void dogger_update(dogger_state *s, char c);void dogger_fin(dogger_state *s);Here, the "init" function initializes the state variable, the "update" function is the state machine itself which takes the state and the input and moves the state machine to the next state, and the "fin" function does the final housekeeping.When it is organized in such way, you do not need to block the thread waiting for the next char. The state machine does the calculation and returns back. You now can have literally thousands of independent active state machines at the same time. You can also save the state of any machine and then restart it from the given state.Of course, if you wish you can linearize the execution, such as:Code:void main(){char c;char *p = "dog eat cat\n";dogger_state s;dogger_init(&s);while (c = *p++) {dogger_update(&s,c);}dogger_fin(&s);}The biggest problems is to come up with good states and effective transitions. The state is usually a number, but in your case, the last two characters fully represent the state, so you can come up with the following state variable type:Code:typedef struct {char a, b;} dogger_state;where "b" is the last character, and "a" is one before that.With such state, the implementation is simple:Code:void dogger_init(dogger_state *s) {s->a = 0;s->b = 0;}void dogger_update(dogger_state *s, char c) {// check for "cat" and replace if foundif (c=='t'&&s->b=='a'&&s->a=='c') {s->a = 'd';s->b = 'o';c = 'g';}// send out the pending characterif (s->a) putchar(s->a);// advance the states->a = s->b;s->b = c;}void dogger_fin(dogger_state *s) {dogger_update(s,0);dogger_update(s,0);}Putting it all together:Code:#include <stdio.h>#include <stdint.h>typedef struct {char a, b;} dogger_state;void dogger_init(dogger_state *s) {s->a = 0;s->b = 0;}void dogger_update(dogger_state *s, char c) {// check for "cat" and replace if foundif (c=='t'&&s->b=='a'&&s->a=='c') {s->a = 'd';s->b = 'o';c = 'g';}// send out the pending characterif (s->a) putchar(s->a);// advance the states->a = s->b;s->b = c;}void dogger_fin(dogger_state *s) {dogger_update(s,0);dogger_update(s,0);}void main(){char c;char *p = "dog eat cat\n";dogger_state s;dogger_init(&s);while (c = *p++) {dogger_update(&s,c);}dogger_fin(&s);}And the end result:Code:$./doggerdog eat dog$

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 04, 2018, 11:40:01 pm
content: Quote from: ehughes on November 04, 2018, 04:31:39 pmIt is nice to see there are still those who teach proper engineering principles with softwareQuote from: ehughes on November 04, 2018, 04:31:39 pmThat is scary to see, but not as seppuku-inducing as what you typically see in real-life software projects:Code:// State = 23;// 20080323 devnam1: Fix PR#20121.// State += 5;// 20101130 devnam2: Fix #PR30115 and #PR30121.State += 3;Quote from: NorthGuy on November 04, 2018, 08:43:38 pmThen you're using the term wrong. It is a classic state machine, just described using a flowchart.Quote from: NorthGuy on November 04, 2018, 08:43:38 pmNo. You are confusing finite state machines as a model of computation, and design patterns used for implementing state machines. (Exactly the sort of thing I was complaining about earlier; the gap between software engineering and information technology.)If you can't parse the state machine the flowchart describes, I can write it as a state table for you.

author: brucehoult
author_rank: Super Contributor
timestamp: November 05, 2018, 12:40:08 am
content: Quote from: ralphrmartin on November 04, 2018, 06:03:05 pmAnother problem with an actual 2D array is that if there are a large number of states and a large number of events then it's likely that the array is quite sparse (or at least, most of the entries are some kind of default or error state). In this case it's better to hash the state and event together and use a 1D array about the same size as the number of valid combinations (or a little larger), and a chaining scheme for collisions. It might take a dozen more instructions, but that's unlikely to be a problem.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 05, 2018, 01:26:34 am
content: It might be interesting to compare different implementations or descriptions of a simple state machine, say an alarm clock implemented on a small microcontroller, say with four buttons: alarm, set, +, and -; no snooze functionality.It is interestingly intertwined with the hardware as well. Hardware or software debouncing for the buttons? Interrupts or timing/counting/something else for blinking the digits when editing? Accelerated advance when + or - button is kept depressed long enough? And so on. Might be a good exercise for those studying FSMs; also mix in a bit of user interface design basics.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 05, 2018, 01:48:19 am
content: Quote from: Nominal Animal on November 04, 2018, 11:40:01 pmWhat you quoted from my post is the definition of what the finite sate machine is, and is not related to any implementations. How can we possibly discuss things if we do not have a definition? If you don't like my definition, come up with your own. Although it's defined pretty well in mathematics - look, for example, here (scroll a little bit down to "Formal Definition"):https://en.wikipedia.org/wiki/Mealy_machineSo, what is the definition of the finite state machine in your eyes?

author: bsfeechannel
author_rank: Super Contributor
timestamp: November 05, 2018, 02:08:20 am
content: Quote from: Howardlong on October 31, 2018, 07:44:50 pmWould it be easier if the concept were introduced taking regex as a starting point?

author: westfw
author_rank: Super Contributor
timestamp: November 05, 2018, 02:35:38 am
content: QuoteQuoteI dunno. It's a "data structures and algorithms" topic, maybe. 2nd year or so?It's barely mentioned in Sedgewick, and only in conjunction with searching.I had it (~1980) as part of the digital logic and/or computer architecture class (very hardware oriented), and again as part of the Compiler class (WRT "parsing.") These days it ought to show up in networking internals classes, too."Automata Theory" tends to be a grad class, very mathematical and theory-based.(iehttps://online.stanford.edu/courses/soe-ycsautomata-automata-theory)I think most students would be lucky to have done one example (the infamous "traffic light"), and have never seen it show up as a general purpose tool. FSMs are sort of "unclean" compared to modern tools like graphs and trees - the concept is simple, but there's a lot of complexity in setting things up. Also, they're hard to document internal to softare (yeah, state diagrams are swell. Til you try to do one in ASCII art), and they can be a pain to debug. Software FSMs can easily suffer from a lot of "sloppiness" in terms of implementing things in a particular state that ought to be mutiple states, and WRT integrating some sort of "clock."(sort of classic cases of "coders are not taught enough CS" and "CS majors are not taught enough coding." Sigh.And even if you learned it, you probably don't remember it until after you've had to actually use it a few times.)QuoteNeither is ""outside" of embedded systems"QuoteHeh. I was in that class (or the 1st one, anyway.) IIRC, that lab was quite the disaster for a lot of the participants. Generated MUCH discussion.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 05, 2018, 06:16:04 pm
content: Quote from: NorthGuy on November 05, 2018, 01:48:19 amSee e.g. the Wikipediafinite-state machinearticle. It has a pretty good definition, and also differentiates between the model itself, and its various representation/implementation methods.AMealy machineis just one specific model with an associated representation (the model is restricted to fit a specific representation). Not all finite-state machines are Mealy machines, even when all Mealy machines are finite-state machines.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 05, 2018, 06:19:28 pm
content: Quote from: westfw on November 05, 2018, 02:35:38 amDammit, that's exactly what I was trying to say above, with software engineering and information technology. Me fail English.

author: tggzzz
author_rank: Super Contributor
timestamp: November 05, 2018, 06:26:12 pm
content: Quote from: Nominal Animal on November 05, 2018, 06:19:28 pmNo, you don't fail English: your statements are easy to understand. I may disagree with them, but that is a different issue

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 05, 2018, 08:13:31 pm
content: Quote from: tggzzz on November 05, 2018, 06:26:12 pmBelieve or not, but I actually appreciate that a lot (from everyone, not just you), when the differing viewpoint/reasoning is shown. I'd often miss my own errors otherwise, and I'd rather admit to and fix my own errors, than lead others astray. That also means that I can be quite aggressive when I see claims that might lead others astray; I can't usually just let them be.Anyway, here's the same cat-to-dog state machine description in table form. This one is suitable for use with aMealy machine.Code:State │ Description │ Input │ Action │ Next state═══════╪═══════════════╪═══════╪═══════════════════════╪═══════════════INIT │ Initial state │ EOF │ │ END│ ├───────┼───────────────────────┼───────────────│ │ 'C' │ │ C│ ├───────┼───────────────────────┼───────────────│ │ │ Output input │ INIT───────┼───────────────┼───────┼───────────────────────┼───────────────C │ Have 'C' │ EOF │ Output 'C' │ END│ ├───────┼───────────────────────┼───────────────│ │ 'A' │ │ CA│ ├───────┼───────────────────────┼───────────────│ │ 'C' │ Output 'C' │ C│ ├───────┼───────────────────────┼───────────────│ │ │ Output 'C' and input │ INIT───────┼───────────────┼───────┼───────────────────────┼───────────────CA │ Have "CA" │ EOF │ Output "CA" │ END│ ├───────┼───────────────────────┼───────────────│ │ 'T' │ Output "DOG" │ INIT│ ├───────┼───────────────────────┼───────────────│ │ 'C' │ Output "CA" │ C│ ├───────┼───────────────────────┼───────────────│ │ │ Output "CA" and input │ INIT───────┼───────────────┼───────┼───────────────────────┼───────────────END │ End of input │If you use UTF-8, such tables can be included in comments, if you use a fixed-size font when writing code.I do not have a strong opinion on what form or what tools are best for describing state machines, as I always pick on a case-by-case basis. I used the flowchart at SO simply because I thought it would be easiest for new programmers to understand. In general, the table forms are easier to maintain. With a large number of states, using visualization tools like Graphviz that can be used to generate nice graphs from text, make it easier to get an overall picture of the complexity, and proper context when contemplating changes.For an FSM that implements say a menu system in C on a microcontroller, I use a structs, as GCC allows constructing it at compile time in read-only memory. You do need to forward-declare the states (static const struct menustate menu_foo;before referring to it via&menu_foo), but with a little care, the end result is maintainable.

author: tggzzz
author_rank: Super Contributor
timestamp: November 05, 2018, 08:26:38 pm
content: Quote from: Nominal Animal on November 05, 2018, 08:13:31 pmJoin the club.QuoteMe too. Many techniques can be used.I've used "event = thread.yieldUntilOrTimeout(setOfInterestingEvents, timeoutMs); process(event);" "continuation-style" code in the past. That does read like a flowchart!QuoteOne consequence of using a flowchart is that the FSM nature of the code is implicit rather than explicit. Another is that it is less suited to event-driven programming and more difficult to integrate with other activities. Beginners seem to have no difficulty understanding for( ; ; ) superloops, and how event driven code fits into that.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 05, 2018, 08:29:23 pm
content: Quote from: Nominal Animal on November 05, 2018, 06:16:04 pmOk. Here's the definition from the page you quoted:Code:A deterministic finite state machine or acceptor deterministic finite state machine is a quintuple,"Sigma" is the input alphabet (a finite, non-empty set of symbols)."S" is a finite, non-empty set of states."S0" is an initial state, an element of S."Selta" is the state-transition function: Delta : S × Sigma -> S"F" is the set of final states, a (possibly empty) subset of S.Doesn't look much different from the Mealy page, but anyway:Looking at the code you wrote for your cat->dog machine, can you point out where is the "set of states" and where is the "state-transition function"?Quote from: Nominal Animal on November 05, 2018, 06:16:04 pmIs your cat->dog machine Mealy?

author: KaneTW
author_rank: Frequent Contributor
timestamp: November 05, 2018, 08:48:15 pm
content: Quote from: westfw on November 05, 2018, 02:35:38 amIn my university state machines are a 2nd semester mandatory class for Bachelor CS, with advanced automata theory being a 4th semester+elective. FSMs for embedded systems are taught in 4th semester+ electives, too.

author: westfw
author_rank: Super Contributor
timestamp: November 05, 2018, 10:06:37 pm
content: QuoteA whole class? Software State Machines?Do you happen to have a class syllabus and/or textbook reference handy?I'd be interesting looking at educational material that is more in-depth than The Traffic Light while being less theoretical than the advanced FSA classes I've seen...

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 05, 2018, 10:46:40 pm
content: Quote from: NorthGuy on November 05, 2018, 08:29:23 pmNo, that's the formal definition of the mathematical model that can represent any finite-state machine. Here's the actual definition, shortened a bit:Quote from: WikipediaQuote from: NorthGuy on November 05, 2018, 08:29:23 pmWell of course the mathematical definition is the same, for chrissakes! What part ofall Mealy machines are finite-state machinesdid you miss?The flowchart describes an implementation of a finite-state machine. I chose a flowchart, rather than a table, because I thought that at StackOverflow new programmers would find it much easier to convert a flowchart to code. (Do note that I forgot to add an edge from "Output D O G" to the top node.)To convert it to a flowchart where each state is clearly delineated, I would have to duplicate the diamond corresponding to thechar = Ctest twice (to the two states below it). In an implementation, the single test suffices,as the transition caused by that test is always the same, and it nicely simplifies the code as well. Nevertheless, repeating that test twice more, the three non-final states would be vertically stacked, with the fourth final Done state on the right side.If that is your objection, I'd be inclined to agree, and be more than happy to fix the flowchart, and add the states as say shaded background areas.Mathematically, the input alphabet setΣis the set of values Cfgetc()function may return. Of this set, valuesEOF,'c','a', and't'are used in determining the appropriate action and state transition, and all other values use a common action and state transition.The set of statesShas three states:Initial state,C state, andC A state. The initial stateS0should be obvious. There is one final state inF,Done. The transition functionδ(state, input)can be described thus:δ(Initial, EOF) = Doneδ(Initial, 'c') = Cδ(Initial, other) = Initialδ(C, EOF) = Doneδ(C, 'a') = C Aδ(C, 'c') = Cδ(C, other) = Initialδ(C A, EOF) = Doneδ(C A, 't') = Initialδ(C A, 'c') = Cδ(C A, other) = CIn Mealy machine terms, the output alphabetΛis the input setΣexcept for EOF. The output functionG:S×Σcan be defined asG(Initial, EOF) =NothingG(Initial, 'c') =NothingG(Initial, other) = otherG(C, EOF) = 'c'G(C, 'a') =NothingG(C, 'c') = 'c'G(C, other) = 'c'G(C A, EOF) = 'c' 'a'G(C A, 't') = 'd' 'o' 'g'G(C A, 'c') = 'c'G(C A, other) = 'c' 'a'I was not trying to be snide, when I said that if you have difficulty reading the flow chart into a finite-state machine, I could show the state table also. Like tggzzz wrote, it is not obvious.Quote from: NorthGuy on November 05, 2018, 08:29:23 pmThe model the code implements is a finite state machine. It does not mean that the code must contain identifiable elements that correspond to the mathematical description.This is exactly what I mean by there being a gap between "coding" and "computer science".The model the code implements isa finite-state machine. The design pattern it uses to do so is a simple loop; not something often used for finite-state machines. Yet, that does not mean the code does not implement a finite-state machine.Quote from: NorthGuy on November 05, 2018, 08:29:23 pmSo funny, ha-ha. Only if your definition of a Mealy machine allows the output functionGto output more than one symbol at a time.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 06, 2018, 01:17:18 am
content: Would this diagram work better than my earlier one?Especially considering new programmers, would this one be easier to understand and implement?White rounded rectangles are states, and the gray rounded rectangle is the final state. I didn't name the states, as there are just three. The "Read char" label reminds new programmers to read a new character.Yellow rectangles name input characters. Arrows with a red head are state transitions. Blue rounded rectangles are output actions. The intent is to be intuitive even for those who are not used to reading such flowcharts.

author: KaneTW
author_rank: Frequent Contributor
timestamp: November 06, 2018, 06:08:29 am
content: Quote from: westfw on November 05, 2018, 10:06:37 pmNot quite a whole class, but a major part. I should note it focuses more on DFA/NFAs in the context of languages.https://verify.rwth-aachen.de/fosap10/-- German only unfortunately.

author: JPortici
author_rank: Super Contributor
timestamp: November 06, 2018, 07:04:39 am
content: Quote from: Nominal Animal on November 06, 2018, 01:17:18 amIs there a software that helps you to generate flowcharts like this without doing everything by hand?

author: nfmax
author_rank: Super Contributor
timestamp: November 06, 2018, 08:37:35 am
content: A comment: when coding a state machine, the current state may be represented either explicitly by a specific, dedicated variable, or implicitly, by the program counter. The software will be more maintainable (=easier for humans to read and understand) using explicit state storage.

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 08:43:23 am
content: Quote from: JPortici on November 06, 2018, 07:04:39 amIf you mean "draw", then search for UML StateCharts and similar.If you mean "reverse engineer" from code, good luck.

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 08:46:32 am
content: Quote from: nfmax on November 06, 2018, 08:37:35 amPlus easier to debug via logs, including in running production systems. The latter isextremelyvaluable as a way ofdocumentingwhether an infelicity is in your product or another company's product.In dysfunctional workplaces, s/company/team/ or even s/company/developer/

author: JPortici
author_rank: Super Contributor
timestamp: November 06, 2018, 08:52:34 am
content: Quote from: tggzzz on November 06, 2018, 08:43:23 amnah, drawit's for my own documentation.. i would be fine with WORD if they were a bit more flexible. Will read on UML!i don't know why i wrote generate... must have been too late or too early

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 09:13:01 am
content: Quote from: JPortici on November 06, 2018, 08:52:34 amIn my experience it is frequently too early/late!Be wary of attempting to autogenerate a complete application from such drawings. There have beenmanyattempts and products over the decades; I even proposed one in 1986! The unsuccessful ones forget that the edge case interactions with the real-world can be very messy. The successful ones have a carefully specified and limited domain of applicability.

author: coppice
author_rank: Super Contributor
timestamp: November 06, 2018, 02:17:35 pm
content: Quote from: tggzzz on November 06, 2018, 09:13:01 amI have seen successful uses of state drawing to code generation, but they have always been in tightly defined domains. For example, in the late 80s we produced ITU SDL charts (basically a representation of an FSM in drawing form), using AutoCAD, for telephony signalling algorithms. These were automatically compiled into the state tables that went into the custom FSM hardware in our telephony systems. Because custom hardware was used, the boundaries of what needed to be represented were well defined, and the compilation process was fairly simple and closed ended.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 06, 2018, 02:43:03 pm
content: Quote from: Nominal Animal on November 05, 2018, 10:46:40 pmExactly. You now did a good job documenting your state machine - with a table, textual transfer functions. You replaced the ugly flowchart with a diagram which actually represents you state machine. But the code you wrote is still disconnected from this representation.As there are multiple ways to represent your state machine on paper, there are different ways to implement this representation in code. You can code the transfer function directly, or you can build an array which mimics the table and lets you fetch the next state using the current state and the received character, or you can represent your states as function pointers etc. The code you have now is just not a representation of your concept, hence you feel the disconnect.BTW: When I was a kid, I read a book about programming (which wasn't a new book even back then). The author suggested drawing a flowcharts (similar to your first diagram). He thought this was mandatory. Now I cannot tell whether this was a mainstream thing, or just this one author. Once you have a flowchart, the programming then becomes the implementation of the flowchart. Blocks get their lables, square blocks are replaced with sequential code, conditional blocks are replaced with ifs, lines become gotos. As soon as you have created the structure with labels and gotos, you can fill in. The same approach works equally well with any language - algol, assembler. Would work with C too. This may be a good idea when you write your program on sheets of paper (one sheet per block), but when looking at it on the screen, it looks horrid. It later was called spaghetti code and is now completely frown upon. Interesting, your flowchart led you to exact this kind of implementation. Of course, you replaced gotos with modern "continue" etc., but this doesn't change the structure of the code.

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 02:56:55 pm
content: Quote from: coppice on November 06, 2018, 02:17:35 pmIn the early 90s I saw a team attempt to do ITL SDU -> C++. The effort foundered since they tried to use C++ to do the drawings (should have used Smalltalk), and tried to generateallthe code from the drawings instead of just the core FSMs.Clearly that doesn't invalidate the concept.But given a suitable Design Pattern, the FSM aspect of the specification can be easily implemented as traditional code. That avoids the learning curve with special tools, impedance mismatches between different levels of the implementation, and enables bog-standard tools to be used.

author: rstofer
author_rank: Super Contributor
timestamp: November 06, 2018, 03:35:08 pm
content: Page 5 shows a state diagram for a RISC type processor - LC3bFrom this diagram and the datapath diagram on page 7, the VHDL can be written directly or there's a blank table for filling in what is essentially microcode on page 14. I haven't tried the microcode approach but it a very powerful technique. IBM 360 computers (and many others) used a microcode approach and the code was on an 8" floppy - invented by IBM for that specific purpose.http://users.ece.utexas.edu/~patt/05f.360N/handouts/360n.appC.pdfA person could take the state diagram and the datapath diagram and convert them into a "C" switch() statement. Creating an emulator would be pretty simple.There is no way to avoid state machines when working with sequential hardware.

author: rstofer
author_rank: Super Contributor
timestamp: November 06, 2018, 04:05:45 pm
content: Quote from: NorthGuy on November 06, 2018, 02:43:03 pmWhen I started programming in '70, flowcharts were very common. Nobody would even think about writing code without a flowchart, especially the COBOL programmers where they were dealing with business transactions in a batch environment. FORTRAN programmers, not so much. This was especially true if all they were doing was some numeric project. However, FORTRAN was used for significant simulations and there were often flowcharts available for the various subroutines in a library.Here is the IBM Reference Manual for flowcharting:http://media.ibm1130.org/E0016-ocr.pdfI still sometimes do something of a flowchart because this is a good way to understand the top down design and bottom up coding. At least, I'll scratch something out...In the early days, we didn't have elegant flow control statements and that, more than flowcharts themselves, led to spaghetti code. FORTRAN IV only had 'goto' of various flavors (direct, computed, assigned and 'if'). There wasn't a while() or repeat-until() and we had to kind of invent these constructs as we went along. Given enough effort, it is possible to write code without a lot of extraneous goto's and flowcharting may actually help in that effort.Even "C" has a goto statement and sometimes it is the best way to break out of nested loops. Not often, but sometimes!Here is a copy of Dijkstra's 1968 paper on harmfulgo tostatements:https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdfQuote

author: RobBarter
author_rank: Regular Contributor
timestamp: November 06, 2018, 04:48:34 pm
content: One of my clients (I'm a contract software developer) models a number of state machines in Enterprise Architect (EA). A custom c# application then interrogates this model via the API published by EA and generates the c++ code to the coding standards the client adheres to (quite strict given it's a medical device). All passes Lint and internal human code review. So if we change the model we just regenerate the state machine code. The c++ code uses Boost.I would hope that Comp Sci departments in Uni still teach this stuff. I'm sure I was...although it was a while ago.

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 05:03:08 pm
content: Quote from: RobBarter on November 06, 2018, 04:48:34 pmFor quality control purposes, is the "source code" the "FSM in EA" or the C++ code?If the former, then presumably the C# application has to be considered part of the source code. If the latter, what assurance is there that the C++ code matches the FSM?

author: RobBarter
author_rank: Regular Contributor
timestamp: November 06, 2018, 05:26:35 pm
content: The C++, although the c# tool is also under full code review / versioning etc. EA versioning isn't that good.The code review ensures we have unit tests that prove the state machine matches the model. i.e. every transition / event is tested, including custom reactions.

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 05:45:18 pm
content: Quote from: RobBarter on November 06, 2018, 05:26:35 pmI've seen that kind of thing with visual tools before. It can be very difficult to get a solid statement of which files/directories must be included and can be excluded.Makes it difficult to replicate an environment on a different machine, or even to guarantee a rollback to a known version.

author: RobBarter
author_rank: Regular Contributor
timestamp: November 06, 2018, 05:49:24 pm
content: You can of course archive the whole EA model (which is done regularly) or export parts of it, but yes, visual tools versioning hasn't yet been perfected.

author: legacy
author_rank: Super Contributor
timestamp: November 06, 2018, 06:31:21 pm
content: Quote from: RobBarter on November 06, 2018, 05:26:35 pmThis is similar to Stood + Doors, used in avionics for the same task.Stood is written in Prolog

author: bd139
author_rank: Super Contributor
timestamp: November 06, 2018, 06:48:57 pm
content: I have a rule: If the client is using EA, I won’t take the position. Not because of the tool but the average user. I watched a company spend a year on the assumption that if they threw their 200 domain object model into it and used the code generator it would solve world peace. It merely threw the project back six months. YMMV but it’s a problem in some teams not a solution.On the original topic I’ve written a few state machines, usually lexers and protocol parsers.I also wrote a state machine DSL a few years back because I was bored of writing state machines. Unfortunately I accidentally signed the rights to it over to the client. That was a fun tool to write. I decided I wasn’t going to use Antlr or anything so write my own parser, AST etc for the DSL. Code generator generated fully async stream code. Similar to SAX but for on the wire protocols.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 06, 2018, 06:55:59 pm
content: Quote from: bd139 on November 06, 2018, 06:48:57 pmSo true.As I teasingly hinted above, just wait until aspect-oriented programming becomes the next silver bullet in embedded programming. Fun days ahead.

author: bd139
author_rank: Super Contributor
timestamp: November 06, 2018, 07:02:27 pm
content: Oh don’t go there. I spent most of 2013 removing some astronaut architect AOP transaction management mess from a 5MLOC enterprise turd ball. Every damn thing got promoted to DTC because of the nested death they created. Unfortunately hardware wasn’t moving as fast as their growth was so it had to be yanked out hard.They’re currently rewriting everything as microservices because they hired another astronaut architect. I will be hired in about two years again to reduce their transaction latency

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 06, 2018, 07:15:52 pm
content: At least that means more business for you!

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 07:24:55 pm
content: Quote from: SiliconWizard on November 06, 2018, 06:55:59 pmAh yes, "patching the binaries" enshrined in the architecture; code reviews rendered meaningless.It can be the technology that enables people to change codeafterit has been compiled and/or installed. That's certainly true for dynamic languages like Java, Smalltalk, LISP, and presumably C#. If it is impossible for C/C++ then it would be one point in their favour.I mean, who could possibly object to invoking customer.charge(price), only to find that AOP has intercepted the call to order a pizza or salami slice a little bit into a completely different account?

author: bd139
author_rank: Super Contributor
timestamp: November 06, 2018, 07:28:56 pm
content: class PayContractorFivePercentInterceptor {}

author: NivagSwerdna
author_rank: Super Contributor
timestamp: November 06, 2018, 07:54:40 pm
content: Of course nowadays state machines are obsolete. You can model them using Machine Learning/Neural networks. They have to be trained by trying many states but eventually they will work out which state they should be in.(I had a similar discussion regarding rules based systems compared to ML recently).

author: bd139
author_rank: Super Contributor
timestamp: November 06, 2018, 08:07:14 pm
content: I always use this as a reference on that subject:https://youtu.be/h73PsFKtIck

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 06, 2018, 08:19:56 pm
content: Quote from: NivagSwerdna on November 06, 2018, 07:54:40 pm"which state they should be in" sounds very appealing for any safety-related designs.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 06, 2018, 08:27:14 pm
content: Quote from: JPortici on November 06, 2018, 07:04:39 amDia, for example.Graphviztoo. Have them save/export the output to SVG, then edit that inInkscape. The former was drawn in Dia, the latter directly in Inkscape with on a grid. Like I said, the tools I happen to use, vary a lot.Quote from: NorthGuy on November 06, 2018, 02:43:03 pmNo, what you mean is that you find it difficult to map the code to the underlying model. That's just your own personal limitation.You keep claiming that the two must match 1:1. I disagree, because one is about software engineering and dealing with real world imperfect languages and tools, and the other is about computer science and mathematics. They are at completely different levels, and deal with completely different problems. This is the gap.Consider this: Is the underlying model any different, if you replace a tail recursive call with a loop? No, it is not. It is just an implementation detail.Similarly, my code uses a common pattern where the "read input" part is done before the state transition, because it reduces the number of conditional jumps (as several similar transitions and their associated input checks can often be combined). The instruction prefetch and caching behaviour on current computers is such that conditional jumps tend to be slow compared to other operations, so a pattern that reduces those (or has a common target) is desirable.Keep that pattern in mind, and read the C code and compare to the diagram. (The pseudocode and its explanation could do a rewrite to make it clearer; the C code is what I whipped up and tested before writing the answer. I also don't find my English language skills as good as I'd like, so the text itself could do with cleaning. But as it is just advice to learners, with the key point being to document what they are trying to accomplish (the model) and their intent of how to implement it, I probably will not bother.)

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 06, 2018, 08:33:39 pm
content: Quote from: tggzzz on November 06, 2018, 07:24:55 pmThat reminds me of web frameworks and bulletin boards, that insist on being able to "auto-update" themselves; i.e. rewrite their own script files. I think I reviewed one that rewrote its own script files whenever any configuration changes were done via its own web interface. Talk about footgun built into the core design...

author: tggzzz
author_rank: Super Contributor
timestamp: November 06, 2018, 10:49:21 pm
content: Quote from: bd139 on November 06, 2018, 08:07:14 pmOf fond memoryOnce, long ago, I booked a seat to see that on Boxing Day at the NFT in London. Later I found it was being shown on TV , starting 15 mins later. I still went to the NFT for the day out and cinema experience.

author: bd139
author_rank: Super Contributor
timestamp: November 06, 2018, 10:53:14 pm
content: I bet that was a marvellous experience though. Well worth it. I still go to the cinema today. Usually go on my own on a week day when there’s no one to annoy me

author: NorthGuy
author_rank: Super Contributor
timestamp: November 06, 2018, 11:12:00 pm
content: Quote from: Nominal Animal on November 06, 2018, 08:27:14 pmBut if the theory doesn't translate into the code, what is the point of drawing diagrams, tables, formulae. Why have you spent hours working on these things if you don't use them when you write the code. Languages and tools are perfectly capable of compiling any code you write. They has been capable of handling various state machine implementations for dozens of years.IMHO, drawing diagrams usually doesn't help much even if you use them to build your code. But if you don't, what's the goal?

author: legacy
author_rank: Super Contributor
timestamp: November 07, 2018, 10:56:07 am
content: QuoteSee also the gap between the Math on a piece of paper, and ... the Math on a Computerif you have ever readthistopic about pixel-color interpolation, ... well, for example, the edge equation A*X + B*Y + C = 0 assumes that, given two points p1(x,y), p2(x,y), a system of two of these equations is always equal to zero, therefore the cross-point equation should be also fine to check if a point belongs to the border of a triangle, which ... only works when numbers are defined on the paper rather than on the grid (compter screen-pixel plane).A*X + B*Y + C =!= 0 for the Bresenham's Line Drawing AlgorithmElisabeth, Zeda, and I have spent two weeks at finding a solution, which physically consists in a correcting function.Theory + correcting function to adapt the theory to the poor prosaicness of the world = problem solvedWe are still referring to the original formula, which doesn't work on the grid, and we are explicitly keeping all the add-ons in the correcting formula: this illustrates where things come from, how they work, providing also a scientific background.Code:...Dx = (B.x - A.x) * (p.y - A.y);Dy = (B.y - A.y) * (p.x - A.x);is_on_edge = do_speculative prediction(A, B, p);if (is_on_edge isEqualTo True)...Imaging now those guys who don't follow this approach: you see magical C code that is supposed to work on the computer screen, but you have absolutely no idea where the idea comes from, hence you have to reverse engineering patterns comparing them to something known from Computer Graphics books, but sometimes the code is a mess up, or it doesn't follow any known pattern in Computer Science, and you end completely lost. Too bad, that's not a scientific approach.

author: legacy
author_rank: Super Contributor
timestamp: November 07, 2018, 11:04:13 am
content: Quote from: NorthGuy on November 06, 2018, 11:12:00 pmWell, diagramshelp a lotpeople in a team to understand details. You don't have to draw diagrams on everything, but you'd better draw them about critical roles and details.That's the point.

author: RobBarter
author_rank: Regular Contributor
timestamp: November 07, 2018, 11:45:15 am
content: Good luck trying to explain a complex state machine with decision points and transitions to a systems engineer, who doesn't code, without a diagram. Fine if your system doesn't do a great deal or you're a one-man-band, but not if it's complicated or requires supporting in the future by someone else.

author: legacy
author_rank: Super Contributor
timestamp: November 07, 2018, 12:33:31 pm
content: Quote from: RobBarter on November 07, 2018, 11:45:15 amyeah, exactly what I meant

author: bd139
author_rank: Super Contributor
timestamp: November 07, 2018, 12:39:41 pm
content: One of the things I did when I built my state machine compiler was generate output for graphviz. That turned the DSL into a state diagram from the IR.Code in the DSL, generate code and diagram from output. The DSL was VCS friendly thus solving the problems of synchronising documentation with reality.

author: BrianHG
author_rank: Super Contributor
timestamp: November 07, 2018, 01:12:05 pm
content: Though I knew what a FSM was, I first come into contact with a project where the contractee demanded I developed their building management system based on their block diagram state machine. This was the first time I had such a huge project which needed to be fitted to a 16 bit PIC MCU. I was given a worded description of what the device had to do, written in english, then the multi-page block diagram made out by a few board members who designed the system functions. The system had to run an update-able state machine so the board of directors could make their own modifications. I couldn't make heads or tails of it as discussions went back and forth. So I passed the design to one of my engineering colleagues who specialized in high level programming and state machines. What should have been a 1 month project took over 6 months, because, and get this, the damn block diagrams were full of illogical inconsistency errors which was the first thing I brought up when first going over the illustrations, which is why I passed on the project.My second experience with a state machine project was an alarm/doorbell/automatic door opening system, because, this one was layed out by someone who knew a bit more of what they were doing, and I was able to talk to him personally. The project took only 5 hours to complete and debug, where 75% of the state machine was left functionally intact as a FSM while an overriding emergency door locking state within the diagram I removed and hard coded it to kill & reset the state machine as this way, the safety aspect overrided any unforeseen state machine problems.If the source of the state diagram make sense, I can deal with it.If it doesn't, even if it may still function, my head will go "awol" as I try to create the project and I would rather be in a mental institute that work on such a project, no matter how much I'm offered in money...

author: T3sl4co1l
author_rank: Super Contributor
timestamp: November 07, 2018, 01:55:17 pm
content: Quote from: legacy on November 07, 2018, 10:56:07 amRight, equals zero for an infinitesimal line, plotted in the domain of real numbers. Which isn't very useful, because you can't see a zero-width line...Also not very useful because real numbers are... very poorly named. Nothing in the real world is actually a "real". That would require infinite information.On the subject of state machines: plotting a real line segment requires an infinite state machine. Plotting an integer line segment requires only a finite state machine.The insight you are missing is this: if it's not zero, thenhow close to zerowill it be, given A, B, C, X and Y quantized to a grid of so-and-so size?This is identical to the matter of testing floating point numbers byproximity to zero, not equality to zero (or equating two numbers within some ε, same thing). Same logic, and numerical methods, apply.It then follows that, for Bresenham's for example, the error term is a variable-scale measure of the sub-pixel position of the line, where it intersects a grid edge. (Variable in terms of A/B.)Tim

author: legacy
author_rank: Super Contributor
timestamp: November 07, 2018, 02:28:38 pm
content: Quote from: T3sl4co1l on November 07, 2018, 01:55:17 pmthe solution is a bit more complex due to the fact that the Bresenham's internal state to choose the next pixel is based on a not visible state which is derived step by step on a floating error, which is not exactly equal to the line equation's errorerr0 = A *X + B * Y + Cerr1 = Bresenham's errorerr0 is not necessarily always equal to zeroerr0 is not necessarily always equal to err1Given a starting and ending points, the finite state machine of the Bresenham's algorithm computes in a finite number of steps (whose precise number can be calculated by the Pythagoras formula), but the error at each step is not predictable by unrolling the algorithm, because the equation becomes recursive.Which is very very bad!So we had to invent a way to solve it. With a speculative algorithm that tries to speculate on the error magnitude compared to the magnitude of the A and B slopes. This trick is computationally light (it takes 2 multiplies and two adders, plus two comparators) and it works fine, it's not perfect, but it does an excellent job, even in HDL implementation.This work is for a mini GTE (geometry transform engine).

author: tggzzz
author_rank: Super Contributor
timestamp: November 07, 2018, 04:18:06 pm
content: Quote from: bd139 on November 07, 2018, 12:39:41 pmThat addresses and solves some important issues, but raises the issue of readability of the diagram in two respects:it really can look like a bowl of spaghetti!"strange" things might be permissable in the text, but not have a good diagramatic representationBoth are solvable, with discipline. But discipline over the long-term is in short supplyI was once involved with assessing a large-scale commerical "FSM-type" product, Kabira. The salesman touted the new graphical design suite, proclaiming it could generate 0.5MLOC/day. My retort was that I could easily personally generate 1MLOC/day.More interestingly, the Kabira application engineers didn't use the graphical tools, preferring to work with text. Now there may have been some stick-in-the-mud behaviour, but that wasn't the whole story.

author: bd139
author_rank: Super Contributor
timestamp: November 07, 2018, 04:30:23 pm
content: Very true indeed. The diagrammatic representation doesn't scale very far either. As the number of states increases, the more it resembles the phone junction box down the road.However the point in this case was that there was one canonical "source of truth" which was the DSL rather than a separate document that was interpreted by meatspace and turned into a hand generated state machine that sort of did what it was supposed to do. The diagram was a soft requirement for the analysts. It was there, regardless of ugly factor so they were happy. Think of it more as "ladder logic" for the developers here who couldn't be trusted to write it themselves.I have come to the conclusion you can't actually ever win with these situations other than making code the intermediate representation somewhere. Plus I like writing lexers and parsers so every problem that looks like that is a handy nailI think graphical tools work really well for expressing this sort of stuff until one of three conditions occur:1. Someone did something on one branch that requires merging. I watched two (contract) graphic designers merging a PSD a couple of weeks back which was hilarious as most of it was spent outside smoking and arguing with each other.2. The company selling the tool discontinues it, usually because the only guys who know how it works left for a cushy job doing nothing of importance (aka SRE) at Google.3. It uses some obscure windows API badly and doesn't work on windows 10 and no one wants to run a Windows XP VM until the sun implodes.I love the software industry if I'm honest. It's so fun watching the incredible level of dysfunction wherever you look. When it comes to it you can sit back and watch the human race slowly coding itself into a nasty little corner somewhere.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 07, 2018, 04:32:49 pm
content: Quote from: legacy on November 07, 2018, 02:28:38 pmIt is easy to estimate the precision you need in your calculations to make sure the error is within the limit. The fact that the algorithm is iterative doesn't change that. Say, for the 1000-point screen, if you want 0.1 pixel precision on your calculation, your coefficients must have 0.0001 precision, which is 14 bits. This guarantees that the maximum error of a single step is 0.0001 pixels, and therefore after 1000 steps your error will be less than 0.0001*1000 - 0.1 pixel. So, if you represent your coefficient as a 32-bit integer where 16 upper bits represent pixels and 16 lower bits represent fractions, you know that you will meet (and exceed) your 0.1 pixel requirement, and all your absolute errors will be less than 0.1 pixel.

author: tggzzz
author_rank: Super Contributor
timestamp: November 07, 2018, 05:20:45 pm
content: Quote from: bd139 on November 07, 2018, 04:30:23 pmThat sums up my beliefs and experiences.Its a bit like WISYWIG editors vs markup editors. I like WISYWIG for small, quick and dirty things. But if I'm doing something large that may change over time, I prefer markup editors.Itisnice to have a graphical representation, hence UML exists. (And the nice thing about UML is that there are so many incompatible diagrams to choose from!)In the end, it is often easier to JWTFC - just write the f*g code. But it helps if the code structure/style/architecture is simple, regular, and firmly implements FSM concepts.

author: coppice
author_rank: Super Contributor
timestamp: November 07, 2018, 06:41:34 pm
content: Quote from: tggzzz on November 07, 2018, 05:20:45 pmThe bottom line is that for really small FSMs almost any representation is adequate, and for really big state machines all representations suck when you are trying to get your head around them. Welcome to life.I just try to live with what annoys the people around me the least.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 07, 2018, 06:51:29 pm
content: Quote from: coppice on November 07, 2018, 06:41:34 pmThere are rare cases where graphical presentation is extremely useful, such as JTAG protocol, for example.

author: tggzzz
author_rank: Super Contributor
timestamp: November 07, 2018, 08:00:35 pm
content: Quote from: coppice on November 07, 2018, 06:41:34 pmFrequently big FSMs can be usefully broken up into multiple independent small FSMs that send messages to each other. That is, after all, at the heart of telecom systems!

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 07, 2018, 08:08:25 pm
content: Quote from: NorthGuy on November 06, 2018, 11:12:00 pmMap ≠ translate. That translation is in the gap I've been talking about in this thread; bridging computer science and practical coding (or software engineering).Sure, you can write code that maps the model to code 1:1, but then you discard the practical considerations and code-level stuff that can make the implementation much better. Or you can just write code and not care about the underlying models, but then you discard a lot of known-good models and algorithms. Only by combining the two, you get the best of both worlds.Yes, that sort of synthesis is hard. It is also not taught anywhere, as far as I can see. Yet, when looking at the development process, most problem-solving expert types do that constantly.Note, however, that there is another expert type of programmer: those that write easily maintained code without other code-level considerations at all. I do not want to imply that all expert developers must be the synthesist type. Sometimes correctness, maintainability, and being easily verifiable is way more valuable than any code-level considerations.Even if the code-implementation happens to be of write-only sort, the model-level documentation helps, because it allows anyone to rip out that particular piece of code, and re-implement it. This kind of modularity has shown to be extremely useful: it was the only way the Linux kernel developers could overcome the bottleneck of limited maintainer throughput. (Yet, even they are struggling with the documentation part, especially things like locking schemes. To avoid having to write it all out and maintain that as well as the code, they've developed tools that check for common problems.)I like that kind of modularity a lot, because it allows competition of ideas and implementations even within a single project.Quote from: legacy on November 07, 2018, 10:56:07 amYup. That one is even harder than usual, because Bresenham's line algorithm is iterative; converting it to a direct analytical function is mathematicallyhard. (A solution that works for all nondegenerate inputs is certainly worth submitting to one of the ACM journals.)A pure model-level person (like, say, compiler or standard library developers tend to be) might quip that you need to switch to the fixed-point slope algorithm (which chooses slightly different pixels), but that is not a solution, it is just changing the problem to one that is easier to solve. The reason why one would prefer to stay with Bresenham's, is that at the code level, it is extremely efficient, with the iteration loop only using additions, subtractions, and comparison or over/underflow test. That synthesis/gap/whatchamacallit pops up here once again.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 07, 2018, 08:26:33 pm
content: Quote from: bd139 on November 07, 2018, 04:30:23 pmIt's the human brain that doesn't scale! The diagrams and tables can describe the machine exactly, but if they're outside the humans grokking capability, they could be abstract art for all intensities and porpoises.Quote from: bd139 on November 07, 2018, 04:30:23 pmI'd wager you found out that the real underlying problem was to get the domain-specific language users to write machines that actually solve the problem they're supposed to. I mean, it is so easy for humans to believe they know how a problem should be solved, but either be completely wrong, or only solve a part of it. Tools that make it easier for them to implement their solution does not fix that. Yet, if you create a tool that points out the flaws in their reasoning, they're more likely to hate it than use it; most people just cannot stand having their errors pointed out.How did you avoid getting (yourself, via the DSL and its compiler/interpreter) blamed for user errors?Quote from: bd139 on November 07, 2018, 04:30:23 pmIt depresses me to no end... that's why I switched to physics. Not that it isn't just as inane, though: applying for funding is closer to buzzword bingo than anyone would guess. I wish I could just sit back and enjoy the show.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: November 07, 2018, 08:49:38 pm
content: Quote from: legacy on November 07, 2018, 06:58:36 pmI mean, if you close your eyes and ignore the accumulator in the middle of the algorithm, maybe.QuoteHow is it not predictable? It is the remainder of a division operation. These things aren't new by any means -- division, factoring and LCM/GCM algorithms were known to the ancients (and probably not even invented by them, that is, by the ones who left written history).The ingenuity that went into them, is probably harder to understand though... many of these things, you look at them and it seems as if they're a gift from the heavens themselves.Myself personally: I probably developed some of my insight on this subject, working with raycasters (i.e., the pseudo-3D technique famous from Wolfenstein 3D and such). In this case, you must calculate not only the grid locations touched by a given ray, but the exact sub-pixel of each grid line intersection (which is used for the wall texture coordinate). Some linear algebra takes care of perspective correction (a linear sequence of vectors is rotated by the viewing angle, and the iteration proceeds according to the X and Y components of the vector), and then you have it.It's a problem I come back to every couple of years (or decade, it seems closer to now). My first version was the naive add-a-fixed-distance-and-test method, which is very inefficient and coarse. Then I learned the slope-intercept method, which involved a multiplication per step and which blows up under special cases (i.e., parallel to axes). Finally, I developed the dual-accumulator method (which, I forget if that's also what Carmack worked with back then, or if I looked at the WOLF3D source and got it from there..), which uses two divisions to set up the calculation, then only conditional increment and addition in the inner loop. Finally, the accumulator residues are converted to the texture coordinate.For your case, the endpoints are known, which are the vector components fed to the accumulators. At any point along the line, the accumulator values can be read and converted to the sub-pixel coordinate, in terms of X or Y intercept, however you like.(If you're interested, I've got a public example here:https://github.com/T3sl4co1l/raycast_win/blob/master/main.cpp, written in floating point since a PC doesn't care, but it works equally well (with suitable adaptations of course) in fixed point. Also, this isn't textured, so it doesn't have the coordinate transformation step, sorry about that.)QuoteIf you want to know for a specific point, remainderAtX(Dx, Dy, AtX), then you have no choice but to calculate it the hard way, i.e., by division. That division can be performed iteratively, or by the various numerical algorithms known. Doesn't much matter, as long as the results are equivalent (as they must).The loop can be unrolled, by using C-style logic operators. That is (e.g.):Code:int condition = xAccum > yAccum; // 1 if true, 0 elsexAccum += Dx * condition;yAccum += Dy * (condition - 1);xAccum -= Dy * (condition - 1);yAccum -= Dx * condition;On many machines, this will compile as a conditional anyway (i.e., when the only nonlinear operation available is a test-and-branch sequence), but some have an instruction that can perform it without the pipeline hit, a sign-extend or a proper C-style condition-bits-to-register instruction.Or, on still other machines: multiplication and division may be practically free, compared to, say, IO bandwidth limitations. Vector machines -- GPUs and such -- fit here. Example:https://youtu.be/bIjrSvGddDQTim