From 46d7c968cc69e5c6057c495659c7e2b23fab1c27 Mon Sep 17 00:00:00 2001 From: Brent Yorgey Date: Thu, 5 Jan 2023 17:11:30 -0600 Subject: [PATCH] Add `GPS receiver` device to provide `senseloc` capability (#956) Add a new `GPS receiver` device which enables the `senseloc` capability (and hence the `whereami` command). Towards #26 . - My immediate motivation is that I want to be able to define `excursion : cmd unit -> cmd unit` which executes the given command and then returns to the same location and orientation as before. Being able to use the `whereami` command is one of the last missing pieces of machinery necessary to be able to do this in classic mode (the other is a `heading` command, see #955). - The proposed recipe for `GPS receiver` is `antenna + circuit + clock + compass`, which is a somewhat difficult recipe (`antenna` requires `silver` which requires a `deep mine`; a `clock` requires `quartz` + a bunch of `iron gears`, etc.). One might wonder whether we should make the recipe easier since finding out where you are seems like a kind of fundamental operation. However, consider that in order to even be able to make use of the result of `whereami` you need at least (1) an `ADT calculator` to deal with the pair (which transitively requires `typewriter` -> `circuit` -> `silicon` -> `quartz`) (2) probably things like `comparator` and `calculator` to do anything useful with the coordinates. By the time you have those things you can definitely already build `circuit` + `clock` + `compass`, and you're probably not that far away from getting some `silver` for an `antenna`. Also, in practice it's an interesting/fun constraint to build up machinery that has to work entirely based on *relative* position without being able to find out your absolute coordinates. - For some reason this is causing `Testing/508-capability-subset` to fail. I think perhaps it is due to #397 ? I will investigate. *EDIT*: unfortunately, that wasn't it! --- data/entities.yaml | 12 ++++++ data/recipes.yaml | 20 ++++++--- data/scenarios/Testing/00-ORDER.txt | 1 + data/scenarios/Testing/956-GPS.yaml | 66 +++++++++++++++++++++++++++++ src/Swarm/Language/Capability.hs | 2 +- test/integration/Main.hs | 7 +-- 6 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 data/scenarios/Testing/956-GPS.yaml diff --git a/data/entities.yaml b/data/entities.yaml index 2f071d938..2174d2b42 100644 --- a/data/entities.yaml +++ b/data/entities.yaml @@ -1146,3 +1146,15 @@ `b1 <- f b0 x; b2 <- f b1 y; f b2 z`. properties: [portable] capabilities: [meet] + +- name: GPS receiver + display: + attr: device + char: 'G' + description: + - | + A GPS receiver triangulates your current (x,y) coordinates from + some convenient satellite signals, + enabling the command `whereami : cmd (int * int)`. + properties: [portable] + capabilities: [senseloc] diff --git a/data/recipes.yaml b/data/recipes.yaml index 5e6c1e951..23d5f0268 100644 --- a/data/recipes.yaml +++ b/data/recipes.yaml @@ -508,6 +508,20 @@ out: - [1, bitcoin] +- in: + - [2, silver] + - [2, copper wire] + out: + - [1, antenna] + +- in: + - [1, antenna] + - [1, clock] + - [1, circuit] + - [1, compass] + out: + - [1, GPS receiver] + ## MAGIC - in: @@ -670,12 +684,6 @@ out: - [1, mirror] -- in: - - [2, silver] - - [2, copper wire] - out: - - [1, antenna] - ######################################### ## LAMBDA ## ######################################### diff --git a/data/scenarios/Testing/00-ORDER.txt b/data/scenarios/Testing/00-ORDER.txt index 68f7637c8..03012b8b1 100644 --- a/data/scenarios/Testing/00-ORDER.txt +++ b/data/scenarios/Testing/00-ORDER.txt @@ -19,3 +19,4 @@ 955-heading.yaml 397-wrong-missing.yaml 961-custom-capabilities.yaml +956-GPS.yaml diff --git a/data/scenarios/Testing/956-GPS.yaml b/data/scenarios/Testing/956-GPS.yaml new file mode 100644 index 000000000..ae1e4e974 --- /dev/null +++ b/data/scenarios/Testing/956-GPS.yaml @@ -0,0 +1,66 @@ +version: 1 +name: Test GPS receiver device +description: | + Test the `whereami` command and GPS receiver device. + https://github.com/swarm-game/swarm/issues/956 +objectives: + - condition: | + loc <- as base {whereami}; + return $ loc == (0,0) + goal: + - | + The goal is to move back to the origin after being + unceremoniously teleported to a random location. The only way + to do this is to use a GPS receiver device to learn the + current location and use the result to decide how to move. +solution: | + def x = \n. \c. if (n == 0) {} {c ; x (n-1) c} end; + def abs = \n. if (n<0) {-n} {n} end; + wait 2; + loc <- whereami; + turn (if (fst loc < 0) {east} {west}); x (abs (fst loc)) move; + turn (if (snd loc < 0) {north} {south}); x (abs (snd loc)) move; +robots: + - name: base + dir: [0,1] + loc: [-5,5] + devices: + - clock + - dictionary + - GPS receiver + - treads + - compass + - ADT calculator + - strange loop + - comparator + - calculator + - branch predictor + - logger + - name: teleporter + dir: [0,1] + loc: [0,0] + system: true + display: + invisible: true + program: | + x <- random 11; + y <- random 11; + teleport base (x-5, y-5) +world: + default: [blank] + palette: + '.': [grass] + upperleft: [-5, 5] + map: | + ........... + ........... + ........... + ........... + ........... + ........... + ........... + ........... + ........... + ........... + ........... + diff --git a/src/Swarm/Language/Capability.hs b/src/Swarm/Language/Capability.hs index a7ceb72ce..44e0b0a53 100644 --- a/src/Swarm/Language/Capability.hs +++ b/src/Swarm/Language/Capability.hs @@ -211,6 +211,7 @@ constCaps = \case Atomic -> Just CAtomic Time -> Just CTime Wait -> Just CTime + Whereami -> Just CSenseloc Heading -> Just COrient -- ---------------------------------------------------------------- -- Text operations @@ -257,7 +258,6 @@ constCaps = \case -- which conveys their capability. TODO: #26 Teleport -> Just CTeleport -- Some space-time machine like Tardis? Appear -> Just CAppear -- paint? - Whereami -> Just CSenseloc -- GPS? Random -> Just CRandom -- randomness device (with bitcoins)? -- ---------------------------------------------------------------- -- Some more constants which *ought* to have their own capability but diff --git a/test/integration/Main.hs b/test/integration/Main.hs index acde2ca50..47af4b7fc 100644 --- a/test/integration/Main.hs +++ b/test/integration/Main.hs @@ -219,7 +219,7 @@ testScenarioSolution _ci _em = , testSolution Default "Testing/710-multi-robot" , testSolution Default "Testing/920-meet" , testSolution Default "Testing/955-heading" - , testSolution' Default "Testing/397-wrong-missing" AllowBadErrors $ \g -> do + , testSolution' Default "Testing/397-wrong-missing" CheckForBadErrors $ \g -> do let msgs = (g ^. messageQueue . to seqToTexts) <> (g ^.. robotMap . traverse . robotLog . to seqToTexts . traverse) @@ -227,9 +227,10 @@ testScenarioSolution _ci _em = assertBool "Should be some messages" (not (null msgs)) assertBool "Error messages should not mention treads" $ not (any ("treads" `T.isInfixOf`) msgs) - assertBool "Error message should mention no device provides senseloc" $ - any ("senseloc" `T.isInfixOf`) msgs + assertBool "Error message should mention GPS receiver" $ + any ("GPS receiver" `T.isInfixOf`) msgs , testSolution Default "Testing/961-custom-capabilities" + , testSolution Default "Testing/956-GPS" ] ] where